import { Command, CommandEmpty, CommandGroup, CommandInput, CommandItem, CommandList, } from "@/components/ui/command"; import { Popover, PopoverContent, PopoverTrigger, } from "@/components/ui/popover"; import { Button } from "@/components/ui/button"; import { Check, ChevronsUpDown } from "lucide-react"; import { cn } from "@/lib/utils"; import { useState, useEffect } from "react"; import { useGitHubAppProvider } from "@/providers/GitHubApp"; import { GitBranch, Shield } from "lucide-react"; import { TargetRepository } from "@open-swe/shared/open-swe/types"; interface BranchSelectorProps { disabled?: boolean; placeholder?: string; buttonClassName?: string; chatStarted?: boolean; streamTargetRepository?: TargetRepository; } export function BranchSelector({ disabled = false, placeholder = "Select a branch...", buttonClassName, chatStarted = false, streamTargetRepository, }: BranchSelectorProps) { const [open, setOpen] = useState(false); const { branches, branchesLoading, branchesError, selectedBranch, setSelectedBranch, selectedRepository, branchesHasMore, branchesLoadingMore, loadMoreBranches, defaultBranch, } = useGitHubAppProvider(); // Auto-select default branch when repository changes and branches are loaded useEffect(() => { if ( selectedRepository && !branchesLoading && !branchesError && branches.length > 0 ) { // Check if the current selected branch exists in the new repository const currentBranchExists = selectedBranch && branches.some((branch) => branch.name === selectedBranch); // Auto-select default branch if no branch is selected OR if the selected branch doesn't exist in this repo if (!selectedBranch || !currentBranchExists) { // Try to find the repository's actual default branch first const actualDefaultBranch = defaultBranch ? branches.find((branch) => branch.name === defaultBranch) : null; if (actualDefaultBranch) { setSelectedBranch(actualDefaultBranch.name); } else if (branches.length > 0) { // If default branch doesn't exist in branches list, select the first available branch setSelectedBranch(branches[0].name); } } } }, [ selectedRepository?.owner, selectedRepository?.repo, branchesLoading, branchesError, branches.length, selectedBranch, setSelectedBranch, defaultBranch, ]); const handleSelect = (branchName: string) => { setSelectedBranch(branchName); setOpen(false); }; if (!selectedRepository) { return ( ); } if (branchesLoading) { return ( ); } if (branchesError) { return ( ); } if (branches.length === 0) { return ( ); } // Determine the display value - prioritize stream data when chatStarted and available const displayValue = chatStarted && streamTargetRepository?.branch ? streamTargetRepository.branch : selectedBranch; if (chatStarted) { return ( ); } return ( No branches found. {branches .slice() .sort((a, b) => { if (defaultBranch) { if (a.name === defaultBranch) return -1; if (b.name === defaultBranch) return 1; } return 0; }) .map((branch) => { const isSelected = selectedBranch === branch.name; const isDefault = branch.name === defaultBranch; return ( handleSelect(branch.name)} >
{branch.name} {isDefault && ( default )} {branch.protected && (
)}
); })}
{branchesHasMore && ( { loadMoreBranches(); }} disabled={branchesLoadingMore} className="justify-center" > {branchesLoadingMore ? "Loading more..." : "Load more branches"} )}
); }