Skip to content

Commit

Permalink
feat: save table page state in local storage
Browse files Browse the repository at this point in the history
Closes #597
  • Loading branch information
murilx committed Dec 5, 2024
1 parent 60b49f6 commit 365de69
Show file tree
Hide file tree
Showing 14 changed files with 112 additions and 99 deletions.
20 changes: 8 additions & 12 deletions dashboard/src/components/BootsTable/BootsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,4 @@
import type {
Cell,
ColumnDef,
PaginationState,
Row,
SortingState,
} from '@tanstack/react-table';
import type { Cell, ColumnDef, Row, SortingState } from '@tanstack/react-table';
import {
flexRender,
getCoreRowModel,
Expand Down Expand Up @@ -52,6 +46,9 @@ import DebounceInput from '@/components/DebounceInput/DebounceInput';
import { useTestDetails } from '@/api/testDetails';
import WrapperTable from '@/pages/TreeDetails/Tabs/WrapperTable';
import { cn } from '@/lib/utils';
import { usePaginationState } from '@/hooks/usePaginationState';

import type { TableKeys } from '@/utils/constants/tables';

const columns: ColumnDef<TestByCommitHash>[] = [
{
Expand Down Expand Up @@ -101,6 +98,7 @@ const columns: ColumnDef<TestByCommitHash>[] = [
];

interface IBootsTable {
tableKey: TableKeys;
testHistory: TestHistory[];
filter: TestsTableFilter;
getRowLink: (testId: TestHistory['id']) => LinkProps;
Expand Down Expand Up @@ -182,6 +180,7 @@ const TableRowMemoized = memo(TableRowComponent);

// TODO: would be useful if the navigation happened within the table, so the parent component would only be required to pass the navigation url instead of the whole function for the update and the currentPath diffFilter (boots/tests Table)
export function BootsTable({
tableKey,
testHistory,
filter,
getRowLink,
Expand All @@ -190,10 +189,7 @@ export function BootsTable({
currentPathFilter,
}: IBootsTable): JSX.Element {
const [sorting, setSorting] = useState<SortingState>([]);
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const { pagination, paginationUpdater } = usePaginationState(tableKey);

const intl = useIntl();

Expand All @@ -220,7 +216,7 @@ export function BootsTable({
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
onPaginationChange: paginationUpdater,
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: {
Expand Down
14 changes: 8 additions & 6 deletions dashboard/src/components/BuildsTable/BuildsTable.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import type {
ColumnDef,
ExpandedState,
Header,
PaginationState,
Row,
SortingState,
} from '@tanstack/react-table';
Expand Down Expand Up @@ -45,7 +44,12 @@ import { useBuildStatusCount } from '@/api/treeDetails';
import WrapperTable from '@/pages/TreeDetails/Tabs/WrapperTable';
import { cn } from '@/lib/utils';

import { usePaginationState } from '@/hooks/usePaginationState';

import type { TableKeys } from '@/utils/constants/tables';

export interface IBuildsTable {
tableKey: TableKeys;
buildItems: AccordionItemBuilds[];
columns: ColumnDef<AccordionItemBuilds>[];
onClickShowBuild: IAccordionItems['onClickShowBuild'];
Expand Down Expand Up @@ -162,6 +166,7 @@ const AccordionBuildContentMemoized = memo(AccordionBuildContentComponent);
const TableRowMemoized = memo(TableRowComponent);

export function BuildsTable({
tableKey,
buildItems,
columns,
onClickShowBuild,
Expand All @@ -170,10 +175,7 @@ export function BuildsTable({
}: IBuildsTable): JSX.Element {
const [sorting, setSorting] = useState<SortingState>([]);
const [expanded, setExpanded] = useState<ExpandedState>({});
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const { pagination, paginationUpdater } = usePaginationState(tableKey);

const intl = useIntl();

Expand Down Expand Up @@ -203,7 +205,7 @@ export function BuildsTable({
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
onPaginationChange: paginationUpdater,
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getRowCanExpand: _ => true,
Expand Down
14 changes: 8 additions & 6 deletions dashboard/src/components/TestsTable/TestsTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
ColumnDef,
ExpandedState,
PaginationState,
SortingState,
} from '@tanstack/react-table';
import {
Expand Down Expand Up @@ -37,10 +36,15 @@ import { PaginationInfo } from '@/components/Table/PaginationInfo';

import DebounceInput from '@/components/DebounceInput/DebounceInput';

import { usePaginationState } from '@/hooks/usePaginationState';

import type { TableKeys } from '@/utils/constants/tables';

import { IndividualTestsTable } from './IndividualTestsTable';
import { defaultColumns, defaultInnerColumns } from './DefaultTestsColumns';

export interface ITestsTable {
tableKey: TableKeys;
testHistory: TestHistory[];
onClickFilter: (filter: TestsTableFilter) => void;
filter: TestsTableFilter;
Expand All @@ -53,6 +57,7 @@ export interface ITestsTable {

// TODO: would be useful if the navigation happened within the table, so the parent component would only be required to pass the navigation url instead of the whole function for the update and the currentPath diffFilter (boots/tests Table)
export function TestsTable({
tableKey,
testHistory,
onClickFilter,
filter,
Expand All @@ -64,10 +69,7 @@ export function TestsTable({
}: ITestsTable): JSX.Element {
const [sorting, setSorting] = useState<SortingState>([]);
const [expanded, setExpanded] = useState<ExpandedState>({});
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const { pagination, paginationUpdater } = usePaginationState(tableKey);

const intl = useIntl();

Expand Down Expand Up @@ -181,7 +183,7 @@ export function TestsTable({
onSortingChange: setSorting,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
onPaginationChange: paginationUpdater,
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
getRowCanExpand: _ => true,
Expand Down
29 changes: 16 additions & 13 deletions dashboard/src/components/TreeListingPage/TreeTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
ColumnDef,
ColumnFiltersState,
PaginationState,
Row,
SortingState,
} from '@tanstack/react-table';
Expand Down Expand Up @@ -34,16 +33,23 @@ import {
zPossibleTabValidator,
} from '@/types/tree/TreeDetails';

import BaseTable, { TableHead } from '../Table/BaseTable';
import { TableBody, TableCell, TableCellWithLink, TableRow } from '../ui/table';
import { usePaginationState } from '@/hooks/usePaginationState';

import { Tooltip, TooltipContent, TooltipTrigger } from '../Tooltip';
import BaseTable, { TableHead } from '@/components/Table/BaseTable';
import {
TableBody,
TableCell,
TableCellWithLink,
TableRow,
} from '@/components/ui/table';

import { Tooltip, TooltipContent, TooltipTrigger } from '@/components/Tooltip';

import { sanitizeTableValue } from '../Table/tableUtils';
import { sanitizeTableValue } from '@/components/Table/tableUtils';

import { BuildStatus, GroupedTestStatus } from '../Status/Status';
import { TableHeader } from '../Table/TableHeader';
import { PaginationInfo } from '../Table/PaginationInfo';
import { BuildStatus, GroupedTestStatus } from '@/components/Status/Status';
import { TableHeader } from '@/components/Table/TableHeader';
import { PaginationInfo } from '@/components/Table/PaginationInfo';

import { InputTime } from './InputTime';

Expand Down Expand Up @@ -187,10 +193,7 @@ interface ITreeTable {
export function TreeTable({ treeTableRows }: ITreeTable): JSX.Element {
const [sorting, setSorting] = useState<SortingState>([]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const { pagination, paginationUpdater } = usePaginationState('treeListing');

const { origin: unsafeOrigin } = useSearch({ strict: false });
const origin = zOrigin.parse(unsafeOrigin);
Expand Down Expand Up @@ -231,7 +234,7 @@ export function TreeTable({ treeTableRows }: ITreeTable): JSX.Element {
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
onPaginationChange: paginationUpdater,
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: {
Expand Down
56 changes: 0 additions & 56 deletions dashboard/src/hooks/usePagination.tsx

This file was deleted.

52 changes: 52 additions & 0 deletions dashboard/src/hooks/usePaginationState.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
import { useState } from 'react';

import type { Updater, PaginationState } from '@tanstack/react-table';

import type { TableKeys } from '@/utils/constants/tables';

import { useFeatureFlag } from './useFeatureFlag';

const DEFAULT_PAGINATION_STATE = { pageIndex: 0, pageSize: 10 } as const;

export const usePaginationState = (
selectedTable: TableKeys,
): {
pagination: PaginationState;
paginationUpdater: (updater: Updater<PaginationState>) => void;
} => {
const { showDev } = useFeatureFlag();
const storageData = window.localStorage.getItem(selectedTable);
let deserializedState = DEFAULT_PAGINATION_STATE;

if (storageData && showDev) {
try {
deserializedState = JSON.parse(storageData);
} catch {
// if stringify throws an error, we use the default state already set
}
}

const [pagination, setPagination] =
useState<PaginationState>(deserializedState);

const paginationUpdater = (updater: Updater<PaginationState>): void => {
let newState;
if (typeof updater === 'function') {
newState = updater(pagination);
} else {
newState = updater;
}
try {
const serializedState = JSON.stringify(newState);
window.localStorage.setItem(selectedTable, serializedState);
setPagination(newState);
} catch {
// if the state can't be serialized, the last state will continue
}
};

const return_value = showDev
? { pagination, paginationUpdater }
: { pagination, paginationUpdater: setPagination };
return return_value;
};
11 changes: 5 additions & 6 deletions dashboard/src/pages/Hardware/HardwareTable.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import type {
ColumnDef,
ColumnFiltersState,
PaginationState,
Row,
SortingState,
} from '@tanstack/react-table';
Expand Down Expand Up @@ -40,6 +39,8 @@ import type { HardwareTableItem } from '@/types/hardware';

import { sumStatus } from '@/utils/status';

import { usePaginationState } from '@/hooks/usePaginationState';

import { InputTime } from './InputTime';

// TODO Extract and reuse the table
Expand Down Expand Up @@ -141,10 +142,8 @@ export function HardwareTable({
}: ITreeTable): JSX.Element {
const [sorting, setSorting] = useState<SortingState>([]);
const [columnFilters, setColumnFilters] = useState<ColumnFiltersState>([]);
const [pagination, setPagination] = useState<PaginationState>({
pageIndex: 0,
pageSize: 10,
});
const { pagination, paginationUpdater } =
usePaginationState('hardwareListing');

const getLinkProps = useCallback(
(row: Row<HardwareTableItem>): LinkProps => {
Expand Down Expand Up @@ -172,7 +171,7 @@ export function HardwareTable({
onColumnFiltersChange: setColumnFilters,
getCoreRowModel: getCoreRowModel(),
getPaginationRowModel: getPaginationRowModel(),
onPaginationChange: setPagination,
onPaginationChange: paginationUpdater,
getSortedRowModel: getSortedRowModel(),
getFilteredRowModel: getFilteredRowModel(),
state: {
Expand Down
1 change: 1 addition & 0 deletions dashboard/src/pages/TreeDetails/Tabs/Boots/BootsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ const BootsTab = ({ reqFilter }: BootsTabProps): JSX.Element => {
</InnerMobileGrid>
</MobileGrid>
<BootsTable
tableKey="treeDetailsBoots"
filter={tableFilter.bootsTable}
onClickFilter={onClickFilter}
testHistory={data.bootHistory}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export function TreeDetailsBuildsTable({

return (
<BuildsTable
tableKey="treeDetailsBuilds"
onClickShowBuild={navigateToBuildDetails}
filter={tableFilter.buildsTable}
buildItems={buildItems}
Expand Down
1 change: 1 addition & 0 deletions dashboard/src/pages/TreeDetails/Tabs/Tests/TestsTab.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,6 +195,7 @@ const TestsTab = ({ reqFilter }: TestsTabProps): JSX.Element => {
</MobileGrid>

<TestsTable
tableKey="treeDetailsTests"
testHistory={data.testHistory}
onClickFilter={onClickFilter}
filter={tableFilter.testsTable}
Expand Down
Loading

0 comments on commit 365de69

Please sign in to comment.