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

Commit b307ce4

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

File tree

6 files changed

+64
-34
lines changed

6 files changed

+64
-34
lines changed

src/components/Table/TableBase.tsx

Lines changed: 46 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,15 @@ 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 type Pagination = { itemsPerPage?: number } & (
29+
| { serverSide?: undefined }
30+
| {
31+
serverSide: true;
32+
currentPage: number;
33+
totalItems: number;
34+
}
35+
);
2736

2837
interface InternalTableBaseProps {
2938
hasCheckbox: boolean;
@@ -170,7 +179,8 @@ export class TableBase<T extends {}> extends React.Component<
170179
}
171180

172181
public componentDidUpdate(prevProps: TableBaseProps<T>) {
173-
const { sort, checkedItems, data, itemsPerPage, rowKey } = this.props;
182+
const { sort, checkedItems, data, pagination, rowKey } = this.props;
183+
const serverSide = pagination?.serverSide;
174184
if (sort && !isEqual(prevProps.sort, sort)) {
175185
this.setState({
176186
sort,
@@ -186,10 +196,12 @@ export class TableBase<T extends {}> extends React.Component<
186196
this.setRowSelection(checkedItems);
187197
}
188198

189-
const totalItems = data?.length ?? 0;
199+
const totalItems = serverSide ? pagination?.totalItems : data?.length ?? 0;
200+
const currentPage = serverSide ? pagination?.currentPage : this.state.page;
190201
if (
191-
this.state.page !== 0 &&
192-
totalItems <= this.state.page * (itemsPerPage ?? 50)
202+
currentPage !== 0 &&
203+
totalItems <=
204+
currentPage * (pagination?.itemsPerPage ?? DEFAULT_ITEMS_PER_PAGE)
193205
) {
194206
this.resetPager();
195207
}
@@ -462,19 +474,20 @@ export class TableBase<T extends {}> extends React.Component<
462474
};
463475

464476
public toggleSort = (e: React.MouseEvent<HTMLButtonElement>) => {
465-
const { field } = e.currentTarget.dataset;
477+
const { field, refScheme } = e.currentTarget.dataset;
466478
const { sort } = this.state;
467479
if (!field) {
468480
return;
469481
}
470482

471483
let nextSort = {
472484
field: field as keyof T,
485+
refScheme,
473486
reverse: false,
474487
};
475488

476489
if (sort.field === field) {
477-
nextSort = { field: sort.field, reverse: !sort.reverse };
490+
nextSort = { field: sort.field, refScheme, reverse: !sort.reverse };
478491
}
479492

480493
this.setState({ sort: nextSort });
@@ -522,11 +535,12 @@ export class TableBase<T extends {}> extends React.Component<
522535
}
523536
};
524537

525-
public setPage = (change: any) => {
526-
if (this.props.onPageChange) {
527-
this.props.onPageChange(change);
528-
}
529-
538+
public setPage = (change: number) => {
539+
const { pagination } = this.props;
540+
this.props.onPageChange?.(
541+
change,
542+
pagination?.itemsPerPage ?? DEFAULT_ITEMS_PER_PAGE,
543+
);
530544
this.setState({ page: change });
531545
};
532546

@@ -547,7 +561,6 @@ export class TableBase<T extends {}> extends React.Component<
547561
columns,
548562
data,
549563
usePager,
550-
itemsPerPage,
551564
pagerPosition,
552565
rowAnchorAttributes,
553566
rowKey,
@@ -557,36 +570,37 @@ 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;
577+
const serverSide = pagination?.serverSide;
563578
const items = data || [];
564-
const totalItems = items.length;
565-
const _itemsPerPage = itemsPerPage || 50;
579+
const totalItems = serverSide ? pagination?.totalItems : items.length;
580+
const itemsPerPage = pagination?.itemsPerPage || DEFAULT_ITEMS_PER_PAGE;
566581
const _pagerPosition = pagerPosition || 'top';
582+
let sortedData = items;
567583

568-
const lowerBound = usePager ? page * _itemsPerPage : 0;
569-
const upperBound = usePager
570-
? Math.min((page + 1) * _itemsPerPage, totalItems)
571-
: totalItems;
572-
573-
const sortedData = this.sortData(items).slice(lowerBound, upperBound);
574-
575-
const shouldShowPaper = !!usePager && totalItems > 0;
584+
if (!serverSide) {
585+
const lowerBound = page * itemsPerPage;
586+
const upperBound = Math.min((page + 1) * itemsPerPage, items.length);
587+
sortedData = this.sortData(items).slice(lowerBound, upperBound);
588+
}
576589

590+
const shouldShowPager = !!usePager && totalItems > 0;
577591
const checkedRowIdentifiers = this.getCheckedRowIdentifiers();
578592
const highlightedRowIdentifiers = this.getHighlightedRowIdentifiers();
579593
const disabledRowIdentifiers = this.getDisabledRowIdentifiers();
580594

581595
return (
582596
<>
583-
{shouldShowPaper &&
597+
{shouldShowPager &&
584598
(_pagerPosition === 'top' || _pagerPosition === 'both') && (
585599
<Pager
586600
fuzzy={fuzzyPager}
587601
totalItems={totalItems}
588-
itemsPerPage={_itemsPerPage}
589-
page={page}
602+
itemsPerPage={itemsPerPage}
603+
page={serverSide ? pagination?.currentPage : page}
590604
nextPage={this.incrementPage}
591605
prevPage={this.decrementPage}
592606
mb={2}
@@ -620,6 +634,7 @@ export class TableBase<T extends {}> extends React.Component<
620634
>
621635
<Button
622636
data-field={item.field}
637+
data-ref-scheme={item.refScheme}
623638
plain
624639
primary={sort.field === item.field}
625640
onClick={this.toggleSort}
@@ -692,12 +707,12 @@ export class TableBase<T extends {}> extends React.Component<
692707
</Base>
693708
</BaseTableWrapper>
694709

695-
{shouldShowPaper &&
710+
{shouldShowPager &&
696711
(_pagerPosition === 'bottom' || _pagerPosition === 'both') && (
697712
<Pager
698713
fuzzy={fuzzyPager}
699714
totalItems={totalItems}
700-
itemsPerPage={_itemsPerPage}
715+
itemsPerPage={itemsPerPage}
701716
page={page}
702717
nextPage={this.incrementPage}
703718
prevPage={this.decrementPage}
@@ -712,6 +727,7 @@ export class TableBase<T extends {}> extends React.Component<
712727
export interface TableSortOptions<T> {
713728
reverse: boolean;
714729
field: keyof T | null;
730+
refScheme?: string;
715731
}
716732

717733
export interface TableBaseProps<T> {
@@ -730,7 +746,7 @@ export interface TableBaseProps<T> {
730746
/** A function that is called when a column is sorted */
731747
onSort?: (sort: TableSortOptions<T>) => void;
732748
/** A function that is called when the page is incremented, decremented and reset */
733-
onPageChange?: (page: number) => void;
749+
onPageChange?: (page: number, itemsPerPage: number) => void;
734750
/** sort options to be used both as a default sort, and on subsequent renders if the passed sort changes */
735751
sort?: TableSortOptions<T>;
736752
/** Attributes to pass to the anchor element used in a row */
@@ -753,6 +769,8 @@ export interface TableBaseProps<T> {
753769
fuzzyPager?: boolean;
754770
/** The number of items to be shown per page. Only used if `usePager` is true. Defaults to 50. */
755771
itemsPerPage?: number;
772+
/** Information from a server side pagination */
773+
pagination?: Pagination;
756774
/** 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`. */
757775
pagerPosition?: 'top' | 'bottom' | 'both';
758776
className?: string;

src/components/Table/TableRow.tsx

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ export interface TableBaseColumn<T> {
3434
row: T,
3535
) => string | number | JSX.Element | null | undefined;
3636
sortable?: boolean | TableSortFunction<T>;
37+
refScheme?: string;
3738
}
3839

3940
export interface TableRowProps<T> {

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: 2 additions & 3 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
);
@@ -950,7 +949,7 @@ describe('Table component', () => {
950949
{
951950
columns: [{ field: 'Name' }] as any,
952951
data: PokeDex,
953-
itemsPerPage: 2,
952+
pagination: { itemsPerPage: 2 },
954953
usePager: true,
955954
},
956955
),

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: 1 addition & 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';

0 commit comments

Comments
 (0)