diff --git a/desktop/src/features/projects/ui/ProjectDetailScreen.tsx b/desktop/src/features/projects/ui/ProjectDetailScreen.tsx index addabcd55..ef68ae26f 100644 --- a/desktop/src/features/projects/ui/ProjectDetailScreen.tsx +++ b/desktop/src/features/projects/ui/ProjectDetailScreen.tsx @@ -843,36 +843,6 @@ export function ProjectDetailScreen(props: ProjectDetailScreenProps) {
- - {repoRemote.webUrl && - (repoRemote.host.kind !== "external" || - repoSource === "local") ? ( - - ) : null} - - } activeTabCrumb={activeTabCrumb} activeWorkItemCrumb={activeWorkItemCrumb} chromeRef={projectDetailHeaderChromeRef} @@ -932,6 +902,36 @@ export function ProjectDetailScreen(props: ProjectDetailScreenProps) { onSelectedTabChange={setActiveTab} profiles={profiles} project={repository} + repositoryControls={ + <> + + {repoRemote.webUrl && + (repoRemote.host.kind !== "external" || + repoSource === "local") ? ( + + ) : null} + + } projectId={project.id} repoDiff={displayedRepoDiff} repoDiffError={displayedRepoDiffError} diff --git a/desktop/src/features/projects/ui/ProjectOverviewPanel.tsx b/desktop/src/features/projects/ui/ProjectOverviewPanel.tsx index 0cb06b3e9..9f56f9752 100644 --- a/desktop/src/features/projects/ui/ProjectOverviewPanel.tsx +++ b/desktop/src/features/projects/ui/ProjectOverviewPanel.tsx @@ -36,6 +36,8 @@ type ProjectOverviewPanelProps = { externalUrl?: string | null; files: ProjectRepoFile[]; gitDataState: GitDataState; + /** Hide the readme header rows when the workspace renders them itself. */ + hideReadmeHeader?: boolean; project: Project; onViewContributors: () => void; profiles?: UserProfileLookup; @@ -149,6 +151,7 @@ export function ProjectOverviewPanel({ externalUrl, files, gitDataState, + hideReadmeHeader, onViewContributors, project, profiles, @@ -182,6 +185,7 @@ export function ProjectOverviewPanel({ externalUrl={externalUrl} file={readmeFile} gitDataState={gitDataState} + hideHeader={hideReadmeHeader} sourceControls={sourceControls} unavailableReason={unavailableReason} /> diff --git a/desktop/src/features/projects/ui/ProjectReadmePanel.tsx b/desktop/src/features/projects/ui/ProjectReadmePanel.tsx index c398f1292..3519f5ea7 100644 --- a/desktop/src/features/projects/ui/ProjectReadmePanel.tsx +++ b/desktop/src/features/projects/ui/ProjectReadmePanel.tsx @@ -140,6 +140,7 @@ export function ReadmePanel({ gitDataState, externalHost, externalUrl, + hideHeader, sourceControls, unavailableReason, }: { @@ -149,13 +150,18 @@ export function ReadmePanel({ gitDataState: "checking" | "available" | "empty" | "unavailable"; externalHost?: string; externalUrl?: string | null; + /** + * Skip the header rows entirely — the workspace layout renders the source + * controls and last-changed timestamp itself. + */ + hideHeader?: boolean; unavailableReason?: ProjectRepoUnavailableReason; /** Branch picker + remote/local toggle rendered in the panel header. */ sourceControls?: RepoSourceHeaderControls; }) { // Two header rows, mirroring the files panel: controls on top, then the // file identity row. - const header = ( + const header = hideHeader ? null : ( <> {sourceControls ? (
@@ -163,7 +169,6 @@ export function ReadmePanel({ @@ -98,7 +103,7 @@ export function ProjectRepositoryPicker({ @@ -229,7 +225,7 @@ export function RepoSourceDropdown({ - ) : null} - {updatePullRequestAction ? ( - - ) : null} -
- ) : null} - {selectedPullRequest ? ( -
- {/* Two full-height columns: the meta rail runs all the way to the + {/* Single workspace box: selection header (repository / source / + branch), then the tab strip, then the active panel. Inner panels + keep their own PROJECT_DETAIL_PANEL_CLASS for standalone use, so + their border + radius are neutralized here via the data attribute + they all carry. */} +
+ {repositoryControls || sourceControls ? ( +
+ {repositoryControls} + {sourceControls ? ( + <> + + +
+ +
+ + ) : null} +
+ ) : null} + {repositoryLoaded ? ( +
+ + {onOpenTerminal ? ( + + ) : null} + {updatePullRequestAction ? ( + + ) : null} + {selectedTab === "overview" && readmeFile ? ( + + Last changed {formatLastChangedAt(readmeFile.lastChangedAt)} + + ) : null} +
+ ) : null} + {selectedPullRequest ? ( +
+ {/* Two full-height columns: the meta rail runs all the way to the top of the card, alongside the header and tabs. */} -
-
- -
- +
+ -
- {(["conversation", "commits", "checks"] as const).map((mode) => ( - - + +
+ {(["conversation", "commits", "checks"] as const).map( + (mode) => ( + + + + ), + )} + + - ))} - - - -
- -
-
- ) : null} - - - setSelectedTab("contributors")} - profiles={profiles} - project={project} - pullRequests={pullRequests} - readmeFile={readmeFile} - snapshot={displayedSnapshot} - sourceControls={sourceControls} - unavailableReason={unavailableReason} - /> - - - - {selectedCommitHash ? ( - commit.hash === selectedCommitHash, - ) ?? null - } - commitAuthorPubkeys={commitAuthorPubkeys} - commitHash={selectedCommitHash} - viewerGitIdentity={viewerGitIdentity} - diff={commitDiff} - diffError={commitDiffError} - diffLoading={commitDiffLoading} - originAgentName={selectedCommitPullRequest?.originAgentName} - originChannelId={selectedCommitPullRequest?.channelId} - profiles={profiles} - /> - ) : ( - onSelectedCommitHashChange(commit.hash)} - profiles={profiles} - pullRequests={pullRequests} - repoContributors={displayedContributors} - snapshot={displayedSnapshot} - viewerGitIdentity={viewerGitIdentity} - /> - )} - - - - setCreatePullRequestOpen(true)} - title="Pull Requests" - /> - - - - - setCreateIssueOpen(true)} - title="Issues" - /> - - - - - {repoSource === "local" && !localSnapshot && !localSnapshotLoading ? ( -
-
- No local checkout found. +
+
) : null} - - - - - + + setSelectedTab("contributors")} + profiles={profiles} + project={project} + pullRequests={pullRequests} + readmeFile={readmeFile} + snapshot={displayedSnapshot} + sourceControls={sourceControls} + unavailableReason={unavailableReason} + /> + + + + {selectedCommitHash ? ( + commit.hash === selectedCommitHash, + ) ?? null + } + commitAuthorPubkeys={commitAuthorPubkeys} + commitHash={selectedCommitHash} + viewerGitIdentity={viewerGitIdentity} + diff={commitDiff} + diffError={commitDiffError} + diffLoading={commitDiffLoading} + originAgentName={selectedCommitPullRequest?.originAgentName} + originChannelId={selectedCommitPullRequest?.channelId} + profiles={profiles} + /> + ) : ( + + onSelectedCommitHashChange(commit.hash) + } + profiles={profiles} + pullRequests={pullRequests} + repoContributors={displayedContributors} + snapshot={displayedSnapshot} + viewerGitIdentity={viewerGitIdentity} + /> + )} + + + + setCreatePullRequestOpen(true)} + title="Pull Requests" + /> + + + + + setCreateIssueOpen(true)} + title="Issues" + /> + + + + + {repoSource === "local" && !localSnapshot && !localSnapshotLoading ? ( +
+
+ No local checkout found. +
+
+ ) : null} + +
+ + + + +
{createPullRequestAction && createPullRequestOpen ? (