/** * usePolicyTable Hook * * Initializes TanStack Table with manual pagination mode for server-side data fetching. * Integrates with URL state and localStorage preferences. * * Key Features: * - Manual pagination (data fetched via Server Actions) * - Column visibility persistence * - Column sizing with drag resize * - Row selection for CSV export * - Sorting with URL sync */ import { useEffect, useMemo, useState } from 'react'; import { getCoreRowModel, useReactTable, type ColumnDef, type SortingState, type VisibilityState, type ColumnSizingState, type RowSelectionState, type PaginationState, } from '@tanstack/react-table'; import type { PolicySettingRow, PaginationMeta } from '@/lib/types/policy-table'; interface UsePolicyTableProps { data: PolicySettingRow[]; columns: ColumnDef[]; pagination: PaginationState; onPaginationChange: (updater: PaginationState | ((old: PaginationState) => PaginationState)) => void; sorting: SortingState; onSortingChange: (updater: SortingState | ((old: SortingState) => SortingState)) => void; columnVisibility?: VisibilityState; onColumnVisibilityChange?: (updater: VisibilityState | ((old: VisibilityState) => VisibilityState)) => void; columnSizing?: ColumnSizingState; onColumnSizingChange?: (updater: ColumnSizingState | ((old: ColumnSizingState) => ColumnSizingState)) => void; meta?: PaginationMeta; enableRowSelection?: boolean; } export function usePolicyTable({ data, columns, pagination, onPaginationChange, sorting, onSortingChange, columnVisibility = {}, onColumnVisibilityChange, columnSizing = {}, onColumnSizingChange, meta, enableRowSelection = false, }: UsePolicyTableProps) { const [rowSelection, setRowSelection] = useState({}); // Reset row selection when page changes useEffect(() => { setRowSelection({}); }, [pagination.pageIndex]); // Initialize TanStack Table const table = useReactTable({ data, columns, pageCount: meta?.pageCount ?? -1, state: { pagination, sorting, columnVisibility, columnSizing, rowSelection, }, onPaginationChange, onSortingChange, onColumnVisibilityChange, onColumnSizingChange, onRowSelectionChange: setRowSelection, getCoreRowModel: getCoreRowModel(), manualPagination: true, // Server-side pagination manualSorting: true, // Server-side sorting manualFiltering: true, // Server-side filtering enableRowSelection, enableColumnResizing: true, columnResizeMode: 'onChange', }); // Get selected rows const selectedRows = useMemo(() => { return table.getSelectedRowModel().rows.map(row => row.original); }, [table, rowSelection]); // Selection helpers const selectedCount = selectedRows.length; const totalCount = meta?.totalCount ?? 0; const hasSelection = selectedCount > 0; const allRowsSelected = table.getIsAllPageRowsSelected(); return { table, selectedRows, selectedCount, totalCount, hasSelection, allRowsSelected, }; }