import type { SortingState } from "@tanstack/react-table"; export type EntityTableNavigationValue = { sort: string | undefined; direction: "asc" | "desc" | undefined; page: number; }; /** Frontera presentacional; el consumidor decide almacenamiento, nombres de parámetros y navegación. */ export type EntityTableNavigation = { values: { sort: string | null; direction: string | null; page: string | null }; onChange: (value: EntityTableNavigationValue) => void; ready: boolean; }; export function tableNavigationPage(value: string | null): number { if (!(value && /^[1-9]\d*$/.test(value))) { return 0; } const page = Number(value); return Number.isSafeInteger(page) ? page - 1 : 0; } export function tableNavigationSorting( values: EntityTableNavigation["values"], columns: readonly { id: string; sortable: boolean }[], fallback: SortingState ): SortingState { if ( (values.direction === "asc" || values.direction === "desc") && columns.some((column) => column.id === values.sort && column.sortable) ) { return [{ id: values.sort ?? "", desc: values.direction === "desc" }]; } return fallback; } export function tableNavigationValue( sorting: SortingState, fallback: SortingState, pageIndex: number ): EntityTableNavigationValue { const first = sorting[0]; const initial = fallback[0]; const isDefault = first?.id === initial?.id && first?.desc === initial?.desc; return { sort: isDefault ? undefined : first?.id, direction: isDefault || !first ? undefined : first.desc ? "desc" : "asc", page: pageIndex + 1, }; }