litellm/ui/litellm-dashboard/src/components/shared/DataTable/DataTable.test-d.tsx
ryan-crabbe-berri eda81fff59 feat(ui): shared URL-state layer for tables and tabs
Add useUrlTableState (search, sort, page, page size and filter_<column>
in the query string via one nuqs useQueryStates call, with keyPrefix and
urlKeys for routes that host two tables or need legacy key names) and
useUrlTab (validated ?tab= param with a role-aware fallback). Migrate
the Virtual Keys table onto useUrlTableState with a byte-identical URL
contract and bind the Playground tab strip to ?tab=.

DataTable gains controlled columnVisibility/onColumnVisibilityChange
plus usePersistedColumnVisibility (localStorage per table id), and an
isError prop that keeps the server page clamp from rewriting a
deep-linked ?page= after a failed fetch. Virtual Keys uses both.

The expired-session redirect in handleError now keeps the query string
and hash so the return URL captured on re-login restores the filtered
view instead of the bare list.

Delete useTabRouting and tabRoutes, the pathname tab router left over
from the reverted path-per-tab attempt (#34327, reverted in #34629);
tab persistence has to be a query param on the static export.
2026-09-16 15:51:45 -07:00

92 lines
3 KiB
TypeScript

import type {
ColumnDef,
PaginationState,
RowSelectionState,
SortingState,
VisibilityState,
} from "@tanstack/react-table";
import { DataTable } from "./DataTable";
interface Row {
id: string;
name: string;
}
const data: Row[] = [];
const columns: ColumnDef<Row, unknown>[] = [];
const sorting: SortingState = [{ id: "name", desc: false }];
const pagination: PaginationState = { pageIndex: 0, pageSize: 10 };
const rowSelection: RowSelectionState = { r1: true };
const columnVisibility: VisibilityState = { name: false };
const noop = () => {};
export const uncontrolled = <DataTable data={data} columns={columns} defaultSorting={sorting} />;
export const controlled = (
<DataTable
data={data}
columns={columns}
sortingMode="server"
sorting={sorting}
onSortingChange={noop}
paginationMode="server"
pagination={pagination}
onPaginationChange={noop}
rowCount={0}
filterMode="server"
columnFilters={[]}
onColumnFiltersChange={noop}
rowSelection={rowSelection}
onRowSelectionChange={noop}
columnVisibility={columnVisibility}
onColumnVisibilityChange={noop}
/>
);
export const clientSortingWithServerPagination = (
<DataTable
data={data}
columns={columns}
defaultSorting={sorting}
paginationMode="server"
pagination={pagination}
onPaginationChange={noop}
rowCount={0}
/>
);
// @ts-expect-error sortingMode="server" requires `sorting` and `onSortingChange`
export const serverSortingWithoutState = <DataTable data={data} columns={columns} sortingMode="server" />;
// @ts-expect-error paginationMode="server" requires `pagination`, `onPaginationChange` and `rowCount`
export const serverPaginationWithoutState = <DataTable data={data} columns={columns} paginationMode="server" />;
// @ts-expect-error filterMode="server" requires `columnFilters` and `onColumnFiltersChange`
export const serverFilteringWithoutState = <DataTable data={data} columns={columns} filterMode="server" />;
export const bothSortingSources = (
// @ts-expect-error `defaultSorting` seeds uncontrolled sorting, so it cannot pair with a controlled `sorting`
<DataTable data={data} columns={columns} defaultSorting={sorting} sorting={sorting} onSortingChange={noop} />
);
export const selectionWithoutHandler = (
// @ts-expect-error a controlled `rowSelection` needs `onRowSelectionChange` or selection changes are dropped
<DataTable data={data} columns={columns} rowSelection={rowSelection} />
);
export const visibilityWithoutHandler = (
// @ts-expect-error a controlled `columnVisibility` needs `onColumnVisibilityChange` or Columns-menu toggles are dropped
<DataTable data={data} columns={columns} columnVisibility={columnVisibility} />
);
export const bothVisibilitySources = (
// @ts-expect-error `defaultColumnVisibility` seeds uncontrolled visibility, so it cannot pair with a controlled `columnVisibility`
<DataTable
data={data}
columns={columns}
defaultColumnVisibility={columnVisibility}
columnVisibility={columnVisibility}
onColumnVisibilityChange={noop}
/>
);