Skip to content

Commit

Permalink
fix: dataTable pagination (#397)
Browse files Browse the repository at this point in the history
* fix: pagination button

* fix: button style
  • Loading branch information
islxyqwe authored Aug 28, 2024
1 parent c4aaa5c commit 23e5838
Show file tree
Hide file tree
Showing 3 changed files with 176 additions and 45 deletions.
9 changes: 6 additions & 3 deletions packages/graphic-walker/jest.config.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,8 @@
/** @type {import('ts-jest').JestConfigWithTsJest} */
module.exports = {
preset: 'ts-jest',
testEnvironment: 'node',
};
preset: 'ts-jest',
testEnvironment: 'node',
moduleNameMapper: {
'^@/(.*)$': '<rootDir>/src/$1',
},
};
113 changes: 113 additions & 0 deletions packages/graphic-walker/src/components/dataTable/pagination.test.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import { getShowIndices } from './pagination';

describe('getShowIndices', () => {
const pageSize = 50;
const extendPageNumber = 1;
test('totalpage 1', () => {
expect(getShowIndices(25, 0, pageSize, extendPageNumber)).toEqual([{ index: 0, disabled: false, type: 'page' }]);
});
test('totalpage 2', () => {
expect(getShowIndices(100, 0, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
]);
});
test('totalpage 3', () => {
expect(getShowIndices(150, 0, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: 2, disabled: false, type: 'page' },
]);
});
test('totalpage 4', () => {
expect(getShowIndices(200, 0, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 3, disabled: false, type: 'page' },
]);
});
test('totalpage 5', () => {
expect(getShowIndices(250, 0, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 4, disabled: false, type: 'page' },
]);
});
test('totalpage 300', () => {
expect(getShowIndices(15000, 0, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 299, disabled: false, type: 'page' },
]);
});
test('totalpage 300 pageIndex 150', () => {
expect(getShowIndices(15000, 150, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 149, disabled: false, type: 'page' },
{ index: 150, disabled: false, type: 'page' },
{ index: 151, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 299, disabled: false, type: 'page' },
]);
});
test('totalpage 2 pageIndex 1', () => {
expect(getShowIndices(100, 1, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
]);
});
test('totalpage 3 pageIndex 1', () => {
expect(getShowIndices(150, 1, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: 2, disabled: false, type: 'page' },
]);
});
test('totalpage 4 pageIndex 1', () => {
expect(getShowIndices(200, 1, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: 2, disabled: false, type: 'page' },
{ index: 3, disabled: false, type: 'page' },
]);
});
test('totalpage 5 pageIndex 1', () => {
expect(getShowIndices(250, 1, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: 2, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 4, disabled: false, type: 'page' },
]);
});
test('totalpage 5 pageIndex 2', () => {
expect(getShowIndices(250, 2, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: 1, disabled: false, type: 'page' },
{ index: 2, disabled: false, type: 'page' },
{ index: 3, disabled: false, type: 'page' },
{ index: 4, disabled: false, type: 'page' },
]);
});
test('totalpage 5 pageIndex 3', () => {
expect(getShowIndices(250, 3, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 2, disabled: false, type: 'page' },
{ index: 3, disabled: false, type: 'page' },
{ index: 4, disabled: false, type: 'page' },
]);
});
test('totalpage 5 pageIndex 4', () => {
expect(getShowIndices(250, 4, pageSize, extendPageNumber)).toEqual([
{ index: 0, disabled: false, type: 'page' },
{ index: -1, type: 'placeholder' },
{ index: 3, disabled: false, type: 'page' },
{ index: 4, disabled: false, type: 'page' },
]);
});
});
99 changes: 57 additions & 42 deletions packages/graphic-walker/src/components/dataTable/pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,43 +25,61 @@ interface PaginationProps {
extendPageNumber?: number;
}

export function getShowIndices(total: number, pageIndex: number, pageSize: number, extendPageNumber: number) {
const totalPage = Math.ceil(total / (pageSize || 1));
const pages = [
{
index: 0,
disabled: false,
type: 'page',
},
...(new Array(1 + extendPageNumber * 2).fill(0).map((p, i) => ({
index: pageIndex - (extendPageNumber - i),
disabled: false,
type: 'page',
})) as IPageItem[]),
{
index: totalPage - 1,
disabled: false,
type: 'page',
},
].filter((p) => p.index >= 0 && p.index < totalPage) as IPageItem[];

const pagesUnique: IPageItem[] = [];
const indexSet: Set<number> = new Set();
for (let p of pages) {
if (!indexSet.has(p.index)) {
pagesUnique.push(p);
indexSet.add(p.index);
}
}
const pageResult: IPageItem[] = pagesUnique.reduce<IPageItem[]>((acc, p) => {
if (acc.length === 0) {
return [p];
}
const last = acc[acc.length - 1];
if (p.index === last.index + 1) {
return [...acc, p];
}
return [...acc, { index: -1, type: 'placeholder' }, p];
}, []);
return pageResult;
}

export default function Pagination(props: PaginationProps) {
const { total, onNext, onPrev, pageIndex, onPageChange, pageSize = 100, extendPageNumber = 1 } = props;
const { t } = useTranslation();
const showIndices: IPageItem[] = useMemo<IPageItem[]>(() => {
const totalPage = Math.ceil(total / (pageSize ?? 1));
const pages = [
{
index: 0,
disabled: false,
type: 'page',
},
...(new Array(1 + extendPageNumber * 2).fill(0).map((p, i) => ({
index: pageIndex - (extendPageNumber - i),
disabled: false,
type: 'page',
})) as IPageItem[]),
{
index: totalPage - 1,
disabled: false,
type: 'page',
},
].filter((p) => p.index >= 0 && p.index < totalPage) as IPageItem[];
const pagesUnique: IPageItem[] = [];
const indexSet: Set<number> = new Set();
for (let p of pages) {
if (!indexSet.has(p.index)) {
pagesUnique.push(p);
indexSet.add(p.index);
}
}
return pagesUnique;
}, [pageIndex, pageSize, extendPageNumber, total, pageIndex]);
const showIndices: IPageItem[] = useMemo<IPageItem[]>(
() => getShowIndices(total, pageIndex, pageSize, extendPageNumber),
[pageIndex, pageSize, extendPageNumber, total, pageIndex]
);

const pageButton = (index: number) => {
return (
<PaginationItem key={index}>
<PaginationLink
size="default"
className='px-3 min-w-[2.25rem]'
isActive={index === pageIndex}
onClick={() => {
onPageChange && onPageChange(index);
Expand All @@ -85,19 +103,16 @@ export default function Pagination(props: PaginationProps) {
{t('actions.prev')}
</PaginationPrevious>
</PaginationItem>
{pageButton(showIndices[0].index)}
{showIndices.length > 2 && showIndices[1].index > showIndices[0].index + 1 && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}
{showIndices.slice(1, showIndices.length > 2 ? -1 : undefined).map((page) => pageButton(page.index))}
{showIndices.length > 2 && showIndices[showIndices.length - 1].index > showIndices[showIndices.length - 2].index + 1 && (
<PaginationItem>
<PaginationEllipsis />
</PaginationItem>
)}
{showIndices.length > 2 && pageButton(showIndices[showIndices.length - 1].index)}
{showIndices.map((x) => {
if (x.type === 'placeholder') {
return (
<PaginationItem key={x.index}>
<PaginationEllipsis />
</PaginationItem>
);
}
return pageButton(x.index);
})}
<PaginationItem>
<PaginationNext
onClick={() => {
Expand Down

0 comments on commit 23e5838

Please sign in to comment.