From 480c19f5f0acf6b0d655904a25517bd86e2da748 Mon Sep 17 00:00:00 2001 From: Neil <4138956+nwparker@users.noreply.github.com> Date: Thu, 16 Apr 2026 20:55:10 -0700 Subject: [PATCH] fix: pinned 'Add folder/repo' footer in repo combobox (#741) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Changed 'repositories' → 'repos/folders' in search placeholder and empty state - Added always-visible 'Add folder/repo' button with FolderPlus icon in popover footer - Button calls existing addRepo store action (same folder picker flow) - Auto-selects newly added repo on success - Made Command controlled to clear selection highlight when hovering footer --- .../src/components/repo/RepoCombobox.tsx | 52 +++++++++++++++++-- 1 file changed, 48 insertions(+), 4 deletions(-) diff --git a/src/renderer/src/components/repo/RepoCombobox.tsx b/src/renderer/src/components/repo/RepoCombobox.tsx index 6c520a7e722..e7b39f0d2a6 100644 --- a/src/renderer/src/components/repo/RepoCombobox.tsx +++ b/src/renderer/src/components/repo/RepoCombobox.tsx @@ -1,5 +1,5 @@ import React, { useCallback, useMemo, useState } from 'react' -import { Check, ChevronsUpDown, Globe } from 'lucide-react' +import { Check, ChevronsUpDown, FolderPlus, Globe } from 'lucide-react' import { Button } from '@/components/ui/button' import { Command, @@ -9,6 +9,8 @@ import { CommandList } from '@/components/ui/command' import { Popover, PopoverContent, PopoverTrigger } from '@/components/ui/popover' +import { useAppStore } from '@/store' +import { isGitRepoKind } from '../../../../shared/repo-kind' import { searchRepos } from '@/lib/repo-search' import { cn } from '@/lib/utils' import type { Repo } from '../../../../shared/types' @@ -31,6 +33,13 @@ export default function RepoCombobox({ }: RepoComboboxProps): React.JSX.Element { const [open, setOpen] = useState(false) const [query, setQuery] = useState('') + // Why: controlled cmdk selection so hovering the footer (which lives outside + // the cmdk tree) can clear the list's highlighted item — otherwise cmdk keeps + // the last-hovered repo visually selected while the mouse is on the footer. + const [commandValue, setCommandValue] = useState('') + const addRepo = useAppStore((s) => s.addRepo) + const fetchWorktrees = useAppStore((s) => s.fetchWorktrees) + const [isAdding, setIsAdding] = useState(false) const selectedRepo = useMemo( () => repos.find((repo) => repo.id === value) ?? null, @@ -57,6 +66,26 @@ export default function RepoCombobox({ [onValueChange] ) + const handleAddFolder = useCallback(async () => { + if (isAdding) { + return + } + setIsAdding(true) + try { + const repo = await addRepo() + if (repo) { + if (isGitRepoKind(repo)) { + await fetchWorktrees(repo.id) + } + onValueChange(repo.id) + setOpen(false) + setQuery('') + } + } finally { + setIsAdding(false) + } + }, [addRepo, fetchWorktrees, isAdding, onValueChange]) + return ( @@ -93,15 +122,15 @@ export default function RepoCombobox({ className="w-[var(--radix-popover-trigger-width)] p-0" data-repo-combobox-root="true" > - + - No repositories match your search. + No repos/folders match your search. {filteredRepos.map((repo) => ( ))} + {/* Why: pinned footer (outside CommandList's scroll container) so the + add action stays visible regardless of list length or scroll position. */} +
+ +