Files
ragflow/web/src/components/ui/ragflow-pagination.tsx
dcc123456 7f707ef5ed Fix: optimize the chunk result page (#8676)
### What problem does this PR solve?
fix: Create a new message component to replace the antd message
component, create a new Spin component to replace the antd Spin
component, optimize the original paging component style, and optimize
the chunk result page[
#3221](https://github.com/infiniflow/ragflow/issues/3221)

### Type of change

- [X] Bug Fix (non-breaking change which fixes an issue)
2025-07-04 19:00:30 +08:00

183 lines
4.6 KiB
TypeScript

import {
Pagination,
PaginationContent,
PaginationEllipsis,
PaginationItem,
PaginationLink,
PaginationNext,
PaginationPrevious,
} from '@/components/ui/pagination';
import { RAGFlowSelect, RAGFlowSelectOptionType } from '@/components/ui/select';
import { cn } from '@/lib/utils';
import { useCallback, useEffect, useMemo, useState } from 'react';
export type RAGFlowPaginationType = {
showQuickJumper?: boolean;
onChange?(page: number, pageSize: number): void;
total?: number;
current?: number;
pageSize?: number;
showSizeChanger?: boolean;
};
export function RAGFlowPagination({
current = 1,
pageSize = 10,
total = 0,
onChange,
showSizeChanger = true,
}: RAGFlowPaginationType) {
const [currentPage, setCurrentPage] = useState(1);
const [currentPageSize, setCurrentPageSize] = useState('10');
const sizeChangerOptions: RAGFlowSelectOptionType[] = useMemo(() => {
return [10, 20, 50, 100].map((x) => ({
label: <span>{x} / page</span>,
value: x.toString(),
}));
}, []);
const pages = useMemo(() => {
const num = Math.ceil(total / pageSize);
return new Array(num).fill(0).map((_, idx) => idx + 1);
}, [pageSize, total]);
const changePage = useCallback(
(page: number) => {
onChange?.(page, Number(currentPageSize));
},
[currentPageSize, onChange],
);
const handlePreviousPageChange = useCallback(() => {
setCurrentPage((page) => {
const previousPage = page - 1;
if (previousPage > 0) {
changePage(previousPage);
return previousPage;
}
changePage(page);
return page;
});
}, [changePage]);
const handlePageChange = useCallback(
(page: number) => () => {
changePage(page);
setCurrentPage(page);
},
[changePage],
);
const handleNextPageChange = useCallback(() => {
setCurrentPage((page) => {
const nextPage = page + 1;
if (nextPage <= pages.length) {
changePage(nextPage);
return nextPage;
}
changePage(page);
return page;
});
}, [changePage, pages.length]);
const handlePageSizeChange = useCallback(
(size: string) => {
onChange?.(currentPage, Number(size));
setCurrentPageSize(size);
},
[currentPage, onChange],
);
useEffect(() => {
setCurrentPage(current);
}, [current]);
useEffect(() => {
setCurrentPageSize(pageSize.toString());
}, [pageSize]);
// Generates an array of page numbers to display
const displayedPages = useMemo(() => {
const totalPages = pages.length;
const maxDisplayedPages = 5;
if (totalPages <= maxDisplayedPages) {
return pages;
}
const left = Math.max(2, currentPage - 2);
const right = Math.min(totalPages - 1, currentPage + 2);
const newPages = [];
newPages.push(1);
if (left > 2) {
newPages.push(-1); // Indicates an ellipsis
}
for (let i = left; i <= right; i++) {
newPages.push(i);
}
if (right < totalPages - 1) {
newPages.push(-1);
}
if (totalPages > 1) {
newPages.push(totalPages);
}
return newPages;
}, [pages, currentPage]);
return (
<section className="flex items-center justify-end text-text-sub-title-invert">
<span className="mr-4">Total {total}</span>
<Pagination className="w-auto mx-0 mr-4">
<PaginationContent>
<PaginationItem>
<PaginationPrevious onClick={handlePreviousPageChange} />
</PaginationItem>
{displayedPages.map((page, index) =>
page === -1 ? (
<PaginationItem key={`ellipsis-${index}`}>
<PaginationEllipsis />
</PaginationItem>
) : (
<PaginationItem
key={page}
className={cn({
['bg-background-header-bar rounded-md text-text-title']:
currentPage === page,
})}
>
<PaginationLink
onClick={handlePageChange(page)}
className="size-8"
>
{page}
</PaginationLink>
</PaginationItem>
),
)}
<PaginationItem>
<PaginationNext onClick={handleNextPageChange} />
</PaginationItem>
</PaginationContent>
</Pagination>
{showSizeChanger && (
<RAGFlowSelect
options={sizeChangerOptions}
value={currentPageSize}
onChange={handlePageSizeChange}
triggerClassName="bg-background-header-bar"
></RAGFlowSelect>
)}
</section>
);
}