useTableSort.ts95 lines · main
1// @ts-nocheck
2import { useCallback, useMemo } from 'react'
3
4import { formatSortURLParams, sortsToUrlParams } from '@/components/grid/BrivenGrid.utils'
5import type { Sort } from '@/components/grid/types'
6import { useTableEditorFiltersSort } from '@/hooks/misc/useTableEditorFiltersSort'
7import { 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 */
15export 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}