From f8f82b7ec246dbdab951ead2cc2ea2987b8dfd09 Mon Sep 17 00:00:00 2001 From: Dotta Date: Tue, 5 May 2026 12:20:46 -0500 Subject: [PATCH] fix(ui): hide planning chip on standard issues and surface toggle via three-dot menu (PAP-3613) Per user feedback: only show the Planning chip in the composer when planning mode is in effect. On a standard issue we no longer render the chip; instead a three-dot button next to the paperclip opens a menu with "Switch to planning" (or "Switch to standard" once toggled). The container only goes amber when pendingWorkMode === planning, matching the visible chip. Co-Authored-By: Paperclip --- ui/src/components/IssueChatThread.test.tsx | 34 +++++++++--- ui/src/components/IssueChatThread.tsx | 64 +++++++++++++++------- 2 files changed, 70 insertions(+), 28 deletions(-) diff --git a/ui/src/components/IssueChatThread.test.tsx b/ui/src/components/IssueChatThread.test.tsx index 0829421fde..3918b39b5a 100644 --- a/ui/src/components/IssueChatThread.test.tsx +++ b/ui/src/components/IssueChatThread.test.tsx @@ -383,7 +383,7 @@ describe("IssueChatThread", () => { }); }); - it("toggles the composer work mode for the next submission without changing the issue immediately", () => { + it("hides the planning chip on a standard issue and exposes the toggle through the menu", () => { const root = createRoot(container); const onWorkModeChange = vi.fn(); @@ -404,21 +404,41 @@ describe("IssueChatThread", () => { ); }); - const toggle = container.querySelector( - '[data-testid="issue-chat-composer-work-mode-toggle"]', + expect( + container.querySelector('[data-testid="issue-chat-composer-work-mode-toggle"]'), + ).toBeNull(); + const composer = container.querySelector('[data-testid="issue-chat-composer"]'); + expect(composer?.getAttribute("data-pending-work-mode")).toBe("standard"); + expect(composer?.className).not.toContain("amber"); + + const menuTrigger = container.querySelector( + '[data-testid="issue-chat-composer-work-mode-menu"]', ) as HTMLButtonElement | null; - expect(toggle).not.toBeNull(); - expect(toggle?.getAttribute("data-pending-work-mode")).toBe("standard"); + expect(menuTrigger).not.toBeNull(); + act(() => { + menuTrigger?.click(); + }); + + const menuItem = document.querySelector( + '[data-testid="issue-chat-composer-work-mode-menu-toggle"]', + ) as HTMLButtonElement | null; + expect(menuItem).not.toBeNull(); + expect(menuItem?.textContent).toContain("Switch to planning"); act(() => { - toggle?.click(); + menuItem?.click(); }); expect(onWorkModeChange).not.toHaveBeenCalled(); - const composer = container.querySelector('[data-testid="issue-chat-composer"]'); expect(composer?.getAttribute("data-pending-work-mode")).toBe("planning"); expect(composer?.className).toContain("amber"); + const visibleChip = container.querySelector( + '[data-testid="issue-chat-composer-work-mode-toggle"]', + ); + expect(visibleChip).not.toBeNull(); + expect(visibleChip?.textContent).toContain("Planning"); + act(() => { root.unmount(); }); diff --git a/ui/src/components/IssueChatThread.tsx b/ui/src/components/IssueChatThread.tsx index b9803abfdb..aea91c341c 100644 --- a/ui/src/components/IssueChatThread.tsx +++ b/ui/src/components/IssueChatThread.tsx @@ -2837,6 +2837,7 @@ const IssueChatComposer = forwardRef(resolvedIssueWorkMode); + const [workModeMenuOpen, setWorkModeMenuOpen] = useState(false); const canToggleWorkMode = typeof onWorkModeChange === "function"; const attachInputRef = useRef(null); const editorRef = useRef(null); @@ -3221,32 +3222,53 @@ const IssueChatComposer = forwardRef ) : null} {canToggleWorkMode ? ( + + + + + + + + + ) : null} + {canToggleWorkMode && isPlanning ? ( ) : null}