diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index 23a0f78465..2ab3daa202 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -206,14 +206,16 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { display: "flex", alignItems: "center", gap: "6px", - }}> + }} + onClick={(e) => e.stopPropagation()}> {allConfigs.map(({ key, icon, labelKey }) => { const isEnabled = !!toggles[key] return ( - onAutoApproveToggle(key, !isEnabled)} style={{ fontSize: "14px", flexShrink: 0, @@ -221,6 +223,19 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { color: isEnabled ? "var(--vscode-foreground)" : "var(--vscode-descriptionForeground)", + background: "transparent", + border: "none", + cursor: "pointer", + padding: "2px", + borderRadius: "3px", + transition: "background-color 0.1s", + }} + onMouseEnter={(e) => { + e.currentTarget.style.backgroundColor = + "var(--vscode-toolbar-hoverBackground)" + }} + onMouseLeave={(e) => { + e.currentTarget.style.backgroundColor = "transparent" }} /> diff --git a/webview-ui/src/components/chat/__tests__/AutoApproveMenu.spec.tsx b/webview-ui/src/components/chat/__tests__/AutoApproveMenu.spec.tsx index 0a0ff8d2da..f35b6b27c8 100644 --- a/webview-ui/src/components/chat/__tests__/AutoApproveMenu.spec.tsx +++ b/webview-ui/src/components/chat/__tests__/AutoApproveMenu.spec.tsx @@ -243,12 +243,48 @@ describe("AutoApproveMenu", () => { render() const container = screen.getByText("Auto-approve").parentElement?.parentElement as HTMLElement - expect(container.querySelector(".codicon-eye")?.getAttribute("data-active")).toBe("true") // Read - expect(container.querySelector(".codicon-edit")?.getAttribute("data-active")).toBe("true") // Write - expect(container.querySelector(".codicon-terminal")?.getAttribute("data-active")).toBe("true") // Execute + expect(container.querySelector("button.codicon-eye")?.getAttribute("data-active")).toBe("true") // Read + expect(container.querySelector("button.codicon-edit")?.getAttribute("data-active")).toBe("true") // Write + expect(container.querySelector("button.codicon-terminal")?.getAttribute("data-active")).toBe("true") // Execute }) - it("should display tooltips on icons in collapsed view", async () => { + it("should toggle options when clicking icons in collapsed view", () => { + const mockSetAlwaysAllowReadOnly = vi.fn() + const mockSetAlwaysAllowWrite = vi.fn() + + ;(useExtensionState as ReturnType).mockReturnValue({ + ...defaultExtensionState, + autoApprovalEnabled: false, + alwaysAllowReadOnly: false, + alwaysAllowWrite: false, + setAlwaysAllowReadOnly: mockSetAlwaysAllowReadOnly, + setAlwaysAllowWrite: mockSetAlwaysAllowWrite, + }) + + render() + + const container = screen.getByText("Auto-approve").parentElement?.parentElement as HTMLElement + const eyeButton = container.querySelector("button.codicon-eye") as HTMLElement + const editButton = container.querySelector("button.codicon-edit") as HTMLElement + + // Click the read-only icon + fireEvent.click(eyeButton) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: "alwaysAllowReadOnly", + bool: true, + }) + expect(mockSetAlwaysAllowReadOnly).toHaveBeenCalledWith(true) + + // Click the write icon + fireEvent.click(editButton) + expect(mockPostMessage).toHaveBeenCalledWith({ + type: "alwaysAllowWrite", + bool: true, + }) + expect(mockSetAlwaysAllowWrite).toHaveBeenCalledWith(true) + }) + + it("should display tooltips on icon buttons in collapsed view", async () => { const user = userEvent.setup() ;(useExtensionState as ReturnType).mockReturnValue({ @@ -261,19 +297,19 @@ describe("AutoApproveMenu", () => { render() - // Find the icons + // Find the icon buttons const container = screen.getByText("Auto-approve").parentElement?.parentElement - const eyeIcon = container?.querySelector(".codicon-eye") as HTMLElement - const editIcon = container?.querySelector(".codicon-edit") as HTMLElement - const terminalIcon = container?.querySelector(".codicon-terminal") as HTMLElement + const eyeButton = container?.querySelector("button.codicon-eye") as HTMLElement + const editButton = container?.querySelector("button.codicon-edit") as HTMLElement + const terminalButton = container?.querySelector("button.codicon-terminal") as HTMLElement - // Verify icons are present - expect(eyeIcon).toBeInTheDocument() - expect(editIcon).toBeInTheDocument() - expect(terminalIcon).toBeInTheDocument() + // Verify icon buttons are present + expect(eyeButton).toBeInTheDocument() + expect(editButton).toBeInTheDocument() + expect(terminalButton).toBeInTheDocument() // Test read-only icon tooltip - await user.hover(eyeIcon) + await user.hover(eyeButton) await waitFor(() => { expect(screen.getByRole("tooltip")).toHaveTextContent("Read-only operations") })