Kaynağa Gözat

fix(app): terminal rename from context menu (#18263)

Co-authored-by: Brendan Allan <[email protected]>
Filip 3 hafta önce
ebeveyn
işleme
c529529f84

+ 37 - 1
packages/app/e2e/terminal/terminal-tabs.spec.ts

@@ -1,7 +1,7 @@
 import type { Page } from "@playwright/test"
 import { runTerminal, waitTerminalReady } from "../actions"
 import { test, expect } from "../fixtures"
-import { terminalSelector } from "../selectors"
+import { dropdownMenuContentSelector, terminalSelector } from "../selectors"
 import { terminalToggleKey, workspacePersistKey } from "../utils"
 
 type State = {
@@ -130,3 +130,39 @@ test("closing the active terminal tab falls back to the previous tab", async ({
       .toEqual({ count: 1, first: true })
   })
 })
+
+test("terminal tab can be renamed from the context menu", async ({ page, withProject }) => {
+  await withProject(async ({ directory, gotoSession }) => {
+    const key = workspacePersistKey(directory, "terminal")
+    const rename = `E2E term ${Date.now()}`
+    const tab = page.locator('#terminal-panel [data-slot="tabs-trigger"]').first()
+
+    await gotoSession()
+    await open(page)
+
+    await expect(tab).toContainText(/Terminal 1/)
+    await tab.click({ button: "right" })
+
+    const menu = page.locator(dropdownMenuContentSelector).first()
+    await expect(menu).toBeVisible()
+    await menu.getByRole("menuitem", { name: /^Rename$/i }).click()
+    await expect(menu).toHaveCount(0)
+
+    const input = page.locator('#terminal-panel input[type="text"]').first()
+    await expect(input).toBeVisible()
+    await input.fill(rename)
+    await input.press("Enter")
+
+    await expect(input).toHaveCount(0)
+    await expect(tab).toContainText(rename)
+    await expect
+      .poll(
+        async () => {
+          const state = await store(page, key)
+          return state?.all[0]?.title
+        },
+        { timeout: 5_000 },
+      )
+      .toBe(rename)
+  })
+})

+ 8 - 1
packages/app/src/components/session/session-sortable-terminal-tab.tsx

@@ -24,6 +24,7 @@ export function SortableTerminalTab(props: { terminal: LocalPTY; onClose?: () =>
   })
   let input: HTMLInputElement | undefined
   let blurFrame: number | undefined
+  let editRequested = false
 
   const isDefaultTitle = () => {
     const number = props.terminal.titleNumber
@@ -168,8 +169,14 @@ export function SortableTerminalTab(props: { terminal: LocalPTY; onClose?: () =>
                 left: `${store.menuPosition.x}px`,
                 top: `${store.menuPosition.y}px`,
               }}
+              onCloseAutoFocus={(e) => {
+                if (!editRequested) return
+                e.preventDefault()
+                editRequested = false
+                requestAnimationFrame(() => edit())
+              }}
             >
-              <DropdownMenu.Item onSelect={edit}>
+              <DropdownMenu.Item onSelect={() => (editRequested = true)}>
                 <Icon name="edit" class="w-4 h-4 mr-2" />
                 {language.t("common.rename")}
               </DropdownMenu.Item>