"use client"; import { PanelHeaderBarSplit } from "./panel-primitives"; import type { GitCredentialDisplay } from "./changes-git-credential-display"; import type { RemoteContributionRelation } from "@/hooks/domains/session/remote-contribution-relation"; import type { ContributionHistoryExplanationTarget } from "@/hooks/domains/session/use-contribution-history-explanation"; import { type RemoteContributionResolutionTarget, type useRemoteContributionResolution, } from "./use-remote-contribution-resolution"; import { RemoteContributionHeaderActions } from "./remote-contribution-header-actions"; import { buildBranchRows, type PerRepoStatus } from "./changes-panel-branch-rows"; import { BranchHoverCard, ChangesPanelHeaderLeft, ChangesPanelHeaderOverflowActions, PullDropdown, } from "./changes-panel-header-actions"; import type { RenameBranchResult } from "./changes-panel-header-actions"; export { PullDropdown } from "./changes-panel-header-actions"; export type { PerRepoStatus } from "./changes-panel-branch-rows"; function buildHeaderBranchRows(props: ChangesPanelHeaderProps) { return buildBranchRows( props.perRepoStatus, props.baseBranchByRepo, props.baseBranchDisplay, props.repoDisplayName, ); } type ChangesPanelHeaderProps = { hasChanges: boolean; hasCommits: boolean; hasPRFiles?: boolean; displayBranch: string | null; baseBranchDisplay: string; /** Per-repo merge target, keyed by repository_name. Undefined entries fall * back to baseBranchDisplay. Empty/missing for single-repo workspaces. */ baseBranchByRepo?: Record; behindCount: number; pullDisabled?: boolean; pullDisabledReason?: string; isLoading: boolean; loadingOperation: string | null; onOpenDiffAll?: () => void; onOpenReview?: () => void; onRequestWalkthrough?: () => void; requestWalkthroughDisabled?: boolean; /** Always non-empty (single-repo includes the empty-name entry). */ repoNames: string[]; perRepoStatus: PerRepoStatus[]; onRepoPull: (repo: string) => void; onRepoRebase: (repo: string) => void; onRepoMerge: (repo: string) => void; onRenameBranch?: (newName: string, repo: string) => Promise; credentialDisplay: GitCredentialDisplay | null; comparisonTargets: string[]; repoDisplayName?: (repositoryName: string) => string | undefined; /** Active task id; piped into the base-branch picker so it can resolve * the right task_repositories row to PATCH. Null while task data is * hydrating — the picker falls back to a static label. */ taskId: string | null; relation?: RemoteContributionRelation; contributionHistoryTarget?: ContributionHistoryExplanationTarget | null; resolution?: ReturnType; resolutionTarget?: RemoteContributionResolutionTarget | null; remoteContributionUrl?: string; remoteContributionNumber?: number; }; function ChangesPanelHeaderRight({ props, branchRows, }: { props: ChangesPanelHeaderProps; branchRows: ReturnType; }) { const { displayBranch, baseBranchDisplay, taskId, onRenameBranch, loadingOperation, credentialDisplay, comparisonTargets, relation, contributionHistoryTarget, resolution, resolutionTarget, remoteContributionUrl, remoteContributionNumber, behindCount, pullDisabled, pullDisabledReason, isLoading, repoNames, perRepoStatus, onRepoPull, onRepoRebase, onRepoMerge, repoDisplayName, } = props; return ( <> {(displayBranch || branchRows.length > 0) && ( )} ); } export function ChangesPanelHeader(props: ChangesPanelHeaderProps) { const { hasChanges, hasCommits, hasPRFiles, onOpenDiffAll, onOpenReview, onRequestWalkthrough, requestWalkthroughDisabled, } = props; const branchRows = buildHeaderBranchRows(props); const showDiffReview = hasChanges || hasCommits || !!hasPRFiles; return ( } leftWhenOverflow={ } right={} overflow={ } overflowAt={520} hideLeftWhenOverflow hideRightWhenOverflow={false} /> ); }