"use client"; import { PanelBody } from "./panel-primitives"; import { DiscardDialog, AmendDialog, ResetDialog } from "./changes-panel-dialogs"; import { FileListSection, CommitsSection, ReviewProgressBar, PRFilesSection, } from "./changes-panel-timeline"; import { mergeCommits, firstVisibleSection } from "./changes-panel-helpers"; import type { ChangesPanelBodyProps } from "./changes-panel-data"; function ChangesPanelDialogsSection({ dialogs, isLoading, }: Pick) { return ( <> ); } type TimelineProps = Pick< ChangesPanelBodyProps, | "hasAnything" | "hasUnstaged" | "hasStaged" | "hasCommits" | "hasPRFiles" | "canPush" | "canCreatePR" | "existingPrUrl" | "unstagedFiles" | "stagedFiles" | "prFiles" | "prCommits" | "commits" | "pendingStageFiles" | "aheadCount" | "isLoading" | "loadingOperation" | "dialogs" | "onOpenDiffFile" | "onEditFile" | "onOpenCommitDetail" | "onRevertCommit" | "onStageAll" | "onUnstageAll" | "onStage" | "onUnstage" | "onBulkStage" | "onBulkUnstage" | "onBulkDiscard" | "onPush" | "onForcePush" | "onRepoStageAll" | "onRepoUnstageAll" | "onRepoCommit" | "onRepoPush" | "onRepoCreatePR" | "repoDisplayName" | "perRepoStatus" | "prByRepo" >; type WorkingTreeProps = Pick< TimelineProps, | "hasUnstaged" | "hasStaged" | "unstagedFiles" | "stagedFiles" | "pendingStageFiles" | "loadingOperation" | "dialogs" | "onOpenDiffFile" | "onEditFile" | "onStageAll" | "onUnstageAll" | "onStage" | "onUnstage" | "onBulkStage" | "onBulkUnstage" | "onBulkDiscard" | "onRepoStageAll" | "onRepoUnstageAll" | "onRepoCommit" | "repoDisplayName" > & { isLastUnstaged: boolean; isLastStaged: boolean }; function WorkingTreeSections(props: WorkingTreeProps) { const isBulkOp = props.pendingStageFiles.size === 0; return ( <> {props.hasUnstaged && ( )} {props.hasStaged && ( props.dialogs.openCommitDialog()} secondaryActionLabel="Unstage all" isSecondaryActionLoading={isBulkOp && props.loadingOperation === "unstage"} onSecondaryAction={props.onUnstageAll} onOpenDiff={props.onOpenDiffFile} onEditFile={props.onEditFile} onStage={props.onStage} onUnstage={props.onUnstage} onDiscard={props.dialogs.handleDiscardClick} onBulkUnstage={props.onBulkUnstage} onBulkDiscard={props.onBulkDiscard} onRepoAction={props.onRepoCommit} onRepoSecondaryAction={props.onRepoUnstageAll} repoDisplayName={props.repoDisplayName} /> )} ); } function ChangesPanelTimeline(props: TimelineProps) { if (!props.hasAnything) { return (
Your changed files will appear here
); } const mergedCommits = mergeCommits(props.commits, props.prCommits); const hasMergedCommits = mergedCommits.length > 0; const hasLocalChanges = props.hasUnstaged || props.hasStaged; const showCommits = props.hasStaged || props.hasCommits; const showCommitsList = props.hasStaged || hasMergedCommits; const hasSomethingAfterStaged = (props.hasPRFiles && hasLocalChanges) || showCommitsList; // Auto-expand the first (topmost) visible section so the panel never opens // looking empty (e.g. review mode: PR + Commits both collapsed). Unstaged / // Staged keep their always-expanded default; PR and Commits are gated. Large // PR diffs (>5 files) skip PR Changes and expand Commits instead. const firstSection = firstVisibleSection({ hasPRFiles: props.hasPRFiles, hasUnstaged: props.hasUnstaged, hasStaged: props.hasStaged, showCommitsList, prFileCount: props.prFiles.length, }); return (
{props.hasPRFiles && !hasLocalChanges && (
)} {props.hasPRFiles && hasLocalChanges && (
)} {showCommitsList && ( )}
); } export function ChangesPanelBody(props: ChangesPanelBodyProps) { return (
); }