fix(desktop): prevent ghost workspace re-appearance on close#1345
fix(desktop): prevent ghost workspace re-appearance on close#1345
Conversation
When closing a workspace, the `close` procedure awaited terminal kills before marking the workspace as deleting. If another workspace was created during that window, the `getAllGrouped` refetch found the closing workspace still visible in the DB, overwriting the optimistic removal and causing stale git metadata to appear on the sidebar. Move `markWorkspaceAsDeleting` and dependent state updates before the async terminal kill in both the workspace `close` and project `close` procedures, matching the existing `delete` procedure pattern.
📝 WalkthroughWalkthroughReorders close/delete flows: closed workspace IDs are determined early, workspaces are marked Changes
Sequence Diagram(s)sequenceDiagram
participant API as Projects API
participant DB as Database
participant Term as TerminalService
participant WS as WorkspaceService
API->>DB: compute closedWorkspaceIds(projectId)
API->>DB: mark workspaces deletingAt(closedWorkspaceIds)
API->>DB: set project.tabOrder = null
API->>Term: kill terminals for closedWorkspaceIds (parallel)
Term-->>API: terminal kill results (success/failure)
API->>DB: selectNextActiveWorkspace(projectId)
API->>DB: setLastActiveWorkspace(nextActiveWorkspace)
API->>WS: delete workspaces(closedWorkspaceIds)
WS-->>DB: remove workspace rows
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~20 minutes Possibly related PRs
Poem
🚥 Pre-merge checks | ✅ 3✅ Passed checks (3 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing touches
🧪 Generate unit tests (beta)
No actionable comments were generated in the recent review. 🎉 Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
There was a problem hiding this comment.
Actionable comments posted: 1
🤖 Fix all issues with AI agents
In `@apps/desktop/src/lib/trpc/routers/workspaces/procedures/delete.ts`:
- Around line 302-312: hideProjectIfNoWorkspaces is called before
deleteWorkspace so the helper still sees the workspace (only marked deletingAt)
and never hides the project; either move the
hideProjectIfNoWorkspaces(input.projectId) call to after
deleteWorkspace(input.id) in the delete procedure (so it runs once the row is
removed) or update the helper in db-helpers.ts to exclude rows with deletingAt
set; update the code paths around markWorkspaceAsDeleting,
getWorkspaceRuntimeRegistry().terminal.killByWorkspaceId, and deleteWorkspace to
ensure hideProjectIfNoWorkspaces runs after the workspace is actually deleted.
hideProjectIfNoWorkspaces counts all rows including deletingAt ones (intentional for concurrent deletion safety), so the row must be fully deleted before the check runs.
2e55baa to
b7584e1
Compare
Summary
getAllGroupedrefetches could resurrect the workspace in the sidebarcloseand projectclosewith the existingdeleteprocedure patternChanges
workspaces/procedures/delete.ts: MovemarkWorkspaceAsDeletingandupdateActiveWorkspaceIfRemovedbefore the async terminal kill in thecloseprocedure; keephideProjectIfNoWorkspacesafterdeleteWorkspace(it counts all rows includingdeletingAtfor concurrent deletion safety)projects/projects.ts: Batch-setdeletingAton all project workspaces and hide the project before the async terminal kill loop; update active workspace viaselectNextActiveWorkspace()before terminal kills (previously used an unfiltered query after deletion); parallelize terminal kills withPromise.allTest Plan
Summary by CodeRabbit