Skip to content

Commit f40c691

Browse files
feat(web): add History tab to bottom panel with latest-commit summary
Adds a new History tab to the bottom panel alongside Explore. The tab is toggled via shift+mod+h with the existing collapse-on-same/switch-on-other semantics, and the active tab is indicated with an underline using LowProfileTabsTrigger (now accepts an optional className). The history panel itself is a client-side infinite-scroll list (react-query useInfiniteQuery + IntersectionObserver) that hits a new client-side listCommits wrapper. Each row reuses AuthorsAvatarGroup, the co-author parsing, and the new shared CommitActionLink primitive for the view-code-at-commit / view-repo-at-commit actions. CommitRow was refactored to use the same primitive. The previous CommitHeader rendered above each open file is removed. A compact summary of the latest commit now appears in the bottom panel header (right side) whenever the panel is collapsed, so the file/folder's last commit stays glanceable without consuming a full row above the code. When the panel is expanded the right side hosts the View-full-history and Hide buttons. Shared commit utilities (commitAuthors.ts, commitParts.tsx) moved up from browse/[...path]/components/ to browse/components/ so both the existing commits view and the new bottom-panel components import them without crossing route boundaries. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent f57f552 commit f40c691

14 files changed

Lines changed: 474 additions & 191 deletions

File tree

packages/web/src/app/(app)/browse/[...path]/components/codePreviewPanel.tsx

Lines changed: 2 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,7 @@ import { Separator } from "@/components/ui/separator";
44
import { cn, getCodeHostInfoForRepo, isServiceError } from "@/lib/utils";
55
import Image from "next/image";
66
import { PureCodePreviewPanel } from "./pureCodePreviewPanel";
7-
import { CommitHeader } from "./commitHeader";
8-
import { getFileSource, listCommits } from '@/features/git';
7+
import { getFileSource } from '@/features/git';
98

