Skip to content

Commit 03a4e49

Browse files
committed
fix(tables): close final view autosave races
1 parent daefc28 commit 03a4e49

1 file changed

Lines changed: 22 additions & 20 deletions

File tree

  • apps/sim/app/workspace/[workspaceId]/tables/[tableId]

apps/sim/app/workspace/[workspaceId]/tables/[tableId]/table.tsx

Lines changed: 22 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -635,6 +635,13 @@ export function Table({
635635
return
636636
}
637637

638+
/** Creating a view updates the query cache before nuqs commits its URL id.
639+
* Keep the blank view already applied in the success handler during that
640+
* gap instead of briefly reapplying the previously selected view. */
641+
if (pendingCreatedViewIdRef.current && activeViewId !== pendingCreatedViewIdRef.current) {
642+
return
643+
}
644+
638645
// The id resolved, so any create race for it is over.
639646
if (selectedView && pendingCreatedViewIdRef.current === selectedView.id) {
640647
pendingCreatedViewIdRef.current = null
@@ -673,11 +680,6 @@ export function Table({
673680
if (activeView && (activeViewId === null || activeViewId === ALL_VIEW_PARAM)) {
674681
setTableParams({ view: activeView.id })
675682
}
676-
// Navigating away ends any create race — without this a reconcile on the
677-
// destination could fall back to the still-pending created id.
678-
if (pendingCreatedViewIdRef.current && pendingCreatedViewIdRef.current !== nextViewId) {
679-
pendingCreatedViewIdRef.current = null
680-
}
681683
const keep = preserved?.viewId === nextViewId ? preserved.keep : undefined
682684
applyViewConfig(activeViewConfig, keep)
683685
if (activeView) flushPendingViewConfig(activeView.id)
@@ -716,19 +718,6 @@ export function Table({
716718
[columns.length, hiddenColumns, liveColumnIds]
717719
)
718720

719-
/**
720-
* Drops a sort whose column was deleted by clearing the URL, rather than masking
721-
* it in a derived value: `queryOptions` feeds the query that produces `columns`,
722-
* so a pruned sort can't flow back into it without a cycle. Clearing keeps one
723-
* source of truth, so the rows query and the active-view autosave cannot
724-
* disagree about whether a sort is active.
725-
*/
726-
useEffect(() => {
727-
if (!sortColumn || columns.length === 0) return
728-
if (liveColumnIds.has(sortColumn)) return
729-
setTableParams({ sort: null, dir: null })
730-
}, [sortColumn, columns.length, liveColumnIds, setTableParams])
731-
732721
/** Rename targets a live view rather than a snapshot, so a concurrent rename or
733722
* delete can't leave the modal editing stale data. */
734723
const renamingView =
@@ -759,7 +748,7 @@ export function Table({
759748
*/
760749
const persistActiveViewConfig = useCallback(
761750
(configPatch: TableViewConfig) => {
762-
if (!userPermissions.canEdit) return
751+
if (!viewsEnabled || !userPermissions.canEdit) return
763752
const viewId = activeView?.id ?? pendingCreatedViewIdRef.current
764753
if (!viewId) {
765754
if (!ownerResolvedRef.current) {
@@ -779,9 +768,22 @@ export function Table({
779768
}
780769
)
781770
},
782-
[activeView?.id, userPermissions.canEdit, releasePersistedViewState]
771+
[viewsEnabled, activeView?.id, userPermissions.canEdit, releasePersistedViewState]
783772
)
784773

774+
/**
775+
* Drops a sort whose column was deleted from both the URL and its persisted
776+
* view. `queryOptions` feeds the query that produces `columns`, so clearing the
777+
* source of truth avoids a dependency cycle and prevents the dead sort from
778+
* returning on reload.
779+
*/
780+
useEffect(() => {
781+
if (!sortColumn || columns.length === 0) return
782+
if (liveColumnIds.has(sortColumn)) return
783+
setTableParams({ sort: null, dir: null })
784+
persistActiveViewConfig({ sort: null })
785+
}, [sortColumn, columns.length, liveColumnIds, setTableParams, persistActiveViewConfig])
786+
785787
/** Column order/width/pinning auto-saves into the active view as the user drags.
786788
* Sent as a `configPatch` so the server merges it — two overlapping layout writes must
787789
* not each replace the whole blob from their own snapshot. With All selected

0 commit comments

Comments
 (0)