Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src/pipeline/limit/customData.ts
Original file line number Diff line number Diff line change
@@ -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<any[]>;
}

class CustomDataLimit extends PipelineProcessor<Tabular, CustomDataProps> {
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<Tabular> {
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;
26 changes: 24 additions & 2 deletions src/view/plugin/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand All @@ -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<any[]>;
}

export function Pagination() {
Expand All @@ -31,9 +34,13 @@ export function Pagination() {
limit = 10,
page = 0,
resetPageOnUpdate = true,
forceTotal,
customData,
} = config.pagination as PaginationConfig;

const processor = useRef<PaginationLimit | ServerPaginationLimit>(null);
const processor = useRef<
PaginationLimit | ServerPaginationLimit | CustomDataLimit
>(null);
const [currentPage, setCurrentPage] = useState(page);
const [total, setTotal] = useState(0);
const _ = useTranslator();
Expand All @@ -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,
Expand All @@ -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),
);
}

Expand Down Expand Up @@ -122,6 +139,7 @@ export function Pagination() {
<button
tabIndex={0}
role="button"
type={'button'}
onClick={() => setPage(0)}
title={_('pagination.firstPage')}
aria-label={_('pagination.firstPage')}
Expand All @@ -147,6 +165,7 @@ export function Pagination() {
<button
tabIndex={0}
role="button"
type={'button'}
onClick={() => setPage(i)}
className={classJoin(
currentPage === i
Expand Down Expand Up @@ -178,6 +197,7 @@ export function Pagination() {
<button
tabIndex={0}
role="button"
type={'button'}
onClick={() => setPage(pages() - 1)}
title={_('pagination.page', pages())}
aria-label={_('pagination.page', pages())}
Expand Down Expand Up @@ -229,6 +249,7 @@ export function Pagination() {
<button
tabIndex={0}
role="button"
type={'button'}
disabled={currentPage === 0}
onClick={() => setPage(currentPage - 1)}
title={_('pagination.previous')}
Expand All @@ -248,6 +269,7 @@ export function Pagination() {
<button
tabIndex={0}
role="button"
type={'button'}
disabled={pages() === currentPage + 1 || pages() === 0}
onClick={() => setPage(currentPage + 1)}
title={_('pagination.next')}
Expand Down