From ab8b03d8d80d68a824e5e7aa0ea4414c96e65d19 Mon Sep 17 00:00:00 2001 From: Killer_Dom1123 Date: Mon, 23 Oct 2023 16:02:35 +0100 Subject: [PATCH] Add ability to get custom data per page --- src/pipeline/limit/customData.ts | 39 ++++++++++++++++++++++++++++++++ src/view/plugin/pagination.tsx | 26 +++++++++++++++++++-- 2 files changed, 63 insertions(+), 2 deletions(-) create mode 100644 src/pipeline/limit/customData.ts diff --git a/src/pipeline/limit/customData.ts b/src/pipeline/limit/customData.ts new file mode 100644 index 00000000..cb0216f0 --- /dev/null +++ b/src/pipeline/limit/customData.ts @@ -0,0 +1,39 @@ +import Tabular from '../../tabular'; +import { + PipelineProcessor, + PipelineProcessorProps, + ProcessorType, +} from '../processor'; + +interface CustomDataProps extends PipelineProcessorProps { + page: number; + limit: number; + data: (page: number, limit: number) => Promise; +} + +class CustomDataLimit extends PipelineProcessor { + protected validateProps(): void { + if ( + isNaN(Number(this.props.limit)) || + isNaN(Number(this.props.page)) || + !this.props.data + ) { + throw Error('Invalid parameters passed'); + } + } + + get type(): ProcessorType { + return ProcessorType.Limit; + } + + protected async _process(): Promise { + const data = await this.props.data(this.props.page, this.props.limit); + + const tab = Tabular.fromArray(data); + tab.length = data.length; + + return tab; + } +} + +export default CustomDataLimit; diff --git a/src/view/plugin/pagination.tsx b/src/view/plugin/pagination.tsx index d8feb1b5..fb5a0f84 100644 --- a/src/view/plugin/pagination.tsx +++ b/src/view/plugin/pagination.tsx @@ -5,6 +5,7 @@ import ServerPaginationLimit from '../../pipeline/limit/serverPagination'; import { useConfig } from '../../hooks/useConfig'; import { useEffect, useRef, useState } from 'preact/hooks'; import { useTranslator } from '../../i18n/language'; +import CustomDataLimit from 'src/pipeline/limit/customData'; export interface PaginationConfig { limit?: number; @@ -18,6 +19,8 @@ export interface PaginationConfig { url?: (prevUrl: string, page: number, limit: number) => string; body?: (prevBody: BodyInit, page: number, limit: number) => BodyInit; }; + forceTotal?: number; + customData?: (page: number, limit: number) => Promise; } export function Pagination() { @@ -31,9 +34,13 @@ export function Pagination() { limit = 10, page = 0, resetPageOnUpdate = true, + forceTotal, + customData, } = config.pagination as PaginationConfig; - const processor = useRef(null); + const processor = useRef< + PaginationLimit | ServerPaginationLimit | CustomDataLimit + >(null); const [currentPage, setCurrentPage] = useState(page); const [total, setTotal] = useState(0); const _ = useTranslator(); @@ -46,6 +53,12 @@ export function Pagination() { url: server.url, body: server.body, }); + } else if (customData !== undefined && forceTotal) { + processor.current = new CustomDataLimit({ + limit: limit, + page: currentPage, + data: customData, + }); } else { processor.current = new PaginationLimit({ limit: limit, @@ -55,12 +68,16 @@ export function Pagination() { if (processor.current instanceof ServerPaginationLimit) { config.pipeline.on('afterProcess', (tabular) => setTotal(tabular.length)); + } else if (processor.current instanceof CustomDataLimit) { + processor.current.on('beforeProcess', (tabular) => + setTotal(forceTotal || tabular.length), + ); } else if (processor.current instanceof PaginationLimit) { // Pagination (all Limit processors) is the last step in the pipeline // and we assume that at this stage, we have the rows that we care about. // Let's grab the rows before processing Pagination and set total number of rows processor.current.on('beforeProcess', (tabular) => - setTotal(tabular.length), + setTotal(forceTotal || tabular.length), ); } @@ -122,6 +139,7 @@ export function Pagination() {