From 782174edc56cafaf916f2c8e6118c2b5a1e1d926 Mon Sep 17 00:00:00 2001 From: Merge Resolver Date: Tue, 19 Aug 2025 17:39:22 -0600 Subject: [PATCH] feat(webview-ui): show all auto-approve icons in collapsed view and highlight active ones; update tests --- .../src/components/chat/AutoApproveMenu.tsx | 48 ++++++++----------- .../chat/__tests__/AutoApproveMenu.spec.tsx | 43 ++++++++++++----- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/webview-ui/src/components/chat/AutoApproveMenu.tsx b/webview-ui/src/components/chat/AutoApproveMenu.tsx index caa5ac73fb..23a0f78465 100644 --- a/webview-ui/src/components/chat/AutoApproveMenu.tsx +++ b/webview-ui/src/components/chat/AutoApproveMenu.tsx @@ -129,12 +129,8 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { setIsExpanded((prev) => !prev) }, []) - // Get enabled icons for display - const enabledIcons = useMemo(() => { - return Object.entries(toggles) - .filter(([_key, value]) => !!value) - .map(([key]) => autoApproveSettingsConfig[key as AutoApproveSetting].icon) - }, [toggles]) + // Get all icons for display and highlight based on toggle state + const allConfigs = useMemo(() => Object.values(autoApproveSettingsConfig), []) const handleOpenSettings = useCallback( () => @@ -211,27 +207,25 @@ const AutoApproveMenu = ({ style }: AutoApproveMenuProps) => { alignItems: "center", gap: "6px", }}> - {!effectiveAutoApprovalEnabled || !hasEnabledOptions - ? t("chat:autoApprove.none") - : enabledIcons.map((icon, index) => { - // Find the config for this icon to get the label - const config = Object.values(autoApproveSettingsConfig).find( - (cfg) => cfg.icon === icon, - ) - const tooltipContent = config ? t(config.labelKey) : "" - - return ( - - - - ) - })} + {allConfigs.map(({ key, icon, labelKey }) => { + const isEnabled = !!toggles[key] + return ( + + + + ) + })} { }) describe("Master checkbox behavior", () => { - it("should show 'None selected' when no sub-options are selected", () => { + it("should show all icons with none highlighted when no sub-options are selected", () => { ;(useExtensionState as ReturnType).mockReturnValue({ ...defaultExtensionState, autoApprovalEnabled: false, @@ -98,11 +98,23 @@ describe("AutoApproveMenu", () => { render() - // Check that the text shows "None selected" - expect(screen.getByText("None selected")).toBeInTheDocument() + const container = screen.getByText("Auto-approve").parentElement?.parentElement + + // All primary icons are rendered + expect(container?.querySelector(".codicon-eye")).toBeInTheDocument() + expect(container?.querySelector(".codicon-edit")).toBeInTheDocument() + expect(container?.querySelector(".codicon-terminal")).toBeInTheDocument() + + // None are active + expect(container?.querySelector(".codicon-eye")?.getAttribute("data-active")).toBe("false") + expect(container?.querySelector(".codicon-edit")?.getAttribute("data-active")).toBe("false") + expect(container?.querySelector(".codicon-terminal")?.getAttribute("data-active")).toBe("false") + + // "None selected" helper text is not shown anymore + expect(screen.queryByText("None selected")).not.toBeInTheDocument() }) - it("should show enabled options when sub-options are selected", () => { + it("should highlight the enabled icons when sub-options are selected", () => { ;(useExtensionState as ReturnType).mockReturnValue({ ...defaultExtensionState, autoApprovalEnabled: true, @@ -112,9 +124,15 @@ describe("AutoApproveMenu", () => { render() - // Check that the icon for read-only operations is shown - const container = screen.getByText("Auto-approve").parentElement?.parentElement - expect(container?.querySelector(".codicon-eye")).toBeInTheDocument() + const container = screen.getByText("Auto-approve").parentElement?.parentElement as HTMLElement + const eyeIcon = container.querySelector(".codicon-eye") as HTMLElement + const editIcon = container.querySelector(".codicon-edit") as HTMLElement + + expect(eyeIcon).toBeInTheDocument() + expect(editIcon).toBeInTheDocument() + + expect(eyeIcon.getAttribute("data-active")).toBe("true") + expect(editIcon.getAttribute("data-active")).toBe("false") }) it("should not allow toggling master checkbox when no options are selected", () => { @@ -213,7 +231,7 @@ describe("AutoApproveMenu", () => { }) describe("Complex scenarios", () => { - it("should display multiple enabled options in summary text", () => { + it("should highlight multiple enabled icons in collapsed view", () => { ;(useExtensionState as ReturnType).mockReturnValue({ ...defaultExtensionState, autoApprovalEnabled: true, @@ -224,11 +242,10 @@ describe("AutoApproveMenu", () => { render() - // Should show icons for all enabled options - const container = screen.getByText("Auto-approve").parentElement?.parentElement - expect(container?.querySelector(".codicon-eye")).toBeInTheDocument() // Read - expect(container?.querySelector(".codicon-edit")).toBeInTheDocument() // Write - expect(container?.querySelector(".codicon-terminal")).toBeInTheDocument() // Execute + 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 }) it("should display tooltips on icons in collapsed view", async () => {