From f58f0edd62b3854bb5b6a3d985556ee8c7d25809 Mon Sep 17 00:00:00 2001 From: Lum1104 Date: Mon, 4 May 2026 19:21:06 +0800 Subject: [PATCH] fix(dashboard): clear pendingFocusContainer on layer/state resets Codex review on PR #114 flagged that `layerResetIfChanged` cleared `containerLayoutCache` and `expandedContainers` but left `pendingFocusContainer` intact. Because container ids collide across layers (the very reason the cache reset exists), a manual expand in layer A that hadn't yet hit its 1.2s clear timer could leak its id into layer B's namespace and recenter the viewport on an unrelated container right after navigation. The same hazard applies to every other reset path that drops the container caches. Add `pendingFocusContainer: null` to all of them: - layerResetIfChanged (tour cross-layer reset, the originally flagged site) - drillIntoLayer - navigateToOverview - setFocusNode - setPersona - setGraph - toggleNodeTypeFilter - clearContainerLayouts Co-Authored-By: Claude Opus 4.7 (1M context) --- .../packages/dashboard/src/store.ts | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/understand-anything-plugin/packages/dashboard/src/store.ts b/understand-anything-plugin/packages/dashboard/src/store.ts index bd5a0c9..ea398a1 100644 --- a/understand-anything-plugin/packages/dashboard/src/store.ts +++ b/understand-anything-plugin/packages/dashboard/src/store.ts @@ -271,6 +271,10 @@ function layerResetIfChanged( containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + // Drop any pending focus too — its id was scoped to the previous + // layer and would otherwise re-collide with a same-id container in + // the new layer for the duration of the 1.2s timer. + pendingFocusContainer: null, }; } @@ -324,6 +328,7 @@ export const useDashboardStore = create()((set, get) => ({ containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, })), setGraph: (graph) => { @@ -350,6 +355,7 @@ export const useDashboardStore = create()((set, get) => ({ activeDomainId: keepDomainView ? activeDomainId : null, containerLayoutCache: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, containerSizeMemory: new Map(), stage1Tick: 0, layoutIssues: [], @@ -449,6 +455,7 @@ export const useDashboardStore = create()((set, get) => ({ containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, }), navigateToOverview: () => @@ -463,6 +470,7 @@ export const useDashboardStore = create()((set, get) => ({ containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, }), setFocusNode: (nodeId) => @@ -475,6 +483,7 @@ export const useDashboardStore = create()((set, get) => ({ containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, }), setSearchMode: (mode) => set({ searchMode: mode }), setSearchQuery: (query) => { @@ -498,6 +507,7 @@ export const useDashboardStore = create()((set, get) => ({ containerLayoutCache: new Map(), containerSizeMemory: new Map(), expandedContainers: new Set(), + pendingFocusContainer: null, }), openCodeViewer: (nodeId) => @@ -718,7 +728,7 @@ export const useDashboardStore = create()((set, get) => ({ return { containerLayoutCache: next, containerSizeMemory: sizeNext }; }), clearContainerLayouts: () => - set({ containerLayoutCache: new Map(), expandedContainers: new Set() }), + set({ containerLayoutCache: new Map(), expandedContainers: new Set(), pendingFocusContainer: null }), containerSizeMemory: new Map(),