Skip to content

Commit 850d8c4

Browse files
committed
fix(app): confirm workspace deletion on Enter
1 parent 51e310c commit 850d8c4

3 files changed

Lines changed: 42 additions & 9 deletions

File tree

packages/app/src/pages/layout.tsx

Lines changed: 24 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ import {
7171
errorMessage,
7272
latestRootSession,
7373
sortedRootSessions,
74+
workspaceDeleteKeyAction,
7475
} from "./layout/helpers"
7576
import {
7677
collectNewSessionDeepLinks,
@@ -1622,7 +1623,30 @@ export default function Layout(props: ParentProps) {
16221623
dirty: false,
16231624
})
16241625

1626+
const handleDelete = () => {
1627+
const leaveDeletedWorkspace = !!params.dir && pathKey(currentDir()) === pathKey(props.directory)
1628+
if (leaveDeletedWorkspace) {
1629+
navigateWithSidebarReset(`/${base64Encode(props.root)}/session`)
1630+
}
1631+
dialog.close()
1632+
void deleteWorkspace(props.root, props.directory, leaveDeletedWorkspace)
1633+
}
1634+
16251635
onMount(() => {
1636+
makeEventListener(
1637+
window,
1638+
"keydown",
1639+
(event) => {
1640+
const action = workspaceDeleteKeyAction(event, data.status)
1641+
if (action === "ignore") return
1642+
event.preventDefault()
1643+
event.stopPropagation()
1644+
if (action === "block") return
1645+
handleDelete()
1646+
},
1647+
{ capture: true },
1648+
)
1649+
16261650
globalSDK.client.file
16271651
.status({ directory: props.directory })
16281652
.then((x) => {
@@ -1635,15 +1659,6 @@ export default function Layout(props: ParentProps) {
16351659
})
16361660
})
16371661

1638-
const handleDelete = () => {
1639-
const leaveDeletedWorkspace = !!params.dir && pathKey(currentDir()) === pathKey(props.directory)
1640-
if (leaveDeletedWorkspace) {
1641-
navigateWithSidebarReset(`/${base64Encode(props.root)}/session`)
1642-
}
1643-
dialog.close()
1644-
void deleteWorkspace(props.root, props.directory, leaveDeletedWorkspace)
1645-
}
1646-
16471662
const description = () => {
16481663
if (data.status === "loading") return language.t("workspace.status.checking")
16491664
if (data.status === "error") return language.t("workspace.status.error")

packages/app/src/pages/layout/helpers.test.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
errorMessage,
1515
hasProjectPermissions,
1616
latestRootSession,
17+
workspaceDeleteKeyAction,
1718
} from "./helpers"
1819
import { pathKey } from "@/utils/path-key"
1920

@@ -217,6 +218,14 @@ describe("layout workspace helpers", () => {
217218
expect(displayName({ worktree: "/tmp/app", name: "My App" })).toBe("My App")
218219
})
219220

221+
test("maps workspace delete dialog Enter keys", () => {
222+
expect(workspaceDeleteKeyAction(new KeyboardEvent("keydown", { key: "Escape" }), "ready")).toBe("ignore")
223+
expect(workspaceDeleteKeyAction(new KeyboardEvent("keydown", { key: "Enter" }), "loading")).toBe("block")
224+
expect(workspaceDeleteKeyAction(new KeyboardEvent("keydown", { key: "Enter", repeat: true }), "ready")).toBe("block")
225+
expect(workspaceDeleteKeyAction(new KeyboardEvent("keydown", { key: "Enter" }), "ready")).toBe("confirm")
226+
expect(workspaceDeleteKeyAction(new KeyboardEvent("keydown", { key: "Enter" }), "error")).toBe("confirm")
227+
})
228+
220229
test("extracts api error message and fallback", () => {
221230
expect(errorMessage({ data: { message: "boom" } }, "fallback")).toBe("boom")
222231
expect(errorMessage(new Error("broken"), "fallback")).toBe("broken")

packages/app/src/pages/layout/helpers.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,15 @@ export const childSessionOnPath = (sessions: Session[] | undefined, rootID: stri
5555
export const displayName = (project: { name?: string; worktree: string }) =>
5656
project.name || getFilename(project.worktree)
5757

58+
export function workspaceDeleteKeyAction(
59+
event: Pick<KeyboardEvent, "key" | "repeat">,
60+
status: "loading" | "ready" | "error",
61+
) {
62+
if (event.key !== "Enter") return "ignore"
63+
if (event.repeat || status === "loading") return "block"
64+
return "confirm"
65+
}
66+
5867
export const errorMessage = (err: unknown, fallback: string) => {
5968
if (err && typeof err === "object" && "data" in err) {
6069
const data = (err as { data?: { message?: string } }).data

0 commit comments

Comments
 (0)