Skip to content
This repository was archived by the owner on Jun 4, 2024. It is now read-only.

Commit 4ccba6e

Browse files
author
Shammamah Hossain
committed
Refactor paginator code.
1 parent 31a562e commit 4ccba6e

File tree

4 files changed

+83
-132
lines changed

4 files changed

+83
-132
lines changed

src/dash-table/components/ControlledTable/index.tsx

+3-2
Original file line numberDiff line numberDiff line change
@@ -797,7 +797,7 @@ export default class ControlledTable extends PureComponent<ControlledTableProps>
797797
tooltip_duration
798798
);
799799

800-
const { export_columns, export_format, export_headers, virtual, merge_duplicate_headers, paginator, page_current } = this.props;
800+
const { export_columns, export_format, export_headers, virtual, merge_duplicate_headers, paginator, page_current, page_count } = this.props;
801801
const buttonProps = {
802802
export_columns,
803803
export_format,
@@ -852,7 +852,8 @@ export default class ControlledTable extends PureComponent<ControlledTableProps>
852852
{!this.displayPagination ? null : (
853853
<PageNavigation
854854
paginator={paginator}
855-
page_current={page_current} />
855+
page_current={page_current}
856+
page_count={page_count} />
856857
)}
857858
</div>);
858859
}

src/dash-table/components/PageNavigation/index.tsx

+5-5
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ export default class PageNavigation extends Component<IPageNavigationProps> {
1818
return;
1919
}
2020

21-
paginator.goToPage(page);
21+
paginator.loadPage(page - 1);
2222
}
2323

