import {
ChevronDown,
Cloud,
DownloadCloud,
GitBranch,
HardDrive,
Loader2,
RefreshCw,
UploadCloud,
} from "lucide-react";
import { Button } from "@/shared/ui/button";
import {
DropdownMenu,
DropdownMenuContent,
DropdownMenuItem,
DropdownMenuRadioGroup,
DropdownMenuRadioItem,
DropdownMenuTrigger,
} from "@/shared/ui/dropdown-menu";
import { PROJECT_PANEL_ACTION_BUTTON_CLASS } from "./projectPanelStyles";
/** Branch picker shared by the readme and files panel headers. */
export function RepositoryBranchDropdown({
branch,
branchOptions,
compact,
onBranchChange,
}: {
branch: string;
branchOptions: string[];
/** Smaller trigger for inline headers. */
compact?: boolean;
onBranchChange: (branch: string) => void;
}) {
const selectableBranches =
branchOptions.length > 0 ? branchOptions : [branch];
if (!branch) {
return (
—
);
}
return (
{selectableBranches.map((option) => (
{option}
))}
);
}
/** Props for the compact branch + remote/local controls in panel headers. */
export type RepoSourceHeaderControls = {
branch: string;
branchOptions: string[];
onBranchChange: (branch: string) => void;
source: "remote" | "local";
onSourceChange: (source: "remote" | "local") => void;
localDisabled: boolean;
localLabel: string;
remoteLabel: string;
/** Clones the repository when no local checkout is available. */
onCloneLocal?: () => void;
clonePending?: boolean;
/** Push of local commits, available when the local checkout is ahead. */
canPush?: boolean;
onPush?: () => void;
pushDisabled?: boolean;
pushPending?: boolean;
pushTitle?: string;
/** Fast-forward pull, available when the local checkout is behind. */
canPull?: boolean;
onPull?: () => void;
pullDisabled?: boolean;
pullPending?: boolean;
pullTitle?: string;
/** Commits the local checkout is ahead/behind the remote branch. */
aheadCount?: number | null;
behindCount?: number | null;
/** Manual sync-status refresh (runs a git fetch under the hood). */
onFetch?: () => void;
fetchPending?: boolean;
fetchTitle?: string;
};
/** Compact dropdown picking the repository source (remote or local). */
export function RepoSourceDropdown({
controls,
}: {
controls: RepoSourceHeaderControls;
}) {
const isLocal = controls.source === "local";
const cloneLocal = controls.localDisabled && controls.onCloneLocal;
const SourceIcon = isLocal ? HardDrive : Cloud;
return (
controls.onSourceChange(value === "local" ? "local" : "remote")
}
value={controls.source}
>
{controls.remoteLabel}
{!cloneLocal ? (
{controls.localLabel}
) : null}
{cloneLocal ? (
{controls.clonePending ? (
) : (
)}
{controls.localLabel}
{controls.clonePending ? "Cloning…" : "Clone"}
) : null}
);
}
/** Always-visible contextual sync button: Pull when the local checkout is
* behind, Push when ahead, otherwise Fetch to refresh the status. */
export function RepoSyncActionButton({
controls,
}: {
controls: RepoSourceHeaderControls;
}) {
const pull = controls.canPull && controls.onPull;
const push = controls.canPush && controls.onPush;
if (pull) {
const count = controls.behindCount ?? 0;
return (
);
}
if (push) {
return (
);
}
if (!controls.onFetch) return null;
return (
);
}