From 53ee6858749816423e7b68f17e4111eb06b02cff Mon Sep 17 00:00:00 2001 From: Philipinho <16838612+Philipinho@users.noreply.github.com> Date: Sat, 18 Apr 2026 19:21:17 +0100 Subject: [PATCH] refactor(base): extract buildViewConfigFromTable helper --- .../src/features/base/hooks/use-base-table.ts | 76 ++++++++++--------- 1 file changed, 40 insertions(+), 36 deletions(-) diff --git a/apps/client/src/features/base/hooks/use-base-table.ts b/apps/client/src/features/base/hooks/use-base-table.ts index 915171f5..8038c713 100644 --- a/apps/client/src/features/base/hooks/use-base-table.ts +++ b/apps/client/src/features/base/hooks/use-base-table.ts @@ -172,6 +172,44 @@ function buildColumnPinning( }; } +// Serializes the live react-table state into a persisted ViewConfig. +// Sort/filter toolbar mutations and the debounced `persistViewConfig` +// both go through this so a direct mutation (e.g. adding a sort) can't +// clobber a pending hide/reorder/resize by reading stale `activeView.config`. +export function buildViewConfigFromTable( + table: Table, + base: ViewConfig | undefined, + overrides: Partial = {}, +): ViewConfig { + const state = table.getState(); + + const sorts = state.sorting.map((s) => ({ + propertyId: s.id, + direction: (s.desc ? "desc" : "asc") as "asc" | "desc", + })); + + const propertyWidths: Record = {}; + Object.entries(state.columnSizing).forEach(([id, width]) => { + if (id !== "__row_number") propertyWidths[id] = width; + }); + + const propertyOrder = state.columnOrder.filter((id) => id !== "__row_number"); + + const hiddenPropertyIds = Object.entries(state.columnVisibility) + .filter(([id, visible]) => id !== "__row_number" && !visible) + .map(([id]) => id); + + return { + ...base, + sorts, + propertyWidths, + propertyOrder, + hiddenPropertyIds, + visiblePropertyIds: undefined, + ...overrides, + }; +} + export type UseBaseTableResult = { table: Table; persistViewConfig: () => void; @@ -265,42 +303,8 @@ export function useBaseTable( } persistTimerRef.current = setTimeout(() => { - const state = table.getState(); - - const sorts = state.sorting.map((s) => ({ - propertyId: s.id, - direction: (s.desc ? "desc" : "asc") as "asc" | "desc", - })); - - const propertyWidths: Record = {}; - Object.entries(state.columnSizing).forEach(([id, width]) => { - if (id !== "__row_number") { - propertyWidths[id] = width; - } - }); - - const propertyOrder = state.columnOrder.filter( - (id) => id !== "__row_number", - ); - - const hiddenPropertyIds = Object.entries(state.columnVisibility) - .filter(([id, visible]) => id !== "__row_number" && !visible) - .map(([id]) => id); - - const config: ViewConfig = { - ...activeView.config, - sorts, - propertyWidths, - propertyOrder, - hiddenPropertyIds, - visiblePropertyIds: undefined, - }; - - updateViewMutation.mutate({ - viewId: activeView.id, - baseId: base.id, - config, - }); + const config = buildViewConfigFromTable(table, activeView.config); + updateViewMutation.mutate({ viewId: activeView.id, baseId: base.id, config }); }, 300); }, [activeView, base, table, updateViewMutation]);