From 7f862533d8e54369ffab402de9724c50fd37b93e Mon Sep 17 00:00:00 2001 From: Adam <2363879+adamdotdevin@users.noreply.github.com> Date: Tue, 20 Jan 2026 10:31:13 -0600 Subject: [PATCH] fix(app): better pending states for workspace operations --- packages/app/src/pages/layout.tsx | 45 ++++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/packages/app/src/pages/layout.tsx b/packages/app/src/pages/layout.tsx index 64fc52739..cc18111ba 100644 --- a/packages/app/src/pages/layout.tsx +++ b/packages/app/src/pages/layout.tsx @@ -122,6 +122,17 @@ export default function Layout(props: ParentProps) { active: "" as string, value: "", }) + const [busyWorkspaces, setBusyWorkspaces] = createSignal>(new Set()) + const setBusy = (directory: string, value: boolean) => { + const key = workspaceKey(directory) + setBusyWorkspaces((prev) => { + const next = new Set(prev) + if (value) next.add(key) + else next.delete(key) + return next + }) + } + const isBusy = (directory: string) => busyWorkspaces().has(workspaceKey(directory)) const editorRef = { current: undefined as HTMLInputElement | undefined } const autoselecting = createMemo(() => { @@ -995,6 +1006,8 @@ export default function Layout(props: ParentProps) { if (!current) return if (directory === current.worktree) return + setBusy(directory, true) + const result = await globalSDK.client.worktree .remove({ directory: current.worktree, worktreeRemoveInput: { directory } }) .then((x) => x.data) @@ -1006,6 +1019,8 @@ export default function Layout(props: ParentProps) { return false }) + setBusy(directory, false) + if (!result) return layout.projects.close(directory) @@ -1021,12 +1036,7 @@ export default function Layout(props: ParentProps) { if (!current) return if (directory === current.worktree) return - const progress = showToast({ - persistent: true, - title: "Resetting workspace", - description: "This may take a minute.", - }) - const dismiss = () => toaster.dismiss(progress) + setBusy(directory, true) const sessions = await globalSDK.client.session .list({ directory }) @@ -1037,7 +1047,6 @@ export default function Layout(props: ParentProps) { .reset({ directory: current.worktree, worktreeResetInput: { directory } }) .then((x) => x.data) .catch((err) => { - dismiss() showToast({ title: "Failed to reset workspace", description: errorMessage(err), @@ -1046,7 +1055,7 @@ export default function Layout(props: ParentProps) { }) if (!result) { - dismiss() + setBusy(directory, false) return } @@ -1066,7 +1075,8 @@ export default function Layout(props: ParentProps) { ) await globalSDK.client.instance.dispose({ directory }).catch(() => undefined) - dismiss() + + setBusy(directory, false) const href = `/${base64Encode(directory)}/session` navigate(href) @@ -1590,6 +1600,7 @@ export default function Layout(props: ParentProps) { const boot = createMemo(() => open() || active()) const loading = createMemo(() => open() && workspaceStore.status !== "complete" && sessions().length === 0) const hasMore = createMemo(() => local() && workspaceStore.sessionTotal > workspaceStore.session.length) + const busy = createMemo(() => isBusy(props.directory)) const loadMore = async () => { if (!local()) return setWorkspaceStore("limit", (limit) => limit + 5) @@ -1612,7 +1623,9 @@ export default function Layout(props: ParentProps) { const header = () => (
- + }> + +
{local() ? "local" : "sandbox"} : +
@@ -1699,13 +1718,13 @@ export default function Layout(props: ParentProps) { Rename dialog.show(() => )} > Reset dialog.show(() => )} > Delete