fix(ui/datatables): sync page count with filtering [EE-5890] (#10009)

pull/10108/head
Chaim Lev-Ari 1 year ago committed by GitHub
parent f24555c6c9
commit 69f3670ce5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -8,29 +8,22 @@ interface Props {
boundaryLinks?: boolean;
currentPage: number;
directionLinks?: boolean;
itemsPerPage: number;
onPageChange(page: number): void;
totalCount: number;
pageCount: number;
maxSize: number;
isInputVisible?: boolean;
}
export function PageSelector({
currentPage,
totalCount,
itemsPerPage,
pageCount,
onPageChange,
maxSize = 5,
directionLinks = true,
boundaryLinks = false,
isInputVisible = false,
}: Props) {
const pages = generatePagesArray(
currentPage,
totalCount,
itemsPerPage,
maxSize
);
const pages = generatePagesArray(currentPage, pageCount, maxSize);
const last = pages[pages.length - 1];
if (pages.length <= 1) {
@ -42,7 +35,7 @@ export function PageSelector({
{isInputVisible && (
<PageInput
onChange={(page) => onPageChange(page)}
totalPages={Math.ceil(totalCount / itemsPerPage)}
totalPages={pageCount}
/>
)}
<ul className="pagination">

@ -9,7 +9,7 @@ interface Props {
page: number;
pageLimit: number;
showAll?: boolean;
totalCount: number;
pageCount: number;
isPageInputVisible?: boolean;
className?: string;
}
@ -20,7 +20,7 @@ export function PaginationControls({
onPageLimitChange,
showAll,
onPageChange,
totalCount,
pageCount,
isPageInputVisible,
className,
}: Props) {
@ -38,8 +38,7 @@ export function PaginationControls({
maxSize={5}
onPageChange={onPageChange}
currentPage={page}
itemsPerPage={pageLimit}
totalCount={totalCount}
pageCount={pageCount}
isInputVisible={isPageInputVisible}
/>
)}

@ -12,12 +12,10 @@ export /**
*/
function generatePagesArray(
currentPage: number,
collectionLength: number,
rowsPerPage: number,
totalPages: number,
paginationRange: number
): (number | '...')[] {
const pages: (number | '...')[] = [];
const totalPages = Math.ceil(collectionLength / rowsPerPage);
const halfWay = Math.ceil(paginationRange / 2);
let position;

@ -34,6 +34,20 @@ import { createSelectColumn } from './select-column';
import { TableRow } from './TableRow';
import { type TableState as GlobalTableState } from './useTableState';
export type PaginationProps =
| {
isServerSidePagination?: false;
totalCount?: never;
page?: never;
onPageChange?: never;
}
| {
isServerSidePagination: true;
totalCount: number;
page: number;
onPageChange(page: number): void;
};
export interface Props<
D extends Record<string, unknown>,
TMeta extends TableMeta<D> = TableMeta<D>
@ -50,13 +64,8 @@ export interface Props<
titleIcon?: IconProps['icon'];
initialTableState?: Partial<TableState>;
isLoading?: boolean;
totalCount?: number;
description?: ReactNode;
pageCount?: number;
highlightedItemId?: string;
page?: number;
onPageChange?(page: number): void;
settingsManager: GlobalTableState<BasicTableSettings>;
renderRow?(row: Row<D>, highlightedItemId?: string): ReactNode;
getRowCanExpand?(row: Row<D>): boolean;
@ -80,11 +89,7 @@ export function Datatable<
emptyContentLabel,
initialTableState = {},
isLoading,
totalCount = dataset.length,
description,
pageCount,
page,
onPageChange = () => null,
settingsManager: settings,
renderRow = defaultRenderRow,
highlightedItemId,
@ -92,8 +97,16 @@ export function Datatable<
getRowCanExpand,
'data-cy': dataCy,
meta,
}: Props<D, TMeta>) {
const isServerSidePagination = typeof pageCount !== 'undefined';
onPageChange = () => {},
page,
totalCount = dataset.length,
isServerSidePagination = false,
}: Props<D, TMeta> & PaginationProps) {
const pageCount = useMemo(
() => Math.ceil(totalCount / settings.pageSize),
[settings.pageSize, totalCount]
);
const enableRowSelection = getIsSelectionEnabled(
disableSelect,
isRowSelectable
@ -120,6 +133,7 @@ export function Datatable<
defaultColumn: {
enableColumnFilter: false,
enableHiding: true,
sortingFn: 'alphanumeric',
},
enableRowSelection,
autoResetExpanded: false,
@ -127,7 +141,6 @@ export function Datatable<
getRowId,
getCoreRowModel: getCoreRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getSortedRowModel: getSortedRowModel(),
getPaginationRowModel: getPaginationRowModel(),
getFacetedRowModel: getFacetedRowModel(),
getFacetedUniqueValues: getFacetedUniqueValues(),
@ -135,7 +148,11 @@ export function Datatable<
getExpandedRowModel: getExpandedRowModel(),
getRowCanExpand,
getColumnCanGlobalFilter,
...(isServerSidePagination ? { manualPagination: true, pageCount } : {}),
...(isServerSidePagination
? { manualPagination: true, pageCount }
: {
getSortedRowModel: getSortedRowModel(),
}),
meta,
});
@ -178,7 +195,7 @@ export function Datatable<
onPageSizeChange={handlePageSizeChange}
page={typeof page === 'number' ? page : tableState.pagination.pageIndex}
pageSize={tableState.pagination.pageSize}
totalCount={totalCount}
pageCount={tableInstance.getPageCount()}
totalSelected={selectedItems.length}
/>
</Table.Container>

@ -8,7 +8,7 @@ interface Props {
pageSize: number;
page: number;
onPageChange(page: number): void;
totalCount: number;
pageCount: number;
onPageSizeChange(pageSize: number): void;
}
@ -17,7 +17,7 @@ export function DatatableFooter({
pageSize,
page,
onPageChange,
totalCount,
pageCount,
onPageSizeChange,
}: Props) {
return (
@ -28,7 +28,7 @@ export function DatatableFooter({
pageLimit={pageSize}
page={page + 1}
onPageChange={(page) => onPageChange(page - 1)}
totalCount={totalCount}
pageCount={pageCount}
onPageLimitChange={onPageSizeChange}
/>
</Table.Footer>

@ -2,7 +2,11 @@ import { Row } from '@tanstack/react-table';
import { ReactNode } from 'react';
import { ExpandableDatatableTableRow } from './ExpandableDatatableRow';
import { Datatable, Props as DatatableProps } from './Datatable';
import {
Datatable,
Props as DatatableProps,
PaginationProps,
} from './Datatable';
interface Props<D extends Record<string, unknown>>
extends Omit<DatatableProps<D>, 'renderRow' | 'expandable'> {
@ -15,7 +19,7 @@ export function ExpandableDatatable<D extends Record<string, unknown>>({
getRowCanExpand = () => true,
expandOnRowClick,
...props
}: Props<D>) {
}: Props<D> & PaginationProps) {
return (
<Datatable<D>
// eslint-disable-next-line react/jsx-props-no-spreading

@ -17,7 +17,6 @@ export function buildNameColumn<T extends Record<string, unknown>>(
cell,
enableSorting: true,
enableHiding: false,
sortingFn: 'text',
};
function createCell<T extends Record<string, unknown>>() {

@ -51,10 +51,10 @@ export function EdgeGroupAssociationTable({
onClickRow: (env: Environment) => void;
} & AutomationTestingProps) {
const tableState = useTableStateWithoutStorage('Name');
const [page, setPage] = useState(1);
const [page, setPage] = useState(0);
const environmentsQuery = useEnvironmentList({
pageLimit: tableState.pageSize,
page,
page: page + 1,
search: tableState.search,
sort: tableState.sortBy.id as 'Group' | 'Name',
order: tableState.sortBy.desc ? 'desc' : 'asc',
@ -87,8 +87,10 @@ export function EdgeGroupAssociationTable({
columns={columns}
settingsManager={tableState}
dataset={environments}
isServerSidePagination
page={page}
onPageChange={setPage}
pageCount={Math.ceil(totalCount / tableState.pageSize)}
totalCount={totalCount}
renderRow={(row) => (
<TableRow<DecoratedEnvironment>
cells={row.getVisibleCells()}
@ -98,7 +100,6 @@ export function EdgeGroupAssociationTable({
emptyContentLabel={emptyContentLabel}
data-cy={dataCy}
disableSelect
totalCount={totalCount}
/>
);
}

@ -24,8 +24,6 @@ export function Datatable() {
search: tableState.search,
});
const pageCount = Math.ceil(totalCount / tableState.pageSize);
return (
<GenericDatatable
settingsManager={tableState}
@ -37,10 +35,10 @@ export function Datatable() {
<TableActions selectedRows={selectedRows} />
)}
isLoading={isLoading}
totalCount={totalCount}
pageCount={pageCount}
isServerSidePagination
page={page}
onPageChange={setPage}
totalCount={totalCount}
description={<Filter />}
/>
);

@ -40,7 +40,7 @@ export function EnvironmentsDatatable() {
(value) => (value ? parseInt(value, 10) : undefined)
);
const tableState = useTableStateWithoutStorage('name');
const endpointsQuery = useEnvironmentList({
const environmentsQuery = useEnvironmentList({
pageLimit: tableState.pageSize,
page: page + 1,
search: tableState.search,
@ -56,7 +56,7 @@ export function EnvironmentsDatatable() {
const gitConfigCommitHash = edgeStackQuery.data?.GitConfig?.ConfigHash || '';
const environments: Array<EdgeStackEnvironment> = useMemo(
() =>
endpointsQuery.environments.map(
environmentsQuery.environments.map(
(env) =>
({
...env,
@ -72,7 +72,7 @@ export function EnvironmentsDatatable() {
[
currentFileVersion,
edgeStackQuery.data?.Status,
endpointsQuery.environments,
environmentsQuery.environments,
gitConfigCommitHash,
gitConfigURL,
]
@ -81,13 +81,15 @@ export function EnvironmentsDatatable() {
return (
<Datatable
columns={columns}
isLoading={endpointsQuery.isLoading}
isLoading={environmentsQuery.isLoading}
dataset={environments}
settingsManager={tableState}
title="Environments Status"
titleIcon={HardDrive}
isServerSidePagination
page={page}
onPageChange={setPage}
totalCount={endpointsQuery.totalCount}
totalCount={environmentsQuery.totalCount}
emptyContentLabel="No environment available."
disableSelect
description={

@ -28,7 +28,6 @@ export function EventsDatatable({ data, isLoading }: EventsDatatableProps) {
dataset={data}
titleIcon={History}
title="Events"
totalCount={data.length}
getRowId={(row) => `${row.Date}-${row.Message}-${row.Type}`}
disableSelect
/>

@ -83,7 +83,7 @@ export function AssociateAMTDialog({
onPageChange={setPage}
pageLimit={pageLimit}
onPageLimitChange={setPageLimit}
totalCount={totalCount}
pageCount={Math.ceil(totalCount / pageLimit)}
/>
</div>
</div>

@ -239,7 +239,7 @@ export function EnvironmentList({ onClickBrowse, onRefresh }: Props) {
pageLimit={pageLimit}
page={page}
onPageChange={setPage}
totalCount={totalCount}
pageCount={Math.ceil(totalCount / pageLimit)}
onPageLimitChange={setPageLimit}
/>
</TableFooter>

@ -111,7 +111,7 @@ export function KubeconfigPrompt({
onPageChange={setPage}
pageLimit={pageLimit}
onPageLimitChange={setPageLimit}
totalCount={totalCount}
pageCount={Math.ceil(totalCount / pageLimit)}
/>
</div>
</div>

@ -12,6 +12,7 @@ import { useTableState } from '@@/datatables/useTableState';
import { isBE } from '../../feature-flags/feature-flags.service';
import { isSortType } from '../queries/useEnvironmentList';
import { EnvironmentStatus } from '../types';
import { columns } from './columns';
import { EnvironmentListItem } from './types';
@ -60,10 +61,14 @@ export function EnvironmentsDatatable({
dataset={environmentsWithGroups}
columns={columns}
settingsManager={tableState}
pageCount={Math.ceil(totalCount / tableState.pageSize)}
isServerSidePagination
page={page}
onPageChange={setPage}
isLoading={isLoading}
totalCount={totalCount}
isLoading={isLoading}
isRowSelectable={(row) =>
row.original.Status !== EnvironmentStatus.Provisioning
}
renderTableActions={(selectedRows) => (
<div className="flex items-center gap-2">
<Button

@ -28,6 +28,7 @@ export function AssociatedEnvironmentsSelector({
emptyContentLabel="No environment available"
query={{
groupIds: [1],
excludeIds: value,
}}
onClickRow={(env) => {
if (!value.includes(env.Id)) {

@ -33,10 +33,10 @@ export function GroupAssociationTable({
onClickRow?: (env: Environment) => void;
} & AutomationTestingProps) {
const tableState = useTableStateWithoutStorage('Name');
const [page, setPage] = useState(1);
const [page, setPage] = useState(0);
const environmentsQuery = useEnvironmentList({
pageLimit: tableState.pageSize,
page,
page: page + 1,
search: tableState.search,
sort: tableState.sortBy.id as 'Name',
order: tableState.sortBy.desc ? 'desc' : 'asc',
@ -51,8 +51,10 @@ export function GroupAssociationTable({
columns={columns}
settingsManager={tableState}
dataset={environments}
isServerSidePagination
page={page}
onPageChange={setPage}
pageCount={Math.ceil(environmentsQuery.totalCount / tableState.pageSize)}
totalCount={environmentsQuery.totalCount}
renderRow={(row) => (
<TableRow<Environment>
cells={row.getVisibleCells()}
@ -62,7 +64,6 @@ export function GroupAssociationTable({
emptyContentLabel={emptyContentLabel}
data-cy={dataCy}
disableSelect
totalCount={environmentsQuery.totalCount}
/>
);
}

@ -53,7 +53,6 @@ export function ListView() {
titleIcon={Clock}
emptyContentLabel="No schedules found"
isLoading={listQuery.isLoading}
totalCount={listQuery.data.length}
renderTableActions={(selectedRows) => (
<TableActions selectedRows={selectedRows} />
)}

@ -48,7 +48,6 @@ export function NotificationsView() {
dataset={userNotifications}
settingsManager={tableState}
emptyContentLabel="No notifications found"
totalCount={userNotifications.length}
renderTableActions={(selectedRows) => (
<TableActions selectedRows={selectedRows} />
)}

Loading…
Cancel
Save