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

Commit fbea07a

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

File tree

5 files changed

+62
-26
lines changed

5 files changed

+62
-26
lines changed

src/components/Table/TableBase.tsx

Lines changed: 40 additions & 21 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

@@ -547,7 +559,6 @@ export class TableBase<T extends {}> extends React.Component<
547559
columns,
548560
data,
549561
usePager,
550-
itemsPerPage,
551562
pagerPosition,
552563
rowAnchorAttributes,
553564
rowKey,
@@ -557,20 +568,26 @@ export class TableBase<T extends {}> extends React.Component<
557568
getRowClass,
558569
className,
559570
fuzzyPager,
571+
pagination,
560572
} = this.props;
561573

562574
const { page, sort } = this.state;
563575
const items = data || [];
564-
const totalItems = items.length;
565-
const _itemsPerPage = itemsPerPage || 50;
576+
const totalItems = pagination?.totalItems ?? items.length;
577+
const _itemsPerPage = pagination?.itemsPerPage || DEFAULT_ITEMS_PER_PAGE;
566578
const _pagerPosition = pagerPosition || 'top';
567579

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

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

575592
const shouldShowPaper = !!usePager && totalItems > 0;
576593

@@ -586,7 +603,7 @@ export class TableBase<T extends {}> extends React.Component<
586603
fuzzy={fuzzyPager}
587604
totalItems={totalItems}
588605
itemsPerPage={_itemsPerPage}
589-
page={page}
606+
page={pagination?.currentPage ?? page}
590607
nextPage={this.incrementPage}
591608
prevPage={this.decrementPage}
592609
mb={2}
@@ -730,7 +747,7 @@ export interface TableBaseProps<T> {
730747
/** A function that is called when a column is sorted */
731748
onSort?: (sort: TableSortOptions<T>) => void;
732749
/** A function that is called when the page is incremented, decremented and reset */
733-
onPageChange?: (page: number) => void;
750+
onPageChange?: (page: number, itemsPerPage: number) => void;
734751
/** sort options to be used both as a default sort, and on subsequent renders if the passed sort changes */
735752
sort?: TableSortOptions<T>;
736753
/** Attributes to pass to the anchor element used in a row */
@@ -753,6 +770,8 @@ export interface TableBaseProps<T> {
753770
fuzzyPager?: boolean;
754771
/** The number of items to be shown per page. Only used if `usePager` is true. Defaults to 50. */
755772
itemsPerPage?: number;
773+
/** Information from a server side pagination */
774+
pagination?: Pagination;
756775
/** 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`. */
757776
pagerPosition?: 'top' | 'bottom' | 'both';
758777
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)