From 184fa25d3e2e061385066cd4238b7f825f5dbf38 Mon Sep 17 00:00:00 2001
From: Philipinho <16838612+Philipinho@users.noreply.github.com>
Date: Mon, 20 Apr 2026 22:54:25 +0100
Subject: [PATCH] feat(base): route toolbar sort/filter changes through local
draft
---
.../features/base/components/base-table.tsx | 22 +++++++++-
.../features/base/components/base-toolbar.tsx | 42 +++++++------------
2 files changed, 37 insertions(+), 27 deletions(-)
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 (