109
interface CodePreviewPanelProps {
1110
path: string;
@@ -14,19 +13,13 @@ interface CodePreviewPanelProps {
1413
}
1514

1615
export const CodePreviewPanel = async ({ path, repoName, revisionName }: CodePreviewPanelProps) => {
17-
const [fileSourceResponse, repoInfoResponse, commitsResponse] = await Promise.all([
16+
const [fileSourceResponse, repoInfoResponse] = await Promise.all([
1817
getFileSource({
1918
path,
2019
repo: repoName,
2120
ref: revisionName,
2221
}, { source: 'sourcebot-web-client' }),
2322
getRepoInfoByName(repoName),
24-
listCommits({
25-
repo: repoName,
26-
path,
27-
ref: revisionName,
28-
maxCount: 1,
29-
}),
3023
]);
3124

3225
if (isServiceError(fileSourceResponse)) {
@@ -37,8 +30,6 @@ export const CodePreviewPanel = async ({ path, repoName, revisionName }: CodePre
3730
return <div>Error loading repo info: {repoInfoResponse.message}</div>
3831
}
3932

40-
const latestCommit = !isServiceError(commitsResponse) ? commitsResponse.commits[0] : undefined;
41-
4233
const codeHostInfo = getCodeHostInfoForRepo({
4334
codeHostType: repoInfoResponse.codeHostType,
4435
name: repoInfoResponse.name,
@@ -83,17 +74,6 @@ export const CodePreviewPanel = async ({ path, repoName, revisionName }: CodePre
8374
)}
8475
</div>
8576
<Separator />
86-
{latestCommit && (
87-
<>
88-
<CommitHeader
89-
commit={latestCommit}
90-
repoName={repoName}
91-
path={path}
92-
revisionName={revisionName}
93-
/>
94-
<Separator />
95-
</>
96-
)}
9777
<PureCodePreviewPanel
9878
source={fileSourceResponse.source}
9979
language={fileSourceResponse.language}

packages/web/src/app/(app)/browse/[...path]/components/commitHeader.tsx

Lines changed: 0 additions & 79 deletions
This file was deleted.

packages/web/src/app/(app)/browse/[...path]/components/commitRow.tsx

Lines changed: 17 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,17 @@
33
import { useCallback, useMemo, useState } from "react";
44
import { formatDistanceToNow } from "date-fns";
55
import { Code, FileCode } from "lucide-react";
6-
import Link from "next/link";
7-
import { Button } from "@/components/ui/button";
8-
import { Tooltip, TooltipContent, TooltipTrigger } from "@/components/ui/tooltip";
96
import { CopyIconButton } from "@/app/(app)/components/copyIconButton";
107
import { useToast } from "@/components/hooks/use-toast";
118
import type { Commit } from "@/features/git";
129
import { getBrowsePath } from "../../hooks/utils";
13-
import { formatAuthorsText, getCommitAuthors } from "./commitAuthors";
14-
import { AuthorsAvatarGroup, CommitBody, CommitBodyToggle } from "./commitParts";
10+
import { formatAuthorsText, getCommitAuthors } from "../../components/commitAuthors";
11+
import {
12+
AuthorsAvatarGroup,
13+
CommitActionLink,
14+
CommitBody,
15+
CommitBodyToggle,
16+
} from "../../components/commitParts";
1517

1618
interface CommitRowProps {
1719
commit: Commit;
@@ -81,27 +83,17 @@ export const CommitRow = ({ commit, repoName, path }: CommitRowProps) => {
8183
</span>
8284
<CopyIconButton onCopy={onCopySha} />
8385
{hasFilePath && (
84-
<Tooltip>
85-
<TooltipTrigger asChild>
86-
<Button asChild variant="ghost" size="sm" className="h-6 w-6 text-muted-foreground">
87-
<Link href={viewFileAtCommitHref} aria-label="View code at this commit">
88-
<FileCode className="h-3 w-3" />
89-
</Link>
90-
</Button>
91-
</TooltipTrigger>
92-
<TooltipContent>View code at this commit</TooltipContent>
93-
</Tooltip>
86+
<CommitActionLink
87+
href={viewFileAtCommitHref}
88+
label="View code at this commit"
89+
icon={<FileCode className="h-3 w-3" />}
90+
/>
9491
)}
95-
<Tooltip>
96-
<TooltipTrigger asChild>
97-
<Button asChild variant="ghost" size="sm" className="h-6 w-6 text-muted-foreground">
98-
<Link href={viewRepoAtCommitHref} aria-label="View repository at this commit">
99-
<Code className="h-3 w-3" />
100-
</Link>
101-
</Button>
102-
</TooltipTrigger>
103-
<TooltipContent>View repository at this commit</TooltipContent>
104-
</Tooltip>
92+
<CommitActionLink
93+
href={viewRepoAtCommitHref}
94+
label="View repository at this commit"
95+
icon={<Code className="h-3 w-3" />}
96+
/>
10597
</div>
10698
</div>
10799
{hasBody && isBodyExpanded && (

packages/web/src/app/(app)/browse/[...path]/components/commitsPanel.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { Separator } from "@/components/ui/separator";
66
import { listCommitAuthors, listCommits } from "@/features/git";
77
import { isServiceError } from "@/lib/utils";
88
import { AuthorFilter } from "./authorFilter";
9-
import { dedupeCommitAuthorsByEmail, escapeGitBreLiteral } from "./commitAuthors";
9+
import { dedupeCommitAuthorsByEmail, escapeGitBreLiteral } from "../../components/commitAuthors";
1010
import { CommitRow } from "./commitRow";
1111
import { CommitsPagination } from "./commitsPagination";
1212
import { DateFilter } from "./dateFilter";

packages/web/src/app/(app)/browse/browseStateProvider.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ export interface BrowseState {
1414
isFileTreePanelCollapsed: boolean;
1515
isFileSearchOpen: boolean;
1616
activeExploreMenuTab: "references" | "definitions";
17+
activeBottomPanelTab: "explore" | "history";
1718
bottomPanelSize: number;
1819
}
1920

@@ -23,6 +24,7 @@ const defaultState: BrowseState = {
2324
isFileTreePanelCollapsed: false,
2425
isFileSearchOpen: false,
2526
activeExploreMenuTab: "references",
27+
activeBottomPanelTab: "history",
2628
bottomPanelSize: 35,
2729
};
2830

0 commit comments

Comments
 (0)