2424
render() {
@@ -27,7 +27,7 @@ export default class PageNavigation extends Component<IPageNavigationProps> {
2727
page_current
2828
} = this.props;
2929

30-
return (paginator.lastPage === 0 ? null : (
30+
return (paginator.lastPage !== undefined && paginator.lastPage <= 0) ? null : (
3131
<div className='previous-next-container'>
3232
<button
3333
className='first-page'
@@ -54,9 +54,9 @@ export default class PageNavigation extends Component<IPageNavigationProps> {
5454
>
5555
</input>
5656

57-
{paginator.lastPage ? ' / ' : ''}
57+
{paginator.lastPage !== undefined ? ' / ' : ''}
5858

59-
{paginator.lastPage ? <div className='last-page'>
59+
{paginator.lastPage !== undefined ? <div className='last-page'>
6060
{paginator.lastPage + 1}
6161
</div> : ''}
6262
</div>
@@ -71,7 +71,7 @@ export default class PageNavigation extends Component<IPageNavigationProps> {
7171
<button
7272
className='last-page'
7373
onClick={paginator.loadLast}
74-
disabled={!paginator.hasLast()}>
74+
disabled={paginator.lastPage === undefined || paginator.isLast()}>
7575
<FontAwesomeIcon icon='angle-double-right' />
7676
</button>
7777
</div>

src/dash-table/components/PageNavigation/props.ts

+1
Original file line numberDiff line numberDiff line change
@@ -3,4 +3,5 @@ import { IPaginator } from 'dash-table/derived/paginator';
33
export interface IPageNavigationProps {
44
paginator: IPaginator;
55
page_current: number;
6+
page_count: number | undefined;
67
}

src/dash-table/derived/paginator.ts

+74-125
Original file line numberDiff line numberDiff line change
@@ -13,169 +13,118 @@ export interface IPaginator {
1313
loadPrevious(): void;
1414
loadFirst(): void;
1515
loadLast(): void;
16-
lastPage: number | undefined;
17-
goToPage(page: number): void;
16+
loadPage(page: number): void;
1817
hasPrevious(): boolean;
1918
hasNext(): boolean;
20-
hasLast(): boolean;
21-
}
22-
23-
export function lastPage(data: Data, page_size: number) {
24-
return Math.max(Math.ceil(data.length / page_size) - 1, 0);
25-
}
26-
27-
export function loadPrevious(page_current: number, setProps: SetProps) {
28-
if (page_current <= 0) {
29-
return;
30-
}
31-
32-
page_current--;
33-
setProps({ page_current, ...clearSelection });
19+
isLast(): boolean;
20+
lastPage: number | undefined;
3421
}
3522

36-
export function loadFirst(page_current: number, setProps: SetProps) {
37-
page_current = 0;
38-
setProps({ page_current, ...clearSelection });
23+
export interface IPaginatorParams {
24+
setProps: SetProps;
25+
page_current: number;
26+
page_count: number | undefined;
3927
}
4028

41-
export function hasPrevious(page_current: number) {
42-
return (page_current !== 0);
29+
export function lastPage(
30+
data: Data,
31+
page_size: number
32+
) {
33+
return Math.ceil(data.length / page_size);
4334
}
4435

45-
function getBackEndPagination(
46-
page_current: number,
47-
setProps: SetProps,
48-
page_count: number | undefined
36+
function makePaginator(
37+
params: IPaginatorParams | null
4938
): IPaginator {
5039

51-
// adjust for zero-indexing
52-
if (page_count) {
53-
page_count = Math.max(0, page_count - 1);
40+
if (params === null) {
41+
return {
42+
loadNext() { },
43+
loadPrevious() { },
44+
loadFirst() { },
45+
loadLast() { },
46+
loadPage() { },
47+
hasPrevious() { return true; },
48+
hasNext() { return true; },
49+
isLast() { return false; },
50+
lastPage: undefined
51+
};
5452
}
5553

56-
return {
57-
loadNext: () => {
58-
page_current++;
59-
setProps({ page_current, ...clearSelection });
60-
},
61-
loadPrevious: () => loadPrevious(page_current, setProps),
62-
loadFirst: () => loadFirst(page_current, setProps),
63-
loadLast: () => {
64-
if (page_count) {
65-
page_current = page_count;
66-
setProps({ page_current, ...clearSelection });
67-
}
68-
},
69-
lastPage: page_count,
70-
goToPage: (page: number) => {
71-
72-
// adjust for zero-indexing
73-
page--;
74-
75-
page_current = page;
54+
let {
55+
setProps,
56+
page_current,
57+
page_count
58+
} = params;
59+
60+
function updatePage() {
61+
setProps({
62+
page_current,
63+
...clearSelection
64+
});
65+
}
7666

77-
if (page < 0) {
78-
page_current = 0;
79-
}
67+
function loadPage(page: number) {
8068

81-
if (page_count && page > page_count) {
82-
page_current = page_count;
83-
}
69+
page = Math.max(0, page);
70+
page = page_count ? Math.min(page_count - 1, page) : page;
8471

85-
setProps({ page_current, ...clearSelection });
86-
},
87-
hasPrevious: () => hasPrevious(page_current),
88-
hasNext: () => {
89-
return page_count === undefined || page_current !== page_count;
90-
},
91-
hasLast: () => {
92-
return !page_count ? false : page_current !== page_count;
93-
}
94-
};
95-
}
72+
page_current = page;
73+
updatePage();
74+
}
9675

97-
function getFrontEndPagination(
98-
page_current: number,
99-
page_size: number,
100-
setProps: SetProps,
101-
data: Data
102-
) {
10376
return {
104-
loadNext: () => {
105-
const maxPageIndex = lastPage(data, page_size);
10677

107-
if (page_current >= maxPageIndex) {
108-
return;
109-
}
78+
loadNext: () => loadPage(page_current + 1),
11079

111-
page_current++;
112-
setProps({ page_current, ...clearSelection });
113-
},
114-
loadPrevious: () => loadPrevious(page_current, setProps),
115-
loadFirst: () => loadFirst(page_current, setProps),
116-
loadLast: () => {
117-
page_current = lastPage(data, page_size);
118-
setProps({ page_current, ...clearSelection });
119-
},
120-
lastPage: lastPage(data, page_size),
121-
goToPage: (page: number) => {
80+
loadPrevious: () => loadPage(page_current - 1),
12281

123-
page--;
82+
loadFirst: () => loadPage(0),
12483

125-
page_current = page;
84+
loadPage,
12685

127-
if (page < 0) {
128-
page_current = 0;
129-
}
130-
131-
if (page > lastPage(data, page_size)) {
132-
page_current = lastPage(data, page_size);
133-
}
86+
loadLast: () => {
87+
if (page_count) { loadPage(page_count - 1); }
88+
},
13489

135-
setProps({ page_current, ...clearSelection });
90+
hasPrevious: () => {
91+
return page_current !== 0;
13692
},
137-
hasPrevious: () => hasPrevious(page_current),
93+
13894
hasNext: () => {
139-
return (page_current !== lastPage(data, page_size));
95+
return page_count ? page_current !== page_count - 1 : true;
14096
},
141-
hasLast: () => {
142-
return (page_current !== lastPage(data, page_size));
143-
}
144-
};
145-
}
14697

147-
function getNoPagination() {
148-
return {
149-
loadNext: () => { },
150-
loadPrevious: () => { },
151-
loadFirst: () => { },
152-
loadLast: () => { },
153-
lastPage: 0,
154-
goToPage: () => { },
155-
hasPrevious: () => false,
156-
hasNext: () => false,
157-
hasLast: () => false
98+
isLast: () => {
99+
return page_count ? page_current === page_count - 1 : false;
100+
},
101+
102+
lastPage: page_count ? Math.max(0, page_count - 1) : undefined
158103
};
159104
}
160105

161106
const getter = (
162-
page_action: TableAction,
107+
table_action: TableAction,
163108
page_current: number,
164109
page_size: number,
165110
page_count: number | undefined,
166111
setProps: SetProps,
167112
data: Data
168113
): IPaginator => {
169-
switch (page_action) {
170-
case TableAction.None:
171-
return getNoPagination();
172-
case TableAction.Native:
173-
return getFrontEndPagination(page_current, page_size, setProps, data);
174-
case TableAction.Custom:
175-
return getBackEndPagination(page_current, setProps, page_count);
176-
default:
177-
throw new Error(`Unknown pagination mode: '${page_action}'`);
114+
115+
if (table_action === TableAction.Native) {
116+
page_count = lastPage(data, page_size);
178117
}
118+
119+
if (page_count) page_count = Math.max(page_count, 1);
120+
121+
return makePaginator(
122+
table_action === TableAction.None ? null : {
123+
setProps,
124+
page_current,
125+
page_count
126+
}
127+
);
179128
};
180129

181130
export default memoizeOneFactory(getter);

0 commit comments

Comments
 (0)