Skip to content

Commit

Permalink
refactor: table state management in withTableState (#5531)
Browse files Browse the repository at this point in the history
  • Loading branch information
Tymek authored Dec 5, 2023
1 parent 607e01b commit b5122a7
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 82 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,7 @@ import {
useTheme,
} from '@mui/material';
import { Link as RouterLink } from 'react-router-dom';
import {
useReactTable,
getCoreRowModel,
createColumnHelper,
} from '@tanstack/react-table';
import { useReactTable, createColumnHelper } from '@tanstack/react-table';
import { PaginatedTable, TablePlaceholder } from 'component/common/Table';
import { SearchHighlightProvider } from 'component/common/Table/SearchHighlightContext/SearchHighlightContext';
import { DateCell } from 'component/common/Table/cells/DateCell/DateCell';
Expand Down Expand Up @@ -48,6 +44,7 @@ import {
import mapValues from 'lodash.mapvalues';
import { NumberParam, StringParam, withDefault } from 'use-query-params';
import { BooleansStringParam } from 'utils/serializeQueryParams';
import { withTableState } from 'utils/withTableState';
import { usePersistentTableState } from 'hooks/usePersistentTableState';

export const featuresPlaceholder = Array(15).fill({
Expand Down Expand Up @@ -202,74 +199,12 @@ export const FeatureToggleListTable: VFC = () => {
[initialLoad, features, loading],
);

const table = useReactTable({
columns,
data,
enableSorting: true,
enableMultiSort: false,
manualPagination: true,
manualSorting: true,
enableSortingRemoval: false,
getCoreRowModel: getCoreRowModel(),
enableHiding: true,
state: {
sorting: [
{
id: tableState.sortBy || 'createdAt',
desc: tableState.sortOrder === 'desc',
},
],
pagination: {
pageIndex: tableState.offset
? tableState.offset / tableState.limit
: 0,
pageSize: tableState.limit,
},
},
onSortingChange: (newSortBy) => {
if (typeof newSortBy === 'function') {
const computedSortBy = newSortBy([
{
id: tableState.sortBy || 'createdAt',
desc: tableState.sortOrder === 'desc',
},
])[0];
setTableState({
sortBy: computedSortBy?.id,
sortOrder: computedSortBy?.desc ? 'desc' : 'asc',
});
} else {
const sortBy = newSortBy[0];
setTableState({
sortBy: sortBy?.id,
sortOrder: sortBy?.desc ? 'desc' : 'asc',
});
}
},
onPaginationChange: (newPagination) => {
if (typeof newPagination === 'function') {
const computedPagination = newPagination({
pageSize: tableState.limit,
pageIndex: tableState.offset
? Math.floor(tableState.offset / tableState.limit)
: 0,
});
setTableState({
limit: computedPagination?.pageSize,
offset: computedPagination?.pageIndex
? computedPagination?.pageIndex *
computedPagination?.pageSize
: 0,
});
} else {
const { pageSize, pageIndex } = newPagination;
setTableState({
limit: pageSize,
offset: pageIndex ? pageIndex * pageSize : 0,
});
}
},
});
const table = useReactTable(
withTableState(tableState, setTableState, {
columns,
data,
}),
);

useEffect(() => {
if (isSmallScreen) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@ import {
useSortBy,
useTable,
} from 'react-table';
import type { FeatureSchema, SearchFeaturesSchema } from 'openapi';
import { ConditionallyRender } from 'component/common/ConditionallyRender/ConditionallyRender';
import { PageHeader } from 'component/common/PageHeader/PageHeader';
import { PageContent } from 'component/common/PageContent/PageContent';
Expand Down
9 changes: 1 addition & 8 deletions frontend/src/component/project/Project/ProjectOverview.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,14 +10,7 @@ import { useRequiredPathParam } from 'hooks/useRequiredPathParam';
import { useLastViewedProject } from 'hooks/useLastViewedProject';
import { ProjectStats } from './ProjectStats/ProjectStats';
import { useUiFlag } from 'hooks/useUiFlag';
import {
DEFAULT_PAGE_LIMIT,
useFeatureSearch,
} from 'hooks/api/getters/useFeatureSearch/useFeatureSearch';
import {
// ProjectTableState,
PaginatedProjectFeatureToggles,
} from './ProjectFeatureToggles/PaginatedProjectFeatureToggles';
import { PaginatedProjectFeatureToggles } from './ProjectFeatureToggles/PaginatedProjectFeatureToggles';

import useProjectOverview from 'hooks/api/getters/useProjectOverview/useProjectOverview';
import { FeatureTypeCount } from '../../../interfaces/project';
Expand Down
128 changes: 128 additions & 0 deletions frontend/src/utils/withTableState.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
import {
type OnChangeFn,
type SortingState,
type PaginationState,
type TableOptions,
getCoreRowModel,
} from '@tanstack/react-table';

const createOnSortingChange =
(
tableState: {
sortBy: string;
sortOrder: string;
},
setTableState: (newState: {
sortBy?: string;
sortOrder?: string;
}) => void,
): OnChangeFn<SortingState> =>
(newSortBy) => {
if (typeof newSortBy === 'function') {
const computedSortBy = newSortBy([
{
id: tableState.sortBy,
desc: tableState.sortOrder === 'desc',
},
])[0];
setTableState({
sortBy: computedSortBy?.id,
sortOrder: computedSortBy?.desc ? 'desc' : 'asc',
});
} else {
const sortBy = newSortBy[0];
setTableState({
sortBy: sortBy?.id,
sortOrder: sortBy?.desc ? 'desc' : 'asc',
});
}
};

const createOnPaginationChange =
(
tableState: {
limit: number;
offset: number;
},
setTableState: (newState: {
limit?: number;
offset?: number;
}) => void,
): OnChangeFn<PaginationState> =>
(newPagination) => {
if (typeof newPagination === 'function') {
const computedPagination = newPagination({
pageSize: tableState.limit,
pageIndex: tableState.offset
? Math.floor(tableState.offset / tableState.limit)
: 0,
});
setTableState({
limit: computedPagination?.pageSize,
offset: computedPagination?.pageIndex
? computedPagination?.pageIndex *
computedPagination?.pageSize
: 0,
});
} else {
const { pageSize, pageIndex } = newPagination;
setTableState({
limit: pageSize,
offset: pageIndex ? pageIndex * pageSize : 0,
});
}
};

const createSortingState = (tableState: {
sortBy: string;
sortOrder: string;
}) => ({
sorting: [
{
id: tableState.sortBy,
desc: tableState.sortOrder === 'desc',
},
],
});

const createPaginationState = (tableState: {
limit: number;
offset: number;
}) => ({
pagination: {
pageIndex: tableState.offset ? tableState.offset / tableState.limit : 0,
pageSize: tableState.limit,
},
});

export const withTableState = <T extends Object>(
tableState: {
sortBy: string;
sortOrder: string;
limit: number;
offset: number;
},
setTableState: (newState: {
sortBy?: string;
sortOrder?: string;
limit?: number;
offset?: number;
}) => void,
options: Omit<TableOptions<T>, 'getCoreRowModel'>,
) => ({
getCoreRowModel: getCoreRowModel(),
enableSorting: true,
enableMultiSort: false,
manualPagination: true,
manualSorting: true,
enableSortingRemoval: false,
enableHiding: true,
state: {
...createSortingState(tableState),
...createPaginationState(tableState),
...(options.state || {}),
},
onPaginationChange: createOnPaginationChange(tableState, setTableState),
onSortingChange: createOnSortingChange(tableState, setTableState),
...options,
});

0 comments on commit b5122a7

Please sign in to comment.