metis-desk/packages/rdx-ui/src/lib/entity-table-navigation.ts

55 lines
1.6 KiB
TypeScript

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,
};
}