SSR module: rebuilt on TYPO3 module layout, cards and core components
Ticket 0096-FE (aehm): the module now uses the core Module layout (DocHeader with reload and shortcut, module-body spacing), a Status card as description list with one badge style, an Actions card with core buttons and icons, help texts below the buttons and TYPO3 modal confirmations (ssr-module.js) instead of window.confirm, and three protocol cards. Purge protocol rows show a one-line time, the trigger as badge plus user, paths as count + first two + disclosure, result and duration right-aligned, with 30/100/500 row switches. Status shows the last health sample with relative age and the cache limit (new optional SSR_CACHE_LIMIT_MB in var/vitec-ssr-purge.env, SsrPurgeService::getCacheLimitMb). ssr-warm-progress.js now also disables the Warm button with a spinner while a run is active. backend-ssr.css holds only layout glue with core CSS variables (dark mode safe). Verified in the backend: layout, modal, running progress bar, protocol tables. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
This commit is contained in:
1 parent
07f74e372b
commit
086a178341
6 files changed
+477
-192
No files matched your search
@@ -9,7 +9,10 @@ use Psr\Http\Message\ResponseInterface;
|
||||
use Psr\Http\Message\ServerRequestInterface;
|
||||
use TYPO3\CMS\Backend\Attribute\AsController;
|
||||
use TYPO3\CMS\Backend\Routing\UriBuilder;
|
||||
use TYPO3\CMS\Backend\Template\Components\ButtonBar;
|
||||
use TYPO3\CMS\Backend\Template\Components\ComponentFactory;
|
||||
use TYPO3\CMS\Backend\Template\ModuleTemplateFactory;
|
||||
use TYPO3\CMS\Backend\Utility\BackendUtility;
|
||||
use TYPO3\CMS\Core\Core\Environment;
|
||||
use TYPO3\CMS\Core\Database\Connection;
|
||||
use TYPO3\CMS\Core\Database\ConnectionPool;
|
||||
@@ -38,6 +41,7 @@ final class SsrController
|
||||
private readonly FlashMessageService $flashMessageService,
|
||||
private readonly UriBuilder $uriBuilder,
|
||||
private readonly PageRenderer $pageRenderer,
|
||||
private readonly ComponentFactory $componentFactory,
|
||||
) {}
|
||||
|
||||
public function indexAction(ServerRequestInterface $request): ResponseInterface
|
||||
@@ -47,14 +51,36 @@ final class SsrController
|
||||
|
||||
[$health, $healthError] = $this->fetchHealth();
|
||||
$this->pageRenderer->loadJavaScriptModule('@evomedien/vitec/ssr-warm-progress.js');
|
||||
$this->pageRenderer->loadJavaScriptModule('@evomedien/vitec/ssr-module.js');
|
||||
$this->pageRenderer->addCssFile('EXT:vitec/Resources/Public/Css/backend-ssr.css');
|
||||
|
||||
// DocHeader: shortcut button (0096-FE); the reload button comes from the core.
|
||||
$view->addButtonToButtonBar(
|
||||
$this->componentFactory->createShortcutButton()
|
||||
->setRouteIdentifier('web_vitecssr')
|
||||
->setDisplayName('VITEC SSR'),
|
||||
ButtonBar::BUTTON_POSITION_RIGHT
|
||||
);
|
||||
|
||||
$limit = (int)($request->getQueryParams()['limit'] ?? 30);
|
||||
if (!in_array($limit, [30, 100, 500], true)) {
|
||||
$limit = 30;
|
||||
}
|
||||
$healthLog = $this->rows('tx_vitec_ssrhealthlog', 10);
|
||||
$lastSample = $healthLog[0] ?? null;
|
||||
|
||||
$view->assignMultiple([
|
||||
'flagOn' => file_exists(Environment::getVarPath() . '/vitec-ssr-on.flag'),
|
||||
'configured' => $this->purgeService->isConfigured(),
|
||||
'health' => $health,
|
||||
'healthError' => $healthError,
|
||||
'purgeLog' => $this->rows('tx_vitec_ssrpurgelog', 30),
|
||||
'healthLog' => $this->rows('tx_vitec_ssrhealthlog', 10),
|
||||
'cacheLimitMb' => $this->purgeService->getCacheLimitMb(),
|
||||
'lastSample' => $lastSample,
|
||||
'lastSampleAge' => $lastSample ? BackendUtility::calcAge(time() - (int)$lastSample['crdate']) : '',
|
||||
'purgeLog' => $this->purgeRows($limit),
|
||||
'purgeLimit' => $limit,
|
||||
'moduleUri' => (string)$this->uriBuilder->buildUriFromRoute('web_vitecssr'),
|
||||
'healthLog' => $healthLog,
|
||||
'clientErrors' => $this->clientErrors(50),
|
||||
'clientErrorCount24h' => $this->clientErrorCount24h(),
|
||||
]);
|
||||
@@ -89,6 +115,42 @@ final class SsrController
|
||||
return $rows;
|
||||
}
|
||||
|
||||
/**
|
||||
* Purge log rows prepared for the template: trigger split into a short
|
||||
* label plus the user, paths as count + first two + the rest behind a
|
||||
* disclosure (the raw list was a wall of text, 0096-FE).
|
||||
*/
|
||||
private function purgeRows(int $limit): array
|
||||
{
|
||||
$rows = $this->rows('tx_vitec_ssrpurgelog', $limit);
|
||||
foreach ($rows as &$row) {
|
||||
$trigger = (string)$row['trigger_source'];
|
||||
$who = '';
|
||||
if (str_contains($trigger, ':')) {
|
||||
[$trigger, $who] = explode(':', $trigger, 2);
|
||||
}
|
||||
$row['trigger_label'] = match ($trigger) {
|
||||
'module' => 'manual',
|
||||
'contextmenu' => 'context menu',
|
||||
'editor-save', 'editor-command' => 'auto-purge',
|
||||
default => $trigger,
|
||||
};
|
||||
$row['trigger_who'] = $who;
|
||||
$row['trigger_badge'] = match ($trigger) {
|
||||
'module', 'contextmenu' => 'badge-info',
|
||||
'switch-on' => 'badge-warning',
|
||||
default => 'badge-secondary',
|
||||
};
|
||||
$paths = preg_split('/\s*,\s*/', trim((string)$row['paths']), -1, PREG_SPLIT_NO_EMPTY) ?: [];
|
||||
$row['paths_all'] = $paths === ['*'];
|
||||
$row['paths_count'] = count($paths);
|
||||
$row['paths_first'] = array_slice($paths, 0, 2);
|
||||
$row['paths_rest'] = array_slice($paths, 2);
|
||||
}
|
||||
unset($row);
|
||||
return $rows;
|
||||
}
|
||||
|
||||
private function clientErrorCount24h(): int
|
||||
{
|
||||
try {
|
||||
|
||||
Reference in new issue
Block a user