Repository navigation
Description
Summary
In the desktop sidebar, workspaces sometimes render without their "creating" / "preparing" / "generating-branch" status indicator even though we have a cached representation of the in-flight create. The workspace row appears as if it's fully synced, even though Electric hasn't actually delivered the real v2Workspaces row yet.
Where it happens
The cloudRowFallbackWorkspaces builder added in 5133730a0 (fix(desktop): keep sidebar from sticking on "creating" when Electric is slow) constructs a sidebar workspace from the cloudRow cached on an in-flight workspace-create entry, but never carries creationStatus onto the resulting object.
apps/desktop/src/renderer/routes/_authenticated/_dashboard/components/DashboardSidebar/hooks/useDashboardSidebarData/useDashboardSidebarData.ts:300-331
const cloudRowFallbackWorkspaces = useMemo(() => {
if (inFlightEntries.length === 0) return [];
// ...
return [
{
id: cloudRow.id,
projectId: localState?.sidebarState.projectId ?? cloudRow.projectId,
hostId: cloudRow.hostId,
type: cloudRow.type,
hostIsOnline: host?.isOnline ?? false,
name: cloudRow.name,
branch: cloudRow.branch,
createdAt: cloudRow.createdAt,
updatedAt: cloudRow.updatedAt,
tabOrder: localState?.sidebarState.tabOrder ?? PENDING_WORKSPACE_TAB_ORDER,
sectionId: localState?.sidebarState.sectionId ?? null,
isHidden: localState?.sidebarState.isHidden ?? false,
// ❌ creationStatus is never set
},
];
}, [collections, hosts, inFlightEntries, localStateWorkspaceIds]);The shape it returns must satisfy DashboardSidebarWorkspace, which declares creationStatus?: "preparing" | "generating-branch" | "creating" | "failed" (see DashboardSidebar/types.ts:43). Because the field is optional, TS doesn't catch the omission.
Why the indicator disappears
The "creating" pending-workspace list is filtered earlier in the same hook: entries with both state === "creating" and a cloudRow are stripped from the pending list (around useDashboardSidebarData.ts:147) so we don't render the workspace twice. That's correct in principle — but it means the cloud-row fallback row is the only thing left to surface that workspace, and it carries no status.
The downstream consumers all key off creationStatus:
DashboardSidebarWorkspaceItem.tsx:79-80—isPending = !!creationStatusDashboardSidebarWorkspaceIcon.tsx:106-108— spinner/failure icon only renders whencreationStatusis setDashboardSidebarExpandedWorkspaceRow.tsx:86-103, 258-267— "Creating…" status text only renders viagetCreationStatusText(creationStatus)
So with creationStatus undefined, the row paints as a normal "synced" workspace right up until Electric delivers the real row and the live query takes over.
Repro
- Trigger a workspace create on a host where the host-service
workspaces.createresolves quickly but Electric is slow to deliver the newv2Workspacesrow (or throttle the Electric stream). - Observe the sidebar: workspace appears with no spinner or "Creating…" label, no status badge, just a normal-looking row.
- Once Electric catches up, the row is replaced seamlessly by the live-query version — so the "missing status" only happens during the fallback window.
Suggested fix
When building cloudRowFallbackWorkspaces, derive creationStatus from entry.state (and possibly persist it on cloudRow itself so this is harder to forget). At minimum:
creationStatus: entry.state === "creating" ? "creating" : undefined,Then double-check the filter at useDashboardSidebarData.ts:147 is consistent with the new behavior (we probably want to keep stripping the duplicate pending entry, since the fallback now carries the status itself).
References
- Commit:
5133730a0fix(desktop): keep sidebar from sticking on "creating" when Electric is slow - Workspace-creates store:
apps/desktop/src/renderer/stores/workspace-creates/store.ts - Manager that removes entries once Electric delivers:
apps/desktop/src/renderer/stores/workspace-creates/Manager.tsx
Activity
fix(desktop): keep creationStatus on sidebar cloud-row fallback rows