From 890186246524a4ae77b4efdbfcf920d1b6efa989 Mon Sep 17 00:00:00 2001 From: Mohamed Boudra Date: Tue, 10 Nov 2026 10:12:14 +0100 Subject: [PATCH] fix(app): close an inline rename that submits the row's current title Saving the title another client had just set left the row's title where it was, so the saved phase waited forever with the field read-only and the row's press and menu handlers off. A submit matching the current title now closes without a request. --- .../browser/sidebar-workspace-rename.spec.ts | 30 +++++++++++++++++++ .../internal/use-sidebar-workspace-rename.tsx | 3 +- 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/packages/app/e2e/browser/sidebar-workspace-rename.spec.ts b/packages/app/e2e/browser/sidebar-workspace-rename.spec.ts index 2a10e52c03..97c06bf36f 100644 --- a/packages/app/e2e/browser/sidebar-workspace-rename.spec.ts +++ b/packages/app/e2e/browser/sidebar-workspace-rename.spec.ts @@ -249,6 +249,36 @@ test.describe("Sidebar workspace rename", () => { } }); + test("submitting the title another client just set closes the field without saving", async ({ + page, + }) => { + const workspace = await seedWorkspace({ repoPrefix: "sidebar-rename-external-same-" }); + + try { + const gate = await installDaemonWebSocketGate(page); + await page.setViewportSize({ width: 1280, height: 800 }); + await gotoAppShell(page); + const row = page.getByTestId(workspaceRowTestId(workspace.workspaceId)); + const input = page.getByTestId(workspaceRenameInputTestId(workspace.workspaceId)); + + await chooseRenameFromKebab(page, workspace.workspaceId); + await expect(input).toBeFocused(); + await renameFromAnotherClient(page, gate, workspace, "External title"); + + await input.fill("External title"); + await page.keyboard.press("Enter"); + await expect(input).toHaveCount(0); + await expect(row).toContainText("External title"); + expect(gate.getClientRequestCount("workspace.title.set.request")).toBe(0); + + // The row is a row again: its menu opens and renames. + await chooseRenameFromKebab(page, workspace.workspaceId); + await expect(input).toBeFocused(); + } finally { + await workspace.cleanup(); + } + }); + test("below the lg breakpoint renaming opens the modal", async ({ page }) => { const workspace = await seedWorkspace({ repoPrefix: "sidebar-rename-modal-" }); diff --git a/packages/app/src/workspace-rename/internal/use-sidebar-workspace-rename.tsx b/packages/app/src/workspace-rename/internal/use-sidebar-workspace-rename.tsx index dd27e9a508..f06ccbea0e 100644 --- a/packages/app/src/workspace-rename/internal/use-sidebar-workspace-rename.tsx +++ b/packages/app/src/workspace-rename/internal/use-sidebar-workspace-rename.tsx @@ -71,7 +71,8 @@ export function useSidebarWorkspaceRename( (text: string) => { if (session.kind !== "inline") return; const title = text.trim(); - if (title.length === 0 || title === session.initialValue) { + // Saving the title the row already has would never move it, so `saved` would never end. + if (title.length === 0 || title === session.initialValue || title === currentTitle) { setSession(CLOSED); return; }