diff --git a/src/components/Tables/tenders/index.tsx b/src/components/Tables/tenders/index.tsx index 3766c09..c29b5e5 100644 --- a/src/components/Tables/tenders/index.tsx +++ b/src/components/Tables/tenders/index.tsx @@ -42,6 +42,7 @@ const TendersTable = () => { navigateToTenderDetails, navigateToTenderFeedback, handlePaginationChange, + buildWindowedPageLabel, getRowNumber, formatDateTimeCell, pagination, @@ -157,6 +158,9 @@ const TendersTable = () => { currentPage={pagination.currentPage} totalPages={pagination.totalPages} onPageChange={handlePaginationChange} + pageRangeDisplayed={3} + marginPagesDisplayed={1} + pageLabelBuilder={buildWindowedPageLabel} /> diff --git a/src/components/Tables/tenders/useTenderListPresenter.ts b/src/components/Tables/tenders/useTenderListPresenter.ts index 8857abb..8143707 100644 --- a/src/components/Tables/tenders/useTenderListPresenter.ts +++ b/src/components/Tables/tenders/useTenderListPresenter.ts @@ -346,6 +346,42 @@ const useTenderListPresenter = () => { error, }); + const MAX_PAGE_JUMP = 10; + const paginationWindow = useMemo(() => { + const windowStart = Math.max(0, pagination.currentPage - MAX_PAGE_JUMP); + const windowEnd = Math.min( + Math.max(pagination.totalPages - 1, 0), + pagination.currentPage + MAX_PAGE_JUMP, + ); + return { + windowStart, + virtualCurrent: pagination.currentPage - windowStart, + virtualTotal: Math.max(windowEnd - windowStart + 1, 1), + }; + }, [pagination.currentPage, pagination.totalPages]); + + const handleWindowedPaginationChange = useCallback( + (e: { selected: number }) => { + handlePaginationChange({ + selected: e.selected + paginationWindow.windowStart, + }); + }, + [handlePaginationChange, paginationWindow.windowStart], + ); + + const buildWindowedPageLabel = useCallback( + (virtualPage: number) => String(virtualPage + paginationWindow.windowStart), + [paginationWindow.windowStart], + ); + + const windowedPagination = useMemo( + () => ({ + currentPage: paginationWindow.virtualCurrent, + totalPages: paginationWindow.virtualTotal, + }), + [paginationWindow.virtualCurrent, paginationWindow.virtualTotal], + ); + const shouldShowPagination = !isPending && (data?.meta?.pages ?? 1) * (data?.meta?.limit ?? 10) > 10; @@ -498,10 +534,11 @@ const useTenderListPresenter = () => { tendersList, navigateToTenderDetails, navigateToTenderFeedback, - handlePaginationChange, + handlePaginationChange: handleWindowedPaginationChange, + buildWindowedPageLabel, getRowNumber, formatDateTimeCell, - pagination, + pagination: windowedPagination, }; }; diff --git a/src/components/ui/pagination.tsx b/src/components/ui/pagination.tsx index b19a474..e63fd6a 100644 --- a/src/components/ui/pagination.tsx +++ b/src/components/ui/pagination.tsx @@ -4,13 +4,23 @@ interface IProps { currentPage: number; totalPages: number; onPageChange: ReactPaginateProps["onPageChange"]; + pageRangeDisplayed?: number; + marginPagesDisplayed?: number; + pageLabelBuilder?: ReactPaginateProps["pageLabelBuilder"]; } /** Full-cell hit target: styles live on