From 3107319812a7e0797a0c9abf2ee9526abf74bdcb Mon Sep 17 00:00:00 2001 From: Sami Mazouz Date: Fri, 10 Nov 2023 22:31:46 +0100 Subject: [PATCH] fix: paginated list limit hard to change (#3918) * fix: paginated list limit hard to change * chore: use the default value * chore: apply to other list states * chore: remove debugging code * fix: typings --- .../js/src/admin/states/QueueState.ts | 2 +- framework/core/js/src/common/Store.ts | 6 ++++- .../src/common/states/PaginatedListState.ts | 26 ++++++++++++++++--- .../src/forum/states/DiscussionListState.ts | 3 ++- .../src/forum/states/NotificationListState.ts | 2 +- .../Api/Controller/AbstractListController.php | 20 ++++++++++++++ .../Controller/ListDiscussionsController.php | 7 +++-- .../ListNotificationsController.php | 7 +++-- framework/core/src/Forum/Content/Index.php | 10 +++++-- 9 files changed, 65 insertions(+), 18 deletions(-) diff --git a/extensions/package-manager/js/src/admin/states/QueueState.ts b/extensions/package-manager/js/src/admin/states/QueueState.ts index 492e415a7a..dde5713a6b 100644 --- a/extensions/package-manager/js/src/admin/states/QueueState.ts +++ b/extensions/package-manager/js/src/admin/states/QueueState.ts @@ -21,7 +21,7 @@ export default class QueueState { return app.store.find('package-manager-tasks', params || {}).then((data) => { this.tasks = data; - this.total = data.payload.meta?.total; + this.total = data.payload.meta?.total!; m.redraw(); diff --git a/framework/core/js/src/common/Store.ts b/framework/core/js/src/common/Store.ts index a6489c797b..052ee020f0 100644 --- a/framework/core/js/src/common/Store.ts +++ b/framework/core/js/src/common/Store.ts @@ -48,7 +48,11 @@ export interface ApiPayloadPlural { next?: string; prev?: string; }; - meta?: MetaInformation; + meta?: MetaInformation & { + total?: number; + page?: number; + perPage?: number; + }; } export type ApiPayload = ApiPayloadSingle | ApiPayloadPlural; diff --git a/framework/core/js/src/common/states/PaginatedListState.ts b/framework/core/js/src/common/states/PaginatedListState.ts index 53d08464b9..6d7e83baf7 100644 --- a/framework/core/js/src/common/states/PaginatedListState.ts +++ b/framework/core/js/src/common/states/PaginatedListState.ts @@ -25,8 +25,15 @@ export interface PaginatedListRequestParams extends Omit { + /** + * This value should not be relied upon when preloading an API document. + * In those cases the pageSize should be taken from the meta information of the preloaded + * document. Checkout `DiscussionListState.loadPage` for an example. + */ + public static DEFAULT_PAGE_SIZE = 20; + protected location!: PaginationLocation; - protected pageSize: number; + protected pageSize: number | null; protected pages: Page[] = []; protected params: P = {} as P; @@ -35,7 +42,7 @@ export default abstract class PaginatedListState(this.type, params); + return app.store.find(this.type, params).then((results) => { + /* + * If this state does not rely on a preloaded API document to know the page size, + * then there is no initial list, and therefore the page size can be taken from subsequent requests. + */ + if (!this.pageSize) { + this.pageSize = results.payload?.meta?.perPage || PaginatedListState.DEFAULT_PAGE_SIZE; + } + + return results; + }); } /** diff --git a/framework/core/js/src/forum/states/DiscussionListState.ts b/framework/core/js/src/forum/states/DiscussionListState.ts index 76d890785c..3620381215 100644 --- a/framework/core/js/src/forum/states/DiscussionListState.ts +++ b/framework/core/js/src/forum/states/DiscussionListState.ts @@ -15,7 +15,7 @@ export default class DiscussionListState

{ constructor() { - super({}, 1, 20); + super({}, 1, null); } get type(): string { diff --git a/framework/core/src/Api/Controller/AbstractListController.php b/framework/core/src/Api/Controller/AbstractListController.php index ac4fd87538..d5aa7f7400 100644 --- a/framework/core/src/Api/Controller/AbstractListController.php +++ b/framework/core/src/Api/Controller/AbstractListController.php @@ -23,4 +23,24 @@ protected function createElement(mixed $data, SerializerInterface $serializer): } abstract protected function data(ServerRequestInterface $request, Document $document): iterable; + + protected function addPaginationData(Document $document, ServerRequestInterface $request, string $url, ?int $total): void + { + $limit = $this->extractLimit($request); + $offset = $this->extractOffset($request); + + $document->addPaginationLinks( + $url, + $request->getQueryParams(), + $offset, + $limit, + $total, + ); + + $document->setMeta([ + 'total' => $total, + 'perPage' => $limit, + 'page' => $offset / $limit + 1, + ]); + } } diff --git a/framework/core/src/Api/Controller/ListDiscussionsController.php b/framework/core/src/Api/Controller/ListDiscussionsController.php index ca34a1881d..54f00a1f34 100644 --- a/framework/core/src/Api/Controller/ListDiscussionsController.php +++ b/framework/core/src/Api/Controller/ListDiscussionsController.php @@ -64,11 +64,10 @@ protected function data(ServerRequestInterface $request, Document $document): it $results = $this->filterer->filter($criteria, $limit, $offset); } - $document->addPaginationLinks( + $this->addPaginationData( + $document, + $request, $this->url->to('api')->route('discussions.index'), - $request->getQueryParams(), - $offset, - $limit, $results->areMoreResults() ? null : 0 ); diff --git a/framework/core/src/Api/Controller/ListNotificationsController.php b/framework/core/src/Api/Controller/ListNotificationsController.php index 354478ca1b..6481274d15 100644 --- a/framework/core/src/Api/Controller/ListNotificationsController.php +++ b/framework/core/src/Api/Controller/ListNotificationsController.php @@ -62,11 +62,10 @@ protected function data(ServerRequestInterface $request, Document $document): it $areMoreResults = true; } - $document->addPaginationLinks( + $this->addPaginationData( + $document, + $request, $this->url->to('api')->route('notifications.index'), - $request->getQueryParams(), - $offset, - $limit, $areMoreResults ? null : 0 ); diff --git a/framework/core/src/Forum/Content/Index.php b/framework/core/src/Forum/Content/Index.php index a8af226e68..3c71323a0b 100644 --- a/framework/core/src/Forum/Content/Index.php +++ b/framework/core/src/Forum/Content/Index.php @@ -10,6 +10,7 @@ namespace Flarum\Forum\Content; use Flarum\Api\Client; +use Flarum\Api\Controller\ListDiscussionsController; use Flarum\Frontend\Document; use Flarum\Http\UrlGenerator; use Flarum\Locale\TranslatorInterface; @@ -25,7 +26,8 @@ public function __construct( protected Factory $view, protected SettingsRepositoryInterface $settings, protected UrlGenerator $url, - protected TranslatorInterface $translator + protected TranslatorInterface $translator, + protected ListDiscussionsController $controller ) { } @@ -39,11 +41,15 @@ public function __invoke(Document $document, Request $request): Document $filters = Arr::pull($queryParams, 'filter', []); $sortMap = resolve('flarum.forum.discussions.sortmap'); + $limit = $this->controller->limit; $params = [ 'sort' => $sort && isset($sortMap[$sort]) ? $sortMap[$sort] : '', 'filter' => $filters, - 'page' => ['offset' => ($page - 1) * 20, 'limit' => 20] + 'page' => [ + 'offset' => ($page - 1) * $limit, + 'limit' => $limit + ], ]; if ($q) {