From 9fb9bd2e68ba5387ba378001f81f35dca9c4a9c0 Mon Sep 17 00:00:00 2001 From: Brennan Benson <79079362+brennanb2025@users.noreply.github.com> Date: Thu, 13 Aug 2026 17:49:05 -0700 Subject: [PATCH] fix(sidebar): preserve reset for matching visibility overrides --- .../sidebar/WorktreeVisibilityDialog.tsx | 1 + .../WorktreeVisibilitySourceList.test.tsx | 70 +++++++++++++++++++ .../sidebar/WorktreeVisibilitySourceList.tsx | 26 ++++++- src/renderer/src/i18n/locales/en.json | 4 +- src/renderer/src/i18n/locales/es.json | 4 +- src/renderer/src/i18n/locales/ja.json | 4 +- src/renderer/src/i18n/locales/ko.json | 4 +- src/renderer/src/i18n/locales/zh.json | 4 +- 8 files changed, 111 insertions(+), 6 deletions(-) create mode 100644 src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.test.tsx diff --git a/src/renderer/src/components/sidebar/WorktreeVisibilityDialog.tsx b/src/renderer/src/components/sidebar/WorktreeVisibilityDialog.tsx index 48d73275417..160f06e1d96 100644 --- a/src/renderer/src/components/sidebar/WorktreeVisibilityDialog.tsx +++ b/src/renderer/src/components/sidebar/WorktreeVisibilityDialog.tsx @@ -363,6 +363,7 @@ export default function WorktreeVisibilityDialog(): React.JSX.Element | null { onAdd={handleAddSource} onRemove={handleRemoveSource} onToggle={handleSourceToggle} + onUseDefault={handleUseDefault} /> diff --git a/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.test.tsx b/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.test.tsx new file mode 100644 index 00000000000..13c581e95ef --- /dev/null +++ b/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.test.tsx @@ -0,0 +1,70 @@ +// @vitest-environment happy-dom + +import { act } from 'react' +import { createRoot, type Root } from 'react-dom/client' +import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest' +import type { ReactNode } from 'react' +import type { Repo } from '../../../../shared/types' +import WorktreeVisibilitySourceList from './WorktreeVisibilitySourceList' + +vi.mock('@/components/ui/tooltip', () => ({ + Tooltip: ({ children }: { children: ReactNode }) => <>{children}, + TooltipTrigger: ({ children }: { children: ReactNode }) => <>{children}, + TooltipContent: ({ children }: { children: ReactNode }) => <>{children} +})) + +let container: HTMLDivElement +let root: Root + +beforeEach(() => { + container = document.createElement('div') + document.body.appendChild(container) + root = createRoot(container) +}) + +afterEach(() => { + act(() => root.unmount()) + container.remove() +}) + +describe('WorktreeVisibilitySourceList', () => { + it('offers a reset when a project override already matches the global value', async () => { + const onUseDefault = vi.fn() + const repo: Repo = { + id: 'repo-1', + path: '/repo', + displayName: 'orca', + badgeColor: '#000000', + addedAt: 0, + worktreeVisibilitySourcePreferences: { builtIn: { claude: 'show' } } + } + act(() => { + root.render( + 'added'} + onRemove={async () => {}} + onToggle={async () => {}} + onUseDefault={onUseDefault} + /> + ) + }) + + const reset = container.querySelector( + 'button[aria-label="Use global for Claude Code"]' + ) + expect(reset).not.toBeNull() + expect(container.querySelectorAll('button[aria-label^="Use global for "]')).toHaveLength(1) + expect(reset?.closest('[data-source-row]')?.textContent).not.toContain( + 'Overriding global setting' + ) + await act(async () => reset?.click()) + + expect(onUseDefault).toHaveBeenCalledWith({ kind: 'built-in', id: 'claude' }) + }) +}) diff --git a/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.tsx b/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.tsx index 4f3bda75c9d..338db8aab53 100644 --- a/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.tsx +++ b/src/renderer/src/components/sidebar/WorktreeVisibilitySourceList.tsx @@ -57,6 +57,7 @@ type Props = { onAdd: (rootPath: string) => Promise onRemove: (source: CustomWorktreeVisibilitySource) => Promise onToggle: (source: WorktreeVisibilitySourceRow, enabled: boolean) => Promise + onUseDefault?: (source: WorktreeVisibilitySourceRow) => Promise } const EMPTY_VISIBILITY_DEFAULTS: WorktreeVisibilityDefaults = {} @@ -151,7 +152,8 @@ export default function WorktreeVisibilitySourceList({ sourceDefaultsDisabled = false, onAdd, onRemove, - onToggle + onToggle, + onUseDefault }: Props): React.JSX.Element { const customSources = useMemo( () => @@ -230,6 +232,8 @@ export default function WorktreeVisibilitySourceList({ const visibility = sourceVisibility(repo, source, visibilityDefaults, repoCustomSourceIds) const note = getWorktreeVisibilitySourceNote(provenance) const overrideNotice = getWorktreeVisibilityOverrideNotice(provenance, visibility) + const matchingOverride = + provenance?.kind === 'project-override' && provenance.globalVisibility === visibility return (
) : null} + {matchingOverride && onUseDefault ? ( + + ) : null}