mirror of
https://github.com/supabase/supabase.git
synced 2026-10-05 17:35:10 +03:00
When a user has sorted by some column in the Table Editor and the column is deleted, the sort data is wrong so it causes issues. In the general view in the Table Editor, the error is handled by removing the sort key when a specific error is detected but it can still happen in ForeignRowSelector. To test: 1. Have 2 tables with references between them. 2. In the `sessionStorage`, under the `supabase_grid-<ref>` key, update the sort key to a non-existant column for a table. 3. Try to open the `ForeignRowSelector` for that table by clicking on a cell in the referencing column. <!-- This is an auto-generated comment: release notes by coderabbit.ai --> ## Summary by CodeRabbit * **Bug Fixes** * Sorting now validates referenced columns and ignores invalid sort entries. * Local sort restoration and UI sort application now derive sorts from the original table context for more consistent behavior across editors and popovers. * Prefetch logic uses the resolved table context when falling back to saved sorts. * **Tests** * Added cases for malformed and out-of-scope sort parameters to prevent regressions. <!-- end of auto-generated comment: release notes by coderabbit.ai -->
90 lines
3.2 KiB
TypeScript
90 lines
3.2 KiB
TypeScript
import { useCallback, useMemo } from 'react'
|
|
|
|
import { formatSortURLParams, sortsToUrlParams } from '@/components/grid/SupabaseGrid.utils'
|
|
import type { Sort } from '@/components/grid/types'
|
|
import { useTableEditorFiltersSort } from '@/hooks/misc/useTableEditorFiltersSort'
|
|
import { useTableEditorTableStateSnapshot } from '@/state/table-editor-table'
|
|
|
|
/**
|
|
* Hook for managing table sort URL parameters and saving.
|
|
* Uses snapshot ONLY to get table name for formatting/mapping.
|
|
* Does NOT format initial sorts (needs table name externally).
|
|
* Does NOT interact with snapshot directly.
|
|
*/
|
|
export function useTableSort() {
|
|
const { sorts: urlSorts, setParams } = useTableEditorFiltersSort()
|
|
const snap = useTableEditorTableStateSnapshot()
|
|
|
|
const tableName = useMemo(() => snap.table?.name || '', [snap])
|
|
|
|
const sorts = useMemo(() => {
|
|
if (!snap.originalTable) return []
|
|
return formatSortURLParams(snap.originalTable, urlSorts)
|
|
}, [snap.originalTable, urlSorts])
|
|
|
|
const onApplySorts = useCallback(
|
|
(appliedSorts: Sort[]) => {
|
|
const sortsWithTable = appliedSorts.map((sort) => ({ ...sort }))
|
|
const newUrlSorts = sortsToUrlParams(sortsWithTable)
|
|
|
|
setParams((prevParams) => ({ ...prevParams, sort: newUrlSorts }))
|
|
},
|
|
[setParams]
|
|
)
|
|
|
|
/**
|
|
* Adds a new sort for a column or updates the direction of an existing one.
|
|
* New sorts are added to the beginning of the array (highest precedence).
|
|
* If the column already exists, its `ascending` direction is updated.
|
|
* Calls `onApplySorts` to update URL parameters and trigger side effects.
|
|
*
|
|
* @param columnKey The key/name of the column to sort.
|
|
* @param ascending The sort direction (true for ascending, false for descending).
|
|
*/
|
|
const addOrUpdateSort = useCallback(
|
|
(columnKey: string, ascending: boolean) => {
|
|
if (!tableName || !columnKey) return
|
|
|
|
// Use the derived 'sorts' state from the hook
|
|
const existingSortIndex = sorts.findIndex((s) => s.column === columnKey)
|
|
let newSorts = [...sorts] // Create a mutable copy
|
|
|
|
if (existingSortIndex !== -1) {
|
|
// Column already exists in sorts: Update the existing sort (toggle handled by removeSort)
|
|
newSorts[existingSortIndex] = { ...newSorts[existingSortIndex], ascending: ascending }
|
|
} else {
|
|
// Column doesn't exist in sorts: Add it to the beginning
|
|
newSorts.unshift({ table: tableName, column: columnKey, ascending: ascending })
|
|
}
|
|
|
|
onApplySorts(newSorts)
|
|
},
|
|
[tableName, sorts, onApplySorts] // Depend on derived sorts and callback
|
|
)
|
|
|
|
/**
|
|
* Removes a sort criterion for a specific column.
|
|
* Calls `onApplySorts` with the filtered array to update URL parameters and trigger side effects.
|
|
*
|
|
* @param columnKey The key/name of the column to remove from sorting.
|
|
*/
|
|
const removeSort = useCallback(
|
|
(columnKey: string) => {
|
|
if (!tableName || !columnKey) return
|
|
|
|
// Use the derived 'sorts' state from the hook
|
|
const newSorts = sorts.filter((s) => s.column !== columnKey)
|
|
onApplySorts(newSorts)
|
|
},
|
|
[tableName, sorts, onApplySorts] // Depend on derived sorts and callback
|
|
)
|
|
|
|
return {
|
|
sorts,
|
|
urlSorts,
|
|
onApplySorts,
|
|
addOrUpdateSort,
|
|
removeSort,
|
|
}
|
|
}
|