diff --git a/apps/client/src/features/base/components/base-table.tsx b/apps/client/src/features/base/components/base-table.tsx index da3c1105..90118a03 100644 --- a/apps/client/src/features/base/components/base-table.tsx +++ b/apps/client/src/features/base/components/base-table.tsx @@ -7,6 +7,10 @@ import { arrayMove } from "@dnd-kit/sortable"; import { generateJitteredKeyBetween } from "fractional-indexing-jittered"; import { useBaseQuery } from "@/features/base/queries/base-query"; import { useBaseSocket } from "@/features/base/hooks/use-base-socket"; +import { + FilterGroup, + ViewSortConfig, +} from "@/features/base/types/base.types"; import { useBaseRowsQuery, flattenRows, @@ -179,6 +183,20 @@ export function BaseTable({ baseId }: BaseTableProps) { persistViewConfig(); }, [persistViewConfig]); + const handleDraftSortsChange = useCallback( + (sorts: ViewSortConfig[] | undefined) => { + setDraftSorts(sorts && sorts.length > 0 ? sorts : undefined); + }, + [setDraftSorts], + ); + + const handleDraftFiltersChange = useCallback( + (filter: FilterGroup | undefined) => { + setDraftFilter(filter); + }, + [setDraftFilter], + ); + const handleRowReorder = useCallback( (rowId: string, targetRowId: string, dropPosition: "above" | "below") => { const remainingRows = rows.filter((r) => r.id !== rowId); @@ -235,12 +253,14 @@ export function BaseTable({ baseId }: BaseTableProps) {
; onViewChange: (viewId: string) => void; onAddView?: () => void; onPersistViewConfig: () => void; + onDraftSortsChange: (sorts: ViewSortConfig[] | undefined) => void; + onDraftFiltersChange: (filter: FilterGroup | undefined) => void; }; export function BaseToolbar({ @@ -44,6 +48,8 @@ export function BaseToolbar({ onViewChange, onAddView, onPersistViewConfig, + onDraftSortsChange, + onDraftFiltersChange, }: BaseToolbarProps) { const { t } = useTranslation(); const [sortOpened, setSortOpened] = useState(false); @@ -113,8 +119,6 @@ export function BaseToolbar({ setFieldsOpened(panel === "fields" ? (v) => !v : false); }, []); - const updateViewMutation = useUpdateViewMutation(); - const sorts = activeView?.config?.sorts ?? []; // Stored view config uses the engine's filter tree. The popover edits // an AND-only flat list; we unwrap the top-level group's children when @@ -134,38 +138,24 @@ export function BaseToolbar({ const handleSortsChange = useCallback( (newSorts: ViewSortConfig[]) => { - if (!activeView) return; - const config = buildViewConfigFromTable(table, activeView.config, { - sorts: newSorts, - }); - updateViewMutation.mutate({ - viewId: activeView.id, - baseId: base.id, - config, - }); + // Normalize empty to undefined so the draft hook can drop the `sorts` + // axis (and remove its localStorage entry when both axes go clean). + onDraftSortsChange(newSorts.length > 0 ? newSorts : undefined); }, - [activeView, base.id, table, updateViewMutation], + [onDraftSortsChange], ); const handleFiltersChange = useCallback( (newConditions: FilterCondition[]) => { - if (!activeView) return; + // Wrap the AND-flat popover output into the engine's FilterGroup shape. + // Pass `undefined` to drop the filter axis from the draft entirely. const filter: FilterGroup | undefined = newConditions.length > 0 ? { op: "and", children: newConditions } : undefined; - // `filter: undefined` in overrides removes the filter key; the helper's - // spread-then-overrides order means `undefined` wins over any base filter. - const config = buildViewConfigFromTable(table, activeView.config, { - filter, - }); - updateViewMutation.mutate({ - viewId: activeView.id, - baseId: base.id, - config, - }); + onDraftFiltersChange(filter); }, - [activeView, base.id, table, updateViewMutation], + [onDraftFiltersChange], ); return (