diff --git a/src/renderer/components/sidebar/DateGroupedSessions.tsx b/src/renderer/components/sidebar/DateGroupedSessions.tsx index f55b1f24..b2d99211 100644 --- a/src/renderer/components/sidebar/DateGroupedSessions.tsx +++ b/src/renderer/components/sidebar/DateGroupedSessions.tsx @@ -38,6 +38,7 @@ import { useShallow } from 'zustand/react/shallow'; import { WorktreeBadge } from '../common/WorktreeBadge'; import { Combobox, type ComboboxOption } from '../ui/combobox'; +import { resolveEffectiveSelectedRepositoryId } from './dateGroupedSessionsSelection'; import { SESSION_PROVIDER_IDS, SessionFiltersPopover } from './SessionFiltersPopover'; import { SessionItem } from './SessionItem'; @@ -327,21 +328,15 @@ export const DateGroupedSessions = (): React.JSX.Element => { const effectiveSelectedWorktreeId = selectedWorktreeId ?? activeProjectId ?? selectedProjectId ?? null; - const effectiveSelectedRepositoryId = useMemo(() => { - if (selectedRepositoryId) { - return selectedRepositoryId; - } - - if (!effectiveSelectedWorktreeId) { - return null; - } - - return ( - repositoryGroups.find((repo) => - repo.worktrees.some((worktree) => worktree.id === effectiveSelectedWorktreeId) - )?.id ?? null - ); - }, [effectiveSelectedWorktreeId, repositoryGroups, selectedRepositoryId]); + const effectiveSelectedRepositoryId = useMemo( + () => + resolveEffectiveSelectedRepositoryId({ + repositoryGroups, + selectedRepositoryId, + effectiveSelectedWorktreeId, + }), + [effectiveSelectedWorktreeId, repositoryGroups, selectedRepositoryId] + ); const activeProjectValue = viewMode === 'grouped' diff --git a/src/renderer/components/sidebar/dateGroupedSessionsSelection.ts b/src/renderer/components/sidebar/dateGroupedSessionsSelection.ts new file mode 100644 index 00000000..4c0e806d --- /dev/null +++ b/src/renderer/components/sidebar/dateGroupedSessionsSelection.ts @@ -0,0 +1,27 @@ +import type { RepositoryGroup } from '@renderer/types/data'; + +interface ResolveEffectiveSelectedRepositoryIdInput { + repositoryGroups: readonly RepositoryGroup[]; + selectedRepositoryId: string | null; + effectiveSelectedWorktreeId: string | null; +} + +export function resolveEffectiveSelectedRepositoryId({ + repositoryGroups, + selectedRepositoryId, + effectiveSelectedWorktreeId, +}: ResolveEffectiveSelectedRepositoryIdInput): string | null { + if (selectedRepositoryId) { + return selectedRepositoryId; + } + + if (!effectiveSelectedWorktreeId) { + return null; + } + + return ( + repositoryGroups.find((repo) => + repo.worktrees.some((worktree) => worktree.id === effectiveSelectedWorktreeId) + )?.id ?? null + ); +} diff --git a/test/renderer/components/sidebar/dateGroupedSessionsSelection.test.ts b/test/renderer/components/sidebar/dateGroupedSessionsSelection.test.ts new file mode 100644 index 00000000..63fda15d --- /dev/null +++ b/test/renderer/components/sidebar/dateGroupedSessionsSelection.test.ts @@ -0,0 +1,53 @@ +import { describe, expect, it } from 'vitest'; + +import { resolveEffectiveSelectedRepositoryId } from '../../../../src/renderer/components/sidebar/dateGroupedSessionsSelection'; + +describe('resolveEffectiveSelectedRepositoryId', () => { + it('falls back to the repository that owns the active worktree when repository selection is empty', () => { + const repositoryGroups = [ + { + id: 'repo-headless', + worktrees: [ + { + id: 'worktree-headless', + path: '/Users/belief/dev/projects/headless', + }, + ], + }, + { + id: 'repo-other', + worktrees: [ + { + id: 'worktree-other', + path: '/Users/belief/dev/projects/other', + }, + ], + }, + ] as const; + + expect( + resolveEffectiveSelectedRepositoryId({ + repositoryGroups, + selectedRepositoryId: null, + effectiveSelectedWorktreeId: 'worktree-headless', + }) + ).toBe('repo-headless'); + }); + + it('keeps the explicit repository selection when it already exists', () => { + const repositoryGroups = [ + { + id: 'repo-headless', + worktrees: [{ id: 'worktree-headless', path: '/Users/belief/dev/projects/headless' }], + }, + ] as const; + + expect( + resolveEffectiveSelectedRepositoryId({ + repositoryGroups, + selectedRepositoryId: 'repo-headless', + effectiveSelectedWorktreeId: 'worktree-headless', + }) + ).toBe('repo-headless'); + }); +});