Skip to content
This repository was archived by the owner on Jan 16, 2025. It is now read-only.

Commit 30b39b4

Browse files
committed
Add server side pagination
Change-type: minor Signed-off-by: Andrea Rosci <[email protected]>
1 parent 52f12ae commit 30b39b4

File tree

5 files changed

+66
-28
lines changed

5 files changed

+66
-28
lines changed

src/components/Table/TableBase.tsx

Lines changed: 44 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ const BaseTableWrapper = styled.div`
2424
max-width: 100%;
2525
border-bottom: 1px solid ${(props) => props.theme.colors.quartenary.main};
2626
`;
27+
export const DEFAULT_ITEMS_PER_PAGE = 50;
28+
export interface Pagination {
29+
currentPage?: number;
30+
itemsPerPage: number;
31+
totalItems?: number;
32+
serverSide?: boolean;
33+
}
2734

2835
interface InternalTableBaseProps {
2936
hasCheckbox: boolean;
@@ -170,7 +177,7 @@ export class TableBase<T extends {}> extends React.Component<
170177
}
171178

172179
public componentDidUpdate(prevProps: TableBaseProps<T>) {
173-
const { sort, checkedItems, data, itemsPerPage, rowKey } = this.props;
180+
const { sort, checkedItems, data, pagination, rowKey } = this.props;
174181
if (sort && !isEqual(prevProps.sort, sort)) {
175182
this.setState({
176183
sort,
@@ -186,10 +193,12 @@ export class TableBase<T extends {}> extends React.Component<
186193
this.setRowSelection(checkedItems);
187194
}
188195

189-
const totalItems = data?.length ?? 0;
196+
const totalItems = pagination?.totalItems ?? data?.length ?? 0;
197+
const currentPage = pagination?.currentPage ?? this.state.page;
190198
if (
191-
this.state.page !== 0 &&
192-
totalItems <= this.state.page * (itemsPerPage ?? 50)
199+
currentPage !== 1 &&
200+
totalItems <=
201+
currentPage * (pagination?.itemsPerPage ?? DEFAULT_ITEMS_PER_PAGE)
193202
) {
194203
this.resetPager();
195204
}
@@ -464,6 +473,7 @@ export class TableBase<T extends {}> extends React.Component<
464473
public toggleSort = (e: React.MouseEvent<HTMLButtonElement>) => {
465474
const { field } = e.currentTarget.dataset;
466475
const { sort } = this.state;
476+
const { pagination } = this.props;
467477
if (!field) {
468478
return;
469479
}
@@ -476,8 +486,9 @@ export class TableBase<T extends {}> extends React.Component<
476486
if (sort.field === field) {
477487
nextSort = { field: sort.field, reverse: !sort.reverse };
478488
}
479-
480-
this.setState({ sort: nextSort });
489+
if (!pagination?.serverSide) {
490+
this.setState({ sort: nextSort });
491+
}
481492

482493
if (this.props.onSort) {
483494
this.props.onSort(nextSort);
@@ -522,11 +533,12 @@ export class TableBase<T extends {}> extends React.Component<
522533
}
523534
};
524535

525-
public setPage = (change: any) => {
526-
if (this.props.onPageChange) {
527-
this.props.onPageChange(change);
528-
}
529-
536+
public setPage = (change: number) => {
537+
const { pagination } = this.props;
538+
this.props.onPageChange?.(
539+
change,
540+
pagination?.itemsPerPage ?? DEFAULT_ITEMS_PER_PAGE,
541+
);
530542
this.setState({ page: change });
531543
};
532544

@@ -535,19 +547,20 @@ export class TableBase<T extends {}> extends React.Component<
535547
};
536548

537549
public incrementPage = () => {
538-
this.setPage(this.state.page + 1);
550+
const newPage = this.state.page + 1;
551+
this.setPage(newPage);
539552
};
540553

541554
public decrementPage = () => {
542-
this.setPage(this.state.page - 1);
555+
const newPage = this.state.page - 1;
556+
this.setPage(newPage);
543557
};
544558

545559
public render() {
546560
const {
547561
columns,
548562
data,
549563
usePager,
550-
itemsPerPage,
551564
pagerPosition,
552565
rowAnchorAttributes,
553566
rowKey,
@@ -557,20 +570,26 @@ export class TableBase<T extends {}> extends React.Component<
557570
getRowClass,
558571
className,
559572
fuzzyPager,
573+
pagination,
560574
} = this.props;
561575

562576
const { page, sort } = this.state;
563577
const items = data || [];
564-
const totalItems = items.length;
565-
const _itemsPerPage = itemsPerPage || 50;
578+
const totalItems = pagination?.totalItems ?? items.length;
579+
const _itemsPerPage = pagination?.itemsPerPage || DEFAULT_ITEMS_PER_PAGE;
566580
const _pagerPosition = pagerPosition || 'top';
567581

568-
const lowerBound = usePager ? page * _itemsPerPage : 0;
569-
const upperBound = usePager
570-
? Math.min((page + 1) * _itemsPerPage, totalItems)
571-
: totalItems;
582+
const lowerBound =
583+
!pagination?.serverSide && usePager ? page * _itemsPerPage : 0;
584+
const upperBound =
585+
!pagination?.serverSide && usePager
586+
? Math.min((page + 1) * _itemsPerPage, totalItems)
587+
: totalItems;
572588

573-
const sortedData = this.sortData(items).slice(lowerBound, upperBound);
589+
const sortedData =
590+
!pagination?.serverSide && usePager
591+
? this.sortData(items).slice(lowerBound, upperBound)
592+
: items;
574593

575594
const shouldShowPaper = !!usePager && totalItems > 0;
576595

@@ -586,7 +605,7 @@ export class TableBase<T extends {}> extends React.Component<
586605
fuzzy={fuzzyPager}
587606
totalItems={totalItems}
588607
itemsPerPage={_itemsPerPage}
589-
page={page}
608+
page={pagination?.currentPage ?? page}
590609
nextPage={this.incrementPage}
591610
prevPage={this.decrementPage}
592611
mb={2}
@@ -730,7 +749,7 @@ export interface TableBaseProps<T> {
730749
/** A function that is called when a column is sorted */
731750
onSort?: (sort: TableSortOptions<T>) => void;
732751
/** A function that is called when the page is incremented, decremented and reset */
733-
onPageChange?: (page: number) => void;
752+
onPageChange?: (page: number, itemsPerPage: number) => void;
734753
/** sort options to be used both as a default sort, and on subsequent renders if the passed sort changes */
735754
sort?: TableSortOptions<T>;
736755
/** Attributes to pass to the anchor element used in a row */
@@ -753,6 +772,8 @@ export interface TableBaseProps<T> {
753772
fuzzyPager?: boolean;
754773
/** The number of items to be shown per page. Only used if `usePager` is true. Defaults to 50. */
755774
itemsPerPage?: number;
775+
/** Information from a server side pagination */
776+
pagination?: Pagination;
756777
/** Sets whether the pager is displayed at the top of the table, the bottom of the table or in both positions. Only used if `usePager` is true. Defaults to `top`. */
757778
pagerPosition?: 'top' | 'bottom' | 'both';
758779
className?: string;

src/components/Table/index.tsx

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
import * as React from 'react';
2-
import { TableBase, TableBaseProps, TableSortOptions } from './TableBase';
2+
import {
3+
TableBase,
4+
TableBaseProps,
5+
TableSortOptions,
6+
Pagination,
7+
} from './TableBase';
38
import styled, { css } from 'styled-components';
49
import keys from 'lodash/keys';
510
import pick from 'lodash/pick';
@@ -710,7 +715,6 @@ export class Table<T extends {}> extends React.Component<
710715
onRowClick,
711716
...props
712717
} = this.props;
713-
714718
const sort =
715719
sortProp || (sortingStateRestorationKey ? this.state.sort : undefined);
716720

@@ -741,4 +745,10 @@ export class Table<T extends {}> extends React.Component<
741745
}
742746
}
743747

744-
export { TableBaseColumn, TableRow, TableSortOptions, TableSortFunction };
748+
export {
749+
TableBaseColumn,
750+
TableRow,
751+
TableSortOptions,
752+
TableSortFunction,
753+
Pagination,
754+
};

src/components/Table/spec.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -889,8 +889,7 @@ describe('Table component', () => {
889889
[{ field: 'Name' }] as Array<TableColumn<PokedexInterface>>
890890
}
891891
data={PokeDex}
892-
usePager
893-
itemsPerPage={3}
892+
pagination={{ itemsPerPage: 3 }}
894893
/>
895894
</Provider>,
896895
);

src/hooks/useTranslation.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ const translationMap = {
9090

9191
'warning.etcher_min_requirement': 'Etcher v1.7.2 or greater is required',
9292

93+
'loading.generic': 'Loading...',
9394
'loading.generating_configuration_file': 'Generating configuration file...',
9495
'loading.fetching_versions': 'Fetching versions...',
9596

src/index.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -89,6 +89,7 @@ export {
8989
TableSortOptions,
9090
TableProps,
9191
TableSortFunction,
92+
Pagination,
9293
} from './components/Table';
9394

9495
export { Accordion, AccordionProps } from './components/Accordion';
@@ -144,6 +145,12 @@ export {
144145

145146
export * as SchemaSieve from './components/Filters/SchemaSieve';
146147

148+
export { operators as stringOperators } from './components/DataTypes/string';
149+
export { operators as numberOperators } from './components/DataTypes/number';
150+
export { operators as booleanOperators } from './components/DataTypes/boolean';
151+
export { operators as objectOperators } from './components/DataTypes/object';
152+
export { operators as arrayOperators } from './components/DataTypes/array';
153+
147154
export {
148155
ResponsiveStyle,
149156
StyledSystemProps,

0 commit comments

Comments
 (0)