fix(client): prune removed workspace view state

This commit is contained in:
_Kerman
2026-08-11 18:59:06 +08:00
parent 230f3b8295
commit 909725f2e9
10 changed files with 71 additions and 12 deletions

View File

@@ -625,6 +625,7 @@ export function WorkspaceBrowser({
t,
}: WorkspaceBrowserProps) {
const workspaces = useWorkspaces(state => state.items)
const workspacePhase = useWorkspaces(state => state.phase)
const archivedSessionIds = useWorkspaces(state => state.archivedSessionIds)
// Live occupancy of this surface's directory-flow hole (the same source the
// flow reads): a composition without a picking affordance can add nothing.
@@ -637,6 +638,13 @@ export function WorkspaceBrowser({
const workspaceExpansion = useStore(s => s.workspaceExpansion)
const recentSessionOrder = useStore(s => s.recentSessionOrder)
const recentSessionUpdatedAt = useStore(s => s.recentSessionUpdatedAt)
useEffect(() => {
if (workspacePhase !== 'ready') return
actions.retainWorkspaceKeys([
UNGROUPED_KEY,
...workspaces.map(workspace => workspace.workspaceId as string),
])
}, [actions.retainWorkspaceKeys, workspacePhase, workspaces])
// The query outlives the tree and the input (both wide-only) so collapsing
// does not silently drop an in-progress filter.
const [query, setQuery] = useState('')

View File

@@ -32,6 +32,7 @@ type WorkspaceViewActions = {
setGroupBy: (draft: WorkspaceViewState, mode: WorkspaceGroupBy) => void
setOrderBy: (draft: WorkspaceViewState, mode: WorkspaceOrderBy) => void
setWorkspaceExpanded: (draft: WorkspaceViewState, key: string, expanded: boolean) => void
retainWorkspaceKeys: (draft: WorkspaceViewState, workspaceKeys: readonly string[]) => void
syncRecentSessions: (
draft: WorkspaceViewState,
workspaceKey: string,
@@ -59,6 +60,18 @@ export function createWorkspaceViewStore(): EngineStoreHandle<WorkspaceViewState
setGroupBy: (d, mode: WorkspaceGroupBy) => { d.groupBy = mode },
setOrderBy: (d, mode: WorkspaceOrderBy) => { d.orderBy = mode },
setWorkspaceExpanded: (d, key: string, expanded: boolean) => { d.workspaceExpansion[key] = expanded },
retainWorkspaceKeys: (d, workspaceKeys: readonly string[]) => {
const retained = new Set(workspaceKeys)
d.workspaceExpansion = Object.fromEntries(
Object.entries(d.workspaceExpansion).filter(([key]) => retained.has(key)),
)
d.recentSessionOrder = Object.fromEntries(
Object.entries(d.recentSessionOrder).filter(([key]) => retained.has(key)),
)
d.recentSessionUpdatedAt = Object.fromEntries(
Object.entries(d.recentSessionUpdatedAt).filter(([key]) => retained.has(key)),
)
},
syncRecentSessions: (d, workspaceKey: string, order: string[], updatedAt: Record<string, number>) => {
d.recentSessionOrder[workspaceKey] = order
d.recentSessionUpdatedAt[workspaceKey] = updatedAt