useTableSort.ts95 lines · main
| 1 | // @ts-nocheck |
| 2 | import { useCallback, useMemo } from 'react' |
| 3 | |
| 4 | import { formatSortURLParams, sortsToUrlParams } from '@/components/grid/BrivenGrid.utils' |
| 5 | import type { Sort } from '@/components/grid/types' |
| 6 | import { useTableEditorFiltersSort } from '@/hooks/misc/useTableEditorFiltersSort' |
| 7 | import { useTableEditorTableStateSnapshot } from '@/state/table-editor-table' |
| 8 | |
| 9 | /** |
| 10 | * Hook for managing table sort URL parameters and saving. |
| 11 | * Uses snapshot ONLY to get table name for formatting/mapping. |
| 12 | * Does NOT format initial sorts (needs table name externally). |
| 13 | * Does NOT interact with snapshot directly. |
| 14 | */ |
| 15 | export function useTableSort() { |
| 16 | const { sorts: urlSorts, setParams } = useTableEditorFiltersSort() |
| 17 | const snap = useTableEditorTableStateSnapshot() |
| 18 | |
| 19 | const tableName = useMemo(() => snap.table?.name || '', [snap]) |
| 20 | |
| 21 | const sorts = useMemo(() => { |
| 22 | return formatSortURLParams(tableName, urlSorts) |
| 23 | }, [tableName, urlSorts]) |
| 24 | |
| 25 | const onApplySorts = useCallback( |
| 26 | (appliedSorts: Sort[]) => { |
| 27 | if (!tableName) { |
| 28 | return console.warn( |
| 29 | '[useTableSort] Table name missing in callback, cannot apply sort correctly.' |
| 30 | ) |
| 31 | } |
| 32 | |
| 33 | const sortsWithTable = appliedSorts.map((sort) => ({ ...sort, table: tableName })) |
| 34 | const newUrlSorts = sortsToUrlParams(sortsWithTable) |
| 35 | |
| 36 | setParams((prevParams) => ({ ...prevParams, sort: newUrlSorts })) |
| 37 | }, |
| 38 | [snap, setParams] |
| 39 | ) |
| 40 | |
| 41 | /** |
| 42 | * Adds a new sort for a column or updates the direction of an existing one. |
| 43 | * New sorts are added to the beginning of the array (highest precedence). |
| 44 | * If the column already exists, its `ascending` direction is updated. |
| 45 | * Calls `onApplySorts` to update URL parameters and trigger side effects. |
| 46 | * |
| 47 | * @param columnKey The key/name of the column to sort. |
| 48 | * @param ascending The sort direction (true for ascending, false for descending). |
| 49 | */ |
| 50 | const addOrUpdateSort = useCallback( |
| 51 | (columnKey: string, ascending: boolean) => { |
| 52 | if (!tableName || !columnKey) return |
| 53 | |
| 54 | // Use the derived 'sorts' state from the hook |
| 55 | const existingSortIndex = sorts.findIndex((s) => s.column === columnKey) |
| 56 | let newSorts = [...sorts] // Create a mutable copy |
| 57 | |
| 58 | if (existingSortIndex !== -1) { |
| 59 | // Column already exists in sorts: Update the existing sort (toggle handled by removeSort) |
| 60 | newSorts[existingSortIndex] = { ...newSorts[existingSortIndex], ascending: ascending } |
| 61 | } else { |
| 62 | // Column doesn't exist in sorts: Add it to the beginning |
| 63 | newSorts.unshift({ table: tableName, column: columnKey, ascending: ascending }) |
| 64 | } |
| 65 | |
| 66 | onApplySorts(newSorts) |
| 67 | }, |
| 68 | [tableName, sorts, onApplySorts] // Depend on derived sorts and callback |
| 69 | ) |
| 70 | |
| 71 | /** |
| 72 | * Removes a sort criterion for a specific column. |
| 73 | * Calls `onApplySorts` with the filtered array to update URL parameters and trigger side effects. |
| 74 | * |
| 75 | * @param columnKey The key/name of the column to remove from sorting. |
| 76 | */ |
| 77 | const removeSort = useCallback( |
| 78 | (columnKey: string) => { |
| 79 | if (!tableName || !columnKey) return |
| 80 | |
| 81 | // Use the derived 'sorts' state from the hook |
| 82 | const newSorts = sorts.filter((s) => s.column !== columnKey) |
| 83 | onApplySorts(newSorts) |
| 84 | }, |
| 85 | [tableName, sorts, onApplySorts] // Depend on derived sorts and callback |
| 86 | ) |
| 87 | |
| 88 | return { |
| 89 | sorts, |
| 90 | urlSorts, |
| 91 | onApplySorts, |
| 92 | addOrUpdateSort, |
| 93 | removeSort, |
| 94 | } |
| 95 | } |