mirror of
https://github.com/flarum/framework.git
synced 2025-02-01 05:52:02 +08:00
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
This commit is contained in:
parent
a9756cb5eb
commit
3107319812
|
@ -21,7 +21,7 @@ export default class QueueState {
|
||||||
|
|
||||||
return app.store.find<Task[]>('package-manager-tasks', params || {}).then((data) => {
|
return app.store.find<Task[]>('package-manager-tasks', params || {}).then((data) => {
|
||||||
this.tasks = data;
|
this.tasks = data;
|
||||||
this.total = data.payload.meta?.total;
|
this.total = data.payload.meta?.total!;
|
||||||
|
|
||||||
m.redraw();
|
m.redraw();
|
||||||
|
|
||||||
|
|
|
@ -48,7 +48,11 @@ export interface ApiPayloadPlural {
|
||||||
next?: string;
|
next?: string;
|
||||||
prev?: string;
|
prev?: string;
|
||||||
};
|
};
|
||||||
meta?: MetaInformation;
|
meta?: MetaInformation & {
|
||||||
|
total?: number;
|
||||||
|
page?: number;
|
||||||
|
perPage?: number;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export type ApiPayload = ApiPayloadSingle | ApiPayloadPlural;
|
export type ApiPayload = ApiPayloadSingle | ApiPayloadPlural;
|
||||||
|
|
|
@ -25,8 +25,15 @@ export interface PaginatedListRequestParams extends Omit<ApiQueryParamsPlural, '
|
||||||
}
|
}
|
||||||
|
|
||||||
export default abstract class PaginatedListState<T extends Model, P extends PaginatedListParams = PaginatedListParams> {
|
export default abstract class PaginatedListState<T extends Model, P extends PaginatedListParams = PaginatedListParams> {
|
||||||
|
/**
|
||||||
|
* 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 location!: PaginationLocation;
|
||||||
protected pageSize: number;
|
protected pageSize: number | null;
|
||||||
|
|
||||||
protected pages: Page<T>[] = [];
|
protected pages: Page<T>[] = [];
|
||||||
protected params: P = {} as P;
|
protected params: P = {} as P;
|
||||||
|
@ -35,7 +42,7 @@ export default abstract class PaginatedListState<T extends Model, P extends Pagi
|
||||||
protected loadingPrev: boolean = false;
|
protected loadingPrev: boolean = false;
|
||||||
protected loadingNext: boolean = false;
|
protected loadingNext: boolean = false;
|
||||||
|
|
||||||
protected constructor(params: P = {} as P, page: number = 1, pageSize: number = 20) {
|
protected constructor(params: P = {} as P, page: number = 1, pageSize: number | null = null) {
|
||||||
this.params = params;
|
this.params = params;
|
||||||
|
|
||||||
this.location = { page };
|
this.location = { page };
|
||||||
|
@ -108,12 +115,23 @@ export default abstract class PaginatedListState<T extends Model, P extends Pagi
|
||||||
...reqParams,
|
...reqParams,
|
||||||
page: {
|
page: {
|
||||||
...reqParams.page,
|
...reqParams.page,
|
||||||
offset: this.pageSize * (page - 1),
|
offset: (this.pageSize && this.pageSize * (page - 1)) || 0,
|
||||||
|
limit: this.pageSize || undefined,
|
||||||
},
|
},
|
||||||
include,
|
include,
|
||||||
};
|
};
|
||||||
|
|
||||||
return app.store.find<T[]>(this.type, params);
|
return app.store.find<T[]>(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;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -15,7 +15,7 @@ export default class DiscussionListState<P extends DiscussionListParams = Discus
|
||||||
protected eventEmitter: EventEmitter;
|
protected eventEmitter: EventEmitter;
|
||||||
|
|
||||||
constructor(params: P, page: number = 1) {
|
constructor(params: P, page: number = 1) {
|
||||||
super(params, page, 20);
|
super(params, page, null);
|
||||||
|
|
||||||
this.eventEmitter = globalEventEmitter.on('discussion.deleted', this.deleteDiscussion.bind(this));
|
this.eventEmitter = globalEventEmitter.on('discussion.deleted', this.deleteDiscussion.bind(this));
|
||||||
}
|
}
|
||||||
|
@ -44,6 +44,7 @@ export default class DiscussionListState<P extends DiscussionListParams = Discus
|
||||||
|
|
||||||
if (preloadedDiscussions) {
|
if (preloadedDiscussions) {
|
||||||
this.initialLoading = false;
|
this.initialLoading = false;
|
||||||
|
this.pageSize = preloadedDiscussions.payload.meta?.perPage || DiscussionListState.DEFAULT_PAGE_SIZE;
|
||||||
|
|
||||||
return Promise.resolve(preloadedDiscussions);
|
return Promise.resolve(preloadedDiscussions);
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,7 +4,7 @@ import Notification from '../../common/models/Notification';
|
||||||
|
|
||||||
export default class NotificationListState extends PaginatedListState<Notification> {
|
export default class NotificationListState extends PaginatedListState<Notification> {
|
||||||
constructor() {
|
constructor() {
|
||||||
super({}, 1, 20);
|
super({}, 1, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
get type(): string {
|
get type(): string {
|
||||||
|
|
|
@ -23,4 +23,24 @@ abstract class AbstractListController extends AbstractSerializeController
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract protected function data(ServerRequestInterface $request, Document $document): iterable;
|
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,
|
||||||
|
]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -64,11 +64,10 @@ class ListDiscussionsController extends AbstractListController
|
||||||
$results = $this->filterer->filter($criteria, $limit, $offset);
|
$results = $this->filterer->filter($criteria, $limit, $offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
$document->addPaginationLinks(
|
$this->addPaginationData(
|
||||||
|
$document,
|
||||||
|
$request,
|
||||||
$this->url->to('api')->route('discussions.index'),
|
$this->url->to('api')->route('discussions.index'),
|
||||||
$request->getQueryParams(),
|
|
||||||
$offset,
|
|
||||||
$limit,
|
|
||||||
$results->areMoreResults() ? null : 0
|
$results->areMoreResults() ? null : 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -62,11 +62,10 @@ class ListNotificationsController extends AbstractListController
|
||||||
$areMoreResults = true;
|
$areMoreResults = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
$document->addPaginationLinks(
|
$this->addPaginationData(
|
||||||
|
$document,
|
||||||
|
$request,
|
||||||
$this->url->to('api')->route('notifications.index'),
|
$this->url->to('api')->route('notifications.index'),
|
||||||
$request->getQueryParams(),
|
|
||||||
$offset,
|
|
||||||
$limit,
|
|
||||||
$areMoreResults ? null : 0
|
$areMoreResults ? null : 0
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
namespace Flarum\Forum\Content;
|
namespace Flarum\Forum\Content;
|
||||||
|
|
||||||
use Flarum\Api\Client;
|
use Flarum\Api\Client;
|
||||||
|
use Flarum\Api\Controller\ListDiscussionsController;
|
||||||
use Flarum\Frontend\Document;
|
use Flarum\Frontend\Document;
|
||||||
use Flarum\Http\UrlGenerator;
|
use Flarum\Http\UrlGenerator;
|
||||||
use Flarum\Locale\TranslatorInterface;
|
use Flarum\Locale\TranslatorInterface;
|
||||||
|
@ -25,7 +26,8 @@ class Index
|
||||||
protected Factory $view,
|
protected Factory $view,
|
||||||
protected SettingsRepositoryInterface $settings,
|
protected SettingsRepositoryInterface $settings,
|
||||||
protected UrlGenerator $url,
|
protected UrlGenerator $url,
|
||||||
protected TranslatorInterface $translator
|
protected TranslatorInterface $translator,
|
||||||
|
protected ListDiscussionsController $controller
|
||||||
) {
|
) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -39,11 +41,15 @@ class Index
|
||||||
$filters = Arr::pull($queryParams, 'filter', []);
|
$filters = Arr::pull($queryParams, 'filter', []);
|
||||||
|
|
||||||
$sortMap = resolve('flarum.forum.discussions.sortmap');
|
$sortMap = resolve('flarum.forum.discussions.sortmap');
|
||||||
|
$limit = $this->controller->limit;
|
||||||
|
|
||||||
$params = [
|
$params = [
|
||||||
'sort' => $sort && isset($sortMap[$sort]) ? $sortMap[$sort] : '',
|
'sort' => $sort && isset($sortMap[$sort]) ? $sortMap[$sort] : '',
|
||||||
'filter' => $filters,
|
'filter' => $filters,
|
||||||
'page' => ['offset' => ($page - 1) * 20, 'limit' => 20]
|
'page' => [
|
||||||
|
'offset' => ($page - 1) * $limit,
|
||||||
|
'limit' => $limit
|
||||||
|
],
|
||||||
];
|
];
|
||||||
|
|
||||||
if ($q) {
|
if ($q) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user