Skip to content

Commit

Permalink
Data Table legacy improvements (#2294)
Browse files Browse the repository at this point in the history
OKTA-753577 feat: add max pages and max rows per page to pagination
feat: add manual pagination next disabling
feat: reset pagination if search or filters changes
refactor: alphabetize props
feat: fixing pagination bug
refactor: improve pagination calculation
refactor: update currentRowsCount to be non-breaking
  • Loading branch information
jordankoschei-okta authored Jul 24, 2024
1 parent 451388d commit 84f3af3
Show file tree
Hide file tree
Showing 10 changed files with 239 additions and 67 deletions.
28 changes: 28 additions & 0 deletions packages/odyssey-react-mui/src/DataTable/DataTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,10 @@ export type DataTableProps = {
* The initial search value
*/
initialSearchValue?: string;
/**
* Is the next or show-more button disabled
*/
isPaginationMoreDisabled?: boolean;
/**
* The component to display when the query returns no results
*/
Expand Down Expand Up @@ -240,6 +244,15 @@ export type DataTableProps = {
* to calculate. Used in table pagination to know when to disable the "next"/"more" button.
*/
totalRows?: number;
/**
* The largest number of rows allowed to be shown per page. This only affects the row input
* in pagination.
*/
maxResultsPerPage?: number;
/**
* The highest page number allowed to be manually input in pagination
*/
maxPages?: number;
};

const displayColumnDefOptions = {
Expand Down Expand Up @@ -376,12 +389,15 @@ const DataTable = ({
hasSorting,
initialDensity = densityValues[0],
initialSearchValue = "",
isPaginationMoreDisabled,
noResultsPlaceholder,
onChangeRowSelection,
onReorderRows,
paginationType = "paged",
renderDetailPanel,
resultsPerPage = 20,
maxResultsPerPage,
maxPages,
rowActionButtons,
rowActionMenuItems,
searchDelayTime,
Expand Down Expand Up @@ -809,11 +825,19 @@ const DataTable = ({
resultsPerPage,
]);

useEffect(() => {
setPagination((prev) => ({
pageIndex: 1,
pageSize: prev.pageSize,
}));
}, [filters, search]);

useEffect(() => {
onChangeRowSelection?.(rowSelection);
}, [rowSelection, onChangeRowSelection]);

const { lastRow } = usePagination({
currentRowsCount: data.length,
pageIndex: pagination.pageIndex,
pageSize: pagination.pageSize,
totalRows,
Expand Down Expand Up @@ -873,10 +897,14 @@ const DataTable = ({
<Pagination
pageIndex={pagination.pageIndex}
pageSize={pagination.pageSize}
maxPageIndex={maxPages}
maxPageSize={maxResultsPerPage}
onPaginationChange={setPagination}
lastRow={lastRow}
totalRows={totalRows}
currentRowsCount={data.length}
isDisabled={isEmpty}
isMoreDisabled={isPaginationMoreDisabled}
variant={paginationType}
rowsPerPageLabel={t("pagination.rowsperpage")}
currentPageLabel={t("pagination.page")}
Expand Down
128 changes: 82 additions & 46 deletions packages/odyssey-react-mui/src/Pagination/Pagination.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -66,75 +66,95 @@ const PaginationButtonContainer = styled("div")({

export type PaginationProps = {
/**
* The current page index
* The labeled rendered for the current page index
*/
pageIndex: number;
currentPageLabel: string;
/**
* The current page size
* The number of items currently visible on the page
*/
pageSize: number;
currentRowsCount?: number;
/**
* Page index and page size setter
* If true, the pagination controls will be disabled
*/
onPaginationChange: ({
pageIndex,
pageSize,
}: {
pageIndex: number;
pageSize: number;
}) => void;
isDisabled?: boolean;
/**
* If true, the next or Show More button will be disabled
*/
isMoreDisabled?: boolean;
/**
* The current page last row index
*/
lastRow: number;
/**
* Total rows count
* If the pagination is of "loadMore" variant, then this is the the load more label
*/
totalRows?: number;
loadMoreLabel: string;
/**
* If true, the pagination controls will be disabled
* The max page
*/
isDisabled?: boolean;
maxPageIndex?: number;
/**
* The type of pagination controls shown. Defaults to next/prev buttons, but can be
* set to a simple "Load more" button by setting to "loadMore".
* The max rows per page
*/
variant?: (typeof paginationTypeValues)[number];
maxPageSize?: number;
/**
* The label that shows how many results are rendered per page
* The label for the next control
*/
rowsPerPageLabel: string;
nextLabel: string;
/**
* The labeled rendered for the current page index
* Page index and page size setter
*/
currentPageLabel: string;
onPaginationChange: ({
pageIndex,
pageSize,
}: {
pageIndex: number;
pageSize: number;
}) => void;
/**
* The current page index
*/
pageIndex: number;
/**
* The current page size
*/
pageSize: number;
/**
* The label for the previous control
*/
previousLabel: string;
/**
* The label for the next control
* The label that shows how many results are rendered per page
*/
nextLabel: string;
rowsPerPageLabel: string;
/**
* If the pagination is of "loadMore" variant, then this is the the load more label
* Total rows count
*/
loadMoreLabel: string;
totalRows?: number;
/**
* The type of pagination controls shown. Defaults to next/prev buttons, but can be
* set to a simple "Load more" button by setting to "loadMore".
*/
variant?: (typeof paginationTypeValues)[number];
};

const Pagination = ({
currentPageLabel,
isDisabled,
isMoreDisabled,
lastRow,
loadMoreLabel,
maxPageIndex,
maxPageSize,
nextLabel,
onPaginationChange,
pageIndex,
pageSize,
onPaginationChange,
lastRow,
previousLabel,
rowsPerPageLabel,
totalRows,
isDisabled,
currentRowsCount,
variant,
rowsPerPageLabel,
currentPageLabel,
previousLabel,
nextLabel,
loadMoreLabel,
}: PaginationProps) => {
const odysseyDesignTokens = useOdysseyDesignTokens();

Expand All @@ -147,7 +167,12 @@ const Pagination = ({
setRowsPerPage(pageSize);
}, [pageIndex, pageSize]);

const { totalRowsLabel } = usePagination({ pageIndex, pageSize, totalRows });
const { totalRowsLabel } = usePagination({
pageIndex,
pageSize,
currentRowsCount: currentRowsCount || pageSize,
totalRows,
});

const handlePaginationChange = useCallback(() => {
const updatedPage =
Expand Down Expand Up @@ -192,16 +217,22 @@ const Pagination = ({

const setPageFromEvent = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setPage(parseInt(event.target.value));
const value = maxPageIndex
? Math.min(parseInt(event.target.value), maxPageIndex)
: parseInt(event.target.value);
setPage(value);
},
[setPage],
[setPage, maxPageIndex],
);

const setRowsPerPageFromEvent = useCallback(
(event: React.ChangeEvent<HTMLInputElement>) => {
setRowsPerPage(parseInt(event.target.value));
const value = maxPageSize
? Math.min(parseInt(event.target.value), maxPageSize)
: parseInt(event.target.value);
setRowsPerPage(value);
},
[setRowsPerPage],
[setRowsPerPage, maxPageSize],
);

const handleLoadMore = useCallback(() => {
Expand All @@ -220,12 +251,15 @@ const Pagination = ({
}, [onPaginationChange, page, rowsPerPage]);

const loadMoreIsDisabled = useMemo(() => {
return totalRows ? rowsPerPage >= totalRows : false;
}, [rowsPerPage, totalRows]);
return isMoreDisabled || (totalRows ? rowsPerPage >= totalRows : false);
}, [isMoreDisabled, rowsPerPage, totalRows]);

const nextButtonDisabled = useMemo(
() => (totalRows ? lastRow >= totalRows : false) || isDisabled,
[totalRows, lastRow, isDisabled],
() =>
isMoreDisabled ||
(totalRows ? lastRow >= totalRows : false) ||
isDisabled,
[isMoreDisabled, totalRows, lastRow, isDisabled],
);

const previousButtonDisabled = useMemo(
Expand All @@ -236,15 +270,17 @@ const Pagination = ({
const rowsPerPageInputProps = useMemo(
() => ({
"aria-label": rowsPerPageLabel,
max: maxPageSize || totalRows,
}),
[rowsPerPageLabel],
[maxPageSize, rowsPerPageLabel, totalRows],
);

const currentPageInputProps = useMemo(
() => ({
"aria-label": currentPageLabel,
max: maxPageIndex,
}),
[currentPageLabel],
[currentPageLabel, maxPageIndex],
);

return variant === "paged" ? (
Expand Down
32 changes: 14 additions & 18 deletions packages/odyssey-react-mui/src/Pagination/usePagination.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,39 +11,35 @@
*/

import { useTranslation } from "react-i18next";
import { useMemo } from "react";

type UsePaginationType = {
currentRowsCount: number;
pageIndex: number;
pageSize: number;
totalRows?: number;
};

export const usePagination = ({
currentRowsCount,
pageIndex,
pageSize,
totalRows,
}: UsePaginationType) => {
const { t } = useTranslation();

const firstRow = pageSize * (pageIndex - 1) + 1;
const lastRow = firstRow + (pageSize - 1);
if (totalRows && lastRow > totalRows) {
// If the last eligible row is greater than the number of total rows,
// show the number of total rows instead (ie, if we're showing rows
// 180-200 but there are only 190 rows, show 180-190 instead)
return useMemo(() => {
const firstRow = pageSize * (pageIndex - 1) + 1;
const lastRow = firstRow + (currentRowsCount - 1);

const totalRowsLabel = totalRows
? t("pagination.rowswithtotal", { firstRow, lastRow, totalRows })
: t("pagination.rowswithouttotal", { firstRow, lastRow });

return {
firstRow,
lastRow: totalRows,
totalRowsLabel: totalRows
? t("pagination.rowswithtotal", { firstRow, lastRow, totalRows })
: t("pagination.rowswithouttotal", { firstRow, lastRow }),
lastRow,
totalRowsLabel,
};
}
return {
firstRow,
lastRow,
totalRowsLabel: totalRows
? t("pagination.rowswithtotal", { firstRow, lastRow, totalRows })
: t("pagination.rowswithouttotal", { firstRow, lastRow }),
};
}, [currentRowsCount, pageIndex, pageSize, totalRows, t]);
};
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,11 @@ const DataStack = ({
isEmpty,
isLoading,
isNoResults,
isPaginationMoreDisabled,
isRowReorderingDisabled,
maxGridColumns,
maxPages,
maxResultsPerPage,
noResultsPlaceholder,
onChangeRowSelection,
paginationType,
Expand Down Expand Up @@ -81,7 +84,10 @@ const DataStack = ({
isEmpty={isEmpty}
isLoading={isLoading}
isNoResults={isNoResults}
isPaginationMoreDisabled={isPaginationMoreDisabled}
isRowReorderingDisabled={isRowReorderingDisabled}
maxPages={maxPages}
maxResultsPerPage={maxResultsPerPage}
noResultsPlaceholder={noResultsPlaceholder}
onChangeRowSelection={onChangeRowSelection}
paginationType={paginationType}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,10 @@ const DataTable = ({
isLoading,
isEmpty,
isNoResults,
isPaginationMoreDisabled,
isRowReorderingDisabled,
maxResultsPerPage,
maxPages,
noResultsPlaceholder,
onChangeRowSelection,
paginationType,
Expand Down Expand Up @@ -93,7 +96,10 @@ const DataTable = ({
isEmpty={isEmpty}
isLoading={isLoading}
isNoResults={isNoResults}
isPaginationMoreDisabled={isPaginationMoreDisabled}
isRowReorderingDisabled={isRowReorderingDisabled}
maxPages={maxPages}
maxResultsPerPage={maxResultsPerPage}
noResultsPlaceholder={noResultsPlaceholder}
onChangeRowSelection={onChangeRowSelection}
paginationType={paginationType}
Expand Down
Loading

0 comments on commit 84f3af3

Please sign in to comment.