|
12 | 12 | * of the License, or any later version. |
13 | 13 | */ |
14 | 14 |
|
| 15 | +use B13\AiLabel\Backend\SortUrlBuilder; |
| 16 | +use B13\AiLabel\Domain\Repository\AiLabelDemand; |
15 | 17 | use B13\AiLabel\Domain\Repository\AiMetadataRecordFinder; |
| 18 | +use B13\AiLabel\Pagination\DemandedArrayPaginator; |
16 | 19 | use B13\AiLabel\Service\AiMetadataBadgeFactory; |
17 | 20 | use Psr\Http\Message\ResponseInterface; |
18 | 21 | use Psr\Http\Message\ServerRequestInterface; |
19 | 22 | use TYPO3\CMS\Backend\Attribute\AsController; |
20 | 23 | use TYPO3\CMS\Backend\Routing\UriBuilder; |
| 24 | +use TYPO3\CMS\Backend\Template\Components\ButtonBar; |
| 25 | +use TYPO3\CMS\Backend\Template\Components\Buttons\Action\ShortcutButton; |
21 | 26 | use TYPO3\CMS\Backend\Template\ModuleTemplateFactory; |
22 | 27 | use TYPO3\CMS\Core\Localization\LanguageService; |
23 | | -use TYPO3\CMS\Core\Page\PageRenderer; |
24 | | -use TYPO3\CMS\Core\Pagination\ArrayPaginator; |
25 | | -use TYPO3\CMS\Core\Pagination\SlidingWindowPagination; |
| 28 | +use TYPO3\CMS\Core\Pagination\SimplePagination; |
| 29 | +use TYPO3\CMS\Core\Utility\GeneralUtility; |
26 | 30 |
|
27 | 31 | #[AsController] |
28 | 32 | final class AiLabelOverviewController |
29 | 33 | { |
30 | | - private const ITEMS_PER_PAGE = 25; |
31 | | - private const MAX_NUMBER_OF_LINKS = 7; |
32 | 34 | private const MODULE_IDENTIFIER = 'web_ai_label_overview'; |
33 | 35 |
|
34 | 36 | public function __construct( |
35 | 37 | private readonly ModuleTemplateFactory $moduleTemplateFactory, |
36 | 38 | private readonly AiMetadataRecordFinder $recordFinder, |
37 | 39 | private readonly AiMetadataBadgeFactory $badgeFactory, |
38 | 40 | private readonly UriBuilder $uriBuilder, |
39 | | - private readonly PageRenderer $pageRenderer, |
| 41 | + private readonly SortUrlBuilder $sortUrlBuilder, |
40 | 42 | ) { |
41 | 43 | } |
42 | 44 |
|
43 | 45 | public function handleRequest(ServerRequestInterface $request): ResponseInterface |
44 | 46 | { |
45 | | - $this->pageRenderer->addCssFile('EXT:ai_label/Resources/Public/Css/ai-label.css'); |
46 | | - $currentPageNumber = max(1, (int)($request->getQueryParams()['currentPage'] ?? 1)); |
| 47 | + $view = $this->moduleTemplateFactory->create($request); |
| 48 | + $languageService = $this->getLanguageService(); |
| 49 | + $view->setTitle($languageService->sL('LLL:EXT:ai_label/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab')); |
47 | 50 |
|
48 | | - $returnUrl = (string)$request->getUri(); |
49 | | - $records = array_map( |
50 | | - fn (array $record) => [ |
| 51 | + $shortcutButton = GeneralUtility::makeInstance(ShortcutButton::class) |
| 52 | + ->setRouteIdentifier(self::MODULE_IDENTIFIER) |
| 53 | + ->setDisplayName($languageService->sL('LLL:EXT:ai_label/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab')); |
| 54 | + $view->getDocHeaderComponent()->getButtonBar()->addButton($shortcutButton, ButtonBar::BUTTON_POSITION_RIGHT); |
| 55 | + |
| 56 | + $demand = AiLabelDemand::fromRequest($request); |
| 57 | + $allRecords = $this->recordFinder->findFlaggedRecords(); |
| 58 | + $statistics = $this->recordFinder->calculateStatistics($allRecords); |
| 59 | + $tables = $this->recordFinder->getDistinctTables($allRecords); |
| 60 | + |
| 61 | + $matchingRecords = $this->recordFinder->filterAndSort($allRecords, $demand); |
| 62 | + $totalCount = count($matchingRecords); |
| 63 | + $pageItems = array_slice($matchingRecords, ($demand->getPage() - 1) * $demand->getLimit(), $demand->getLimit()); |
| 64 | + |
| 65 | + $returnUrl = $this->buildOverviewUrl($demand); |
| 66 | + $pageItems = array_map( |
| 67 | + fn (array $record): array => [ |
51 | 68 | ...$record, |
52 | 69 | 'reviewBadge' => $this->badgeFactory->getBadge($record['metadata'], $this->buildEditUrl($record['table'], $record['uid'], $returnUrl)), |
53 | 70 | ], |
54 | | - $this->recordFinder->findFlaggedRecords() |
| 71 | + $pageItems, |
55 | 72 | ); |
56 | 73 |
|
57 | | - $paginator = new ArrayPaginator($records, $currentPageNumber, self::ITEMS_PER_PAGE); |
58 | | - $pagination = new SlidingWindowPagination($paginator, self::MAX_NUMBER_OF_LINKS); |
| 74 | + $paginator = new DemandedArrayPaginator($pageItems, $demand->getPage(), $demand->getLimit(), $totalCount); |
| 75 | + $pagination = new SimplePagination($paginator); |
| 76 | + $paginationBaseUrl = (string)$this->uriBuilder->buildUriFromRoute(self::MODULE_IDENTIFIER, $this->demandToRouteParams($demand)); |
59 | 77 |
|
60 | | - $moduleTemplate = $this->moduleTemplateFactory->create($request); |
61 | | - $moduleTemplate->setTitle( |
62 | | - $this->getLanguageService()->sL('LLL:EXT:ai_label/Resources/Private/Language/locallang_mod.xlf:mlang_tabs_tab') |
63 | | - ); |
64 | | - $moduleTemplate->assignMultiple([ |
| 78 | + $view->assignMultiple([ |
| 79 | + 'demand' => $demand, |
| 80 | + // Filters are submitted via POST (Overview/Filters.html), so they never |
| 81 | + // show up in the request's own URI. It must be rebuilt from the parsed |
| 82 | + // demand instead, the same way $paginationBaseUrl is. |
| 83 | + 'returnUrl' => $returnUrl, |
| 84 | + 'paginationBaseUrl' => $paginationBaseUrl, |
| 85 | + 'sortUrls' => $this->sortUrlBuilder->build($demand, self::MODULE_IDENTIFIER), |
65 | 86 | 'paginator' => $paginator, |
66 | 87 | 'pagination' => $pagination, |
67 | | - 'pageUris' => $this->buildPageUris($pagination), |
68 | | - 'previousPageUri' => $this->buildPageUri($pagination->getPreviousPageNumber()), |
69 | | - 'nextPageUri' => $this->buildPageUri($pagination->getNextPageNumber()), |
| 88 | + 'statistics' => $statistics, |
| 89 | + 'tables' => $tables, |
70 | 90 | ]); |
71 | 91 |
|
72 | | - return $moduleTemplate->renderResponse('Overview/Index'); |
| 92 | + return $view->renderResponse('Overview/Index'); |
73 | 93 | } |
74 | 94 |
|
75 | | - /** @return array<int, string> */ |
76 | | - private function buildPageUris(SlidingWindowPagination $pagination): array |
| 95 | + /** |
| 96 | + * @return array<string, string> |
| 97 | + */ |
| 98 | + private function demandToRouteParams(AiLabelDemand $demand): array |
77 | 99 | { |
78 | | - $uris = []; |
79 | | - foreach ($pagination->getAllPageNumbers() as $pageNumber) { |
80 | | - $uris[$pageNumber] = (string)$this->buildPageUri($pageNumber); |
| 100 | + $params = [ |
| 101 | + 'orderField' => $demand->getOrderField(), |
| 102 | + 'orderDirection' => $demand->getOrderDirection(), |
| 103 | + ]; |
| 104 | + foreach ($demand->getParameters() as $key => $value) { |
| 105 | + $params['demand[' . $key . ']'] = $value; |
81 | 106 | } |
82 | | - return $uris; |
| 107 | + return $params; |
83 | 108 | } |
84 | 109 |
|
85 | | - private function buildPageUri(?int $pageNumber): ?string |
| 110 | + private function buildOverviewUrl(AiLabelDemand $demand): string |
86 | 111 | { |
87 | | - if ($pageNumber === null) { |
88 | | - return null; |
89 | | - } |
90 | | - return (string)$this->uriBuilder->buildUriFromRoute(self::MODULE_IDENTIFIER, ['currentPage' => $pageNumber]); |
| 112 | + return (string)$this->uriBuilder->buildUriFromRoute( |
| 113 | + self::MODULE_IDENTIFIER, |
| 114 | + array_merge($this->demandToRouteParams($demand), ['page' => $demand->getPage()]), |
| 115 | + ); |
91 | 116 | } |
92 | 117 |
|
93 | 118 | private function buildEditUrl(string $table, int $uid, string $returnUrl): string |
|
0 commit comments