From 7c23ac091253d458f0e4ef37f55326c24ff39ebe Mon Sep 17 00:00:00 2001 From: "Florian Will [mac]" <florian.will@sgalinski.de> Date: Fri, 7 Feb 2025 11:45:49 +0100 Subject: [PATCH] [TASK] SgJobs working pagination --- Classes/Controller/BackendController.php | 35 +++- Classes/Pagination/Pagination.php | 4 +- Resources/Private/Language/de.locallang.xlf | 16 ++ Resources/Private/Language/locallang.xlf | 12 ++ .../Private/Partials/Backend/Pagination.html | 179 +++++++++++------- 5 files changed, 169 insertions(+), 77 deletions(-) diff --git a/Classes/Controller/BackendController.php b/Classes/Controller/BackendController.php index 4c132ed6..99ffbdd9 100644 --- a/Classes/Controller/BackendController.php +++ b/Classes/Controller/BackendController.php @@ -28,6 +28,7 @@ namespace SGalinski\SgJobs\Controller; use Doctrine\DBAL\Exception; use Psr\Http\Message\ResponseInterface; +use SGalinski\SgAccount\Domain\Repository\FrontendUserRepository; use SGalinski\SgJobs\Domain\Repository\CompanyRepository; use SGalinski\SgJobs\Domain\Repository\JobRepository; use SGalinski\SgJobs\Pagination\Pagination; @@ -77,14 +78,22 @@ class BackendController extends ActionController { */ protected ModuleTemplate $moduleTemplate; + /** + * @var FrontendUserRepository + */ + protected FrontendUserRepository $frontendUserRepository; + public function __construct( CompanyRepository $companyRepository, JobRepository $jobRepository, - ModuleTemplateFactory $moduleTemplateFactory + ModuleTemplateFactory $moduleTemplateFactory, + FrontendUserRepository $frontendUserRepository, + ) { $this->companyRepository = $companyRepository; $this->jobRepository = $jobRepository; $this->moduleTemplateFactory = $moduleTemplateFactory; + $this->frontendUserRepository = $frontendUserRepository; } public function initializeAction(): void { @@ -103,7 +112,7 @@ class BackendController extends ActionController { */ public function indexAction(array $filters = [], int $currentPage = 1): ResponseInterface { $pageUid = $this->request->getQueryParams()['id'] ?? 0; - $itemsPerPage = 10; + /** @var BackendUserAuthentication $backendUser */ $backendUser = $GLOBALS['BE_USER']; if ($filters === []) { @@ -112,6 +121,28 @@ class BackendController extends ActionController { $backendUser->pushModuleData('web_SgJobsBackend_filters', $filters); } + $itemsPerPage = (int) ( + $this->request->getQueryParams()['itemsPerPage'] + ?? $this->request->getParsedBody()['itemsPerPage'] + ?? $backendUser->getModuleData('itemsPerPage', 'ses') // Retrieve from session if available + ?? 10 + ); + +// Store itemsPerPage in the session + $backendUser->pushModuleData('itemsPerPage', $itemsPerPage); + +// Ensure at least 1 item per page + $itemsPerPage = max($itemsPerPage, 1); + +// Create the query builder + $usersQueryBuilder = $this->frontendUserRepository->getUsersByPidForBackendList( + $pageUid, $filters, $itemsPerPage + ); + +// 🛠Recreate Pagination with updated values + $pagination = GeneralUtility::makeInstance(\SGalinski\SgAccount\Pagination\Pagination::class, $usersQueryBuilder, $currentPage, $itemsPerPage); + $this->moduleTemplate->assign('pagination', $pagination); + // create docheader + buttons $pageInfo = BackendUtility::readPageAccess($pageUid, $GLOBALS['BE_USER']->getPagePermsClause(1)); if ($pageInfo === FALSE) { diff --git a/Classes/Pagination/Pagination.php b/Classes/Pagination/Pagination.php index 07e191d7..717832b2 100644 --- a/Classes/Pagination/Pagination.php +++ b/Classes/Pagination/Pagination.php @@ -85,8 +85,8 @@ class Pagination { $this->lastPage = (int) ceil($this->totalItems / $this->limit); // correct current page if out of bounds $this->currentPage = $this->currentPage < 1 ? 1 : min($this->currentPage, $this->lastPage); - $this->nextPage = $this->currentPage >= $this->lastPage ? $this->lastPage : $this->currentPage + 1; - $this->previousPage = $this->currentPage <= 1 ? 1 : $this->currentPage - 1; + $this->previousPage = ($this->currentPage > 1) ? $this->currentPage - 1 : null; + $this->nextPage = ($this->currentPage < $this->lastPage) ? $this->currentPage + 1 : null; $this->startItem = ($this->currentPage - 1) * $this->limit + 1; // correct startItem if out of bounds $this->startItem = max($this->startItem, 1); diff --git a/Resources/Private/Language/de.locallang.xlf b/Resources/Private/Language/de.locallang.xlf index e3503e4d..a7ca6051 100644 --- a/Resources/Private/Language/de.locallang.xlf +++ b/Resources/Private/Language/de.locallang.xlf @@ -538,6 +538,22 @@ <source><![CDATA[Previous]]></source> <target><![CDATA[Zurück]]></target> </trans-unit> + <trans-unit id="backend.job.page" resname="backend.job.page"> + <source><![CDATA[Page]]></source> + <target><![CDATA[Seite]]></target> + </trans-unit> + <trans-unit id="backend.job.records" resname="backend.job.records"> + <source><![CDATA[Records]]></source> + <target><![CDATA[Einträge]]></target> + </trans-unit> + <trans-unit id="backend.job.itemsPerPage" resname="backend.job.itemsPerPage"> + <source><![CDATA[Entries per page:]]></source> + <target><![CDATA[Einträge pro Seite:]]></target> + </trans-unit> + <trans-unit id="backend.job.of" resname="backend.job.of"> + <source><![CDATA[of]]></source> + <target><![CDATA[von]]></target> + </trans-unit> </body> </file> </xliff> diff --git a/Resources/Private/Language/locallang.xlf b/Resources/Private/Language/locallang.xlf index fdd7432a..1ad9f1f8 100644 --- a/Resources/Private/Language/locallang.xlf +++ b/Resources/Private/Language/locallang.xlf @@ -429,6 +429,18 @@ <trans-unit id="pagebrowser.previous" resname="pagebrowser.previous"> <source><![CDATA[Previous]]></source> </trans-unit> + <trans-unit id="backend.job.records" resname="backend.job.records"> + <source><![CDATA[Records]]></source> + </trans-unit> + <trans-unit id="backend.job.page" resname="backend.job.page"> + <source><![CDATA[Page]]></source> + </trans-unit> + <trans-unit id="backend.job.itemsPerPage" resname="backend.job.itemsPerPage"> + <source><![CDATA[Entries per page:]]></source> + </trans-unit> + <trans-unit id="backend.job.of" resname="backend.job.of"> + <source><![CDATA[of]]></source> + </trans-unit> </body> </file> </xliff> diff --git a/Resources/Private/Partials/Backend/Pagination.html b/Resources/Private/Partials/Backend/Pagination.html index ded7eaf1..2fa6a527 100644 --- a/Resources/Private/Partials/Backend/Pagination.html +++ b/Resources/Private/Partials/Backend/Pagination.html @@ -1,96 +1,129 @@ {namespace core=TYPO3\CMS\Core\ViewHelpers} -{namespace sg=SGalinski\SgMail\ViewHelpers} +{namespace sg=SGalinski\SgJobs\ViewHelpers} -<nav class="pagination-wrap"> - <ul class="pagination pagination-block"> - <f:if condition="{pagination.previousPage} && {pagination.previousPage} >= {pagination.firstPage}"> - <f:then> - <li class="page-item"> - <a href="{f:uri.action(action: 'index', arguments: {currentPage: 1})}" - title="{f:translate(key:'widget.pagination.first')}" - class="page-link"> +<html xmlns:f="http://typo3.org/ns/TYPO3/CMS/Fluid/ViewHelpers" data-namespace-typo3-fluid="true" lang=""> +<nav class="mb-2 mt-2"> + <ul class="pagination"> + <!-- Records Display --> + <li class="page-item ps-2 pe-2 pagination-label"> + <span> + <f:translate key="backend.job.records" extensionName="sg_jobs" /> {pagination.startItem} - {pagination.endItem} + </span> + </li> + + <!-- First Button --> + <li class="page-item ps-2 {f:if(condition: pagination.previousPage, then: '', else: 'disabled')}"> + <f:if condition="{pagination.previousPage}"> + <f:then> + <a href="{f:uri.action(action: action, arguments: {currentPage: 1, itemsPerPage: itemsPerPage})}" + > <core:icon identifier="actions-view-paging-first" /> </a> - </li> - <li class="page-item"> - <a href="{f:uri.action(action: 'index', arguments: {currentPage: pagination.previousPage})}" - title="{f:translate(key:'widget.pagination.previous')}" - class="page-link"> + </f:then> + <f:else> + <span > + <core:icon identifier="actions-view-paging-first" /> + </span> + </f:else> + </f:if> + </li> + + <!-- Previous Button --> + <li class="page-item ps-2 {f:if(condition: pagination.previousPage, then: '', else: 'disabled')}"> + <f:if condition="{pagination.previousPage}"> + <f:then> + <a href="{f:uri.action(action: action, arguments: {currentPage: pagination.previousPage, itemsPerPage: itemsPerPage})}" + > <core:icon identifier="actions-view-paging-previous" /> </a> - </li> - </f:then> - <f:else> - <li class="page-item disabled"> - <span class="page-link"> - <core:icon identifier="actions-view-paging-first" /> - </span> - </li> - <li class="page-item disabled"> - <span class="page-link"> - <core:icon identifier="actions-view-paging-previous" /> - </span> - </li> - </f:else> - </f:if> - <li class="page-item"> - <span class="page-link"> - <f:translate key="widget.pagination.records" /> - {pagination.startItem} - {pagination.endItem} / {pagination.totalItems} - </span> + </f:then> + <f:else> + <span > + <core:icon identifier="actions-view-paging-previous" /> + </span> + </f:else> + </f:if> </li> - <li class="page-item"> - <span class="page-link"> - <f:translate key="widget.pagination.page" /> + + <!-- Go to Page --> + <li class="page-item ps-2"> + <form action="" method="POST"> + <f:translate key="backend.job.page" extensionName="sg_jobs" /> <f:form.textfield id="paginator" name="paginator-target-page" additionalAttributes="{ - min: '1', - data-uri: '{f:uri.action(action: actionName, arguments: {currentPage: 987654321}) -> f:format.raw()}' - }" + min: '1', + data-uri: '{f:uri.action(action: action, arguments: {currentPage: 987654321, itemsPerPage: itemsPerPage}) -> f:format.raw()}' + }" class="form-control input-sm paginator-input" - size="5" + style="padding: 4px 8px" value="{pagination.currentPage}" type="number" /> - / {pagination.lastPage} - </span> + <f:translate key="backend.job.of" extensionName="sg_jobs" /> {pagination.lastPage} + <input type="hidden" name="itemsPerPage" value="{itemsPerPage}" /> + </form> </li> - <f:if condition="{pagination.nextPage} && {pagination.nextPage} <= {pagination.lastPage}"> - <f:then> - <li class="page-item"> - <a class="page-link" - href="{f:uri.action(action: 'index', arguments: {currentPage: pagination.nextPage})}" - title="{f:translate(key:'widget.pagination.next')}"> + + <!-- Next Button --> + <li class="page-item ps-2 {f:if(condition: pagination.nextPage, then: '', else: 'disabled')}"> + <f:if condition="{pagination.nextPage}"> + <f:then> + <a href="{f:uri.action(action: action, arguments: {currentPage: pagination.nextPage, itemsPerPage: itemsPerPage})}" + > <core:icon identifier="actions-view-paging-next" /> </a> - </li> - <li class="page-item"> - <a class="page-link" - href="{f:uri.action(action: 'index', arguments: {currentPage: pagination.lastPage})}" - title="{f:translate(key:'widget.pagination.last')}"> + </f:then> + <f:else> + <span > + <core:icon identifier="actions-view-paging-next" /> + </span> + </f:else> + </f:if> + </li> + + <!-- Last Button --> + <li class="page-item ps-2 {f:if(condition: pagination.nextPage, then: '', else: 'disabled')}"> + <f:if condition="{pagination.nextPage}"> + <f:then> + <a href="{f:uri.action(action: action, arguments: {currentPage: pagination.lastPage, itemsPerPage: itemsPerPage})}" + > <core:icon identifier="actions-view-paging-last" /> </a> - </li> - </f:then> - <f:else> - <li class="page-item disabled"> - <span class="page-link"> - <core:icon identifier="actions-view-paging-next" /> - </span> - </li> - <li class="page-item disabled"> - <span class="page-link"> - <core:icon identifier="actions-view-paging-last" /> - </span> - </li> - </f:else> - </f:if> - <li class="page-item"> - <a class="page-link" - href="{f:uri.action(action: 'index', arguments: {currentPage: pagination.currentPage})}" - title="{f:translate(key:'widget.pagination.refresh')}"> + </f:then> + <f:else> + <span > + <core:icon identifier="actions-view-paging-last" /> + </span> + </f:else> + </f:if> + </li> + + <!-- Custom Items Per Page Input Field with Label --> + <li class="page-item ps-2 "> + <form action="" method="POST" class="d-flex "> + <label for="itemsPerPageInput" class="me-2 mb-0"> + <f:translate key="backend.job.itemsPerPage" extensionName="sg_jobs" /> + </label> + <input type="number" + name="itemsPerPage" + id="itemsPerPageInput" + class="form-control input-sm " + style="padding: 4px 8px; width: 70px; min-width: 50px; margin: -7px 0px" + value="{itemsPerPage}" + min="1" + required /> + <input type="hidden" name="page" value="{pagination.currentPage}" /> + </form> + </li> + + + <!-- Refresh Button --> + <li class="page-item ps-2"> + <a href="{f:uri.action(action: action, arguments: {currentPage: pagination.currentPage, itemsPerPage: itemsPerPage})}" + > <core:icon identifier="actions-refresh" /> </a> </li> </ul> </nav> +</html> -- GitLab