Skip to content

Commit a698afd

Browse files
fix(web): Change buttons into Links in various places (#532)
1 parent ef46c01 commit a698afd

File tree

8 files changed

+124
-132
lines changed

8 files changed

+124
-132
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
1717
- Improved repository query performance by adding db indices. [#526](https://github.com/sourcebot-dev/sourcebot/pull/526)
1818
- Improved repository query performance by removing JOIN on `Connection` table. [#527](https://github.com/sourcebot-dev/sourcebot/pull/527)
1919
- Changed repo carousel and repo list links to redirect to the file browser. [#528](https://github.com/sourcebot-dev/sourcebot/pull/528)
20+
- Changed file headers, files/directories in file tree, and reference list buttons into links. [#532](https://github.com/sourcebot-dev/sourcebot/pull/532)
2021

2122
## [4.7.1] - 2025-09-19
2223

packages/web/src/app/[domain]/browse/[...path]/components/pureTreePreviewPanel.tsx

Lines changed: 12 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,22 @@
11
'use client';
22

3-
import { useCallback, useRef } from "react";
3+
import { useRef } from "react";
44
import { FileTreeItem } from "@/features/fileTree/actions";
55
import { FileTreeItemComponent } from "@/features/fileTree/components/fileTreeItemComponent";
6-
import { useBrowseNavigation } from "../../hooks/useBrowseNavigation";
6+
import { getBrowsePath } from "../../hooks/useBrowseNavigation";
77
import { ScrollArea } from "@/components/ui/scroll-area";
88
import { useBrowseParams } from "../../hooks/useBrowseParams";
9+
import { useDomain } from "@/hooks/useDomain";
910

1011
interface PureTreePreviewPanelProps {
1112
items: FileTreeItem[];
1213
}
1314

1415
export const PureTreePreviewPanel = ({ items }: PureTreePreviewPanelProps) => {
1516
const { repoName, revisionName } = useBrowseParams();
16-
const { navigateToPath } = useBrowseNavigation();
1717
const scrollAreaRef = useRef<HTMLDivElement>(null);
18-
19-
const onNodeClicked = useCallback((node: FileTreeItem) => {
20-
navigateToPath({
21-
repoName: repoName,
22-
revisionName: revisionName,
23-
path: node.path,
24-
pathType: node.type === 'tree' ? 'tree' : 'blob',
25-
});
26-
}, [navigateToPath, repoName, revisionName]);
27-
18+
const domain = useDomain();
19+
2820
return (
2921
<ScrollArea
3022
className="flex flex-col p-0.5"
@@ -37,8 +29,14 @@ export const PureTreePreviewPanel = ({ items }: PureTreePreviewPanelProps) => {
3729
isActive={false}
3830
depth={0}
3931
isCollapseChevronVisible={false}
40-
onClick={() => onNodeClicked(item)}
4132
parentRef={scrollAreaRef}
33+
href={getBrowsePath({
34+
repoName,
35+
revisionName,
36+
path: item.path,
37+
pathType: item.type === 'tree' ? 'tree' : 'blob',
38+
domain,
39+
})}
4240
/>
4341
))}
4442
</ScrollArea>

packages/web/src/app/[domain]/components/pathHeader.tsx

Lines changed: 31 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import { cn, getCodeHostInfoForRepo } from "@/lib/utils";
44
import { LaptopIcon } from "@radix-ui/react-icons";
55
import Image from "next/image";
6-
import { useBrowseNavigation } from "../browse/hooks/useBrowseNavigation";
6+
import { getBrowsePath } from "../browse/hooks/useBrowseNavigation";
77
import { ChevronRight, MoreHorizontal } from "lucide-react";
88
import { useCallback, useState, useMemo, useRef, useEffect } from "react";
99
import { useToast } from "@/components/hooks/use-toast";
@@ -15,6 +15,8 @@ import {
1515
} from "@/components/ui/dropdown-menu";
1616
import { VscodeFileIcon } from "@/app/components/vscodeFileIcon";
1717
import { CopyIconButton } from "./copyIconButton";
18+
import Link from "next/link";
19+
import { useDomain } from "@/hooks/useDomain";
1820

1921
interface FileHeaderProps {
2022
path: string;
@@ -64,11 +66,11 @@ export const PathHeader = ({
6466
webUrl: repo.webUrl,
6567
});
6668

67-
const { navigateToPath } = useBrowseNavigation();
6869
const { toast } = useToast();
6970
const containerRef = useRef<HTMLDivElement>(null);
7071
const breadcrumbsRef = useRef<HTMLDivElement>(null);
7172
const [visibleSegmentCount, setVisibleSegmentCount] = useState<number | null>(null);
73+
const domain = useDomain();
7274

7375
// Create breadcrumb segments from file path
7476
const breadcrumbSegments = useMemo(() => {
@@ -179,16 +181,6 @@ export const PathHeader = ({
179181
return true;
180182
}, [path, toast]);
181183

182-
const onBreadcrumbClick = useCallback((segment: BreadcrumbSegment) => {
183-
navigateToPath({
184-
repoName: repo.name,
185-
path: segment.fullPath,
186-
pathType: segment.isLastSegment ? pathType : 'tree',
187-
revisionName: branchDisplayName,
188-
});
189-
}, [repo.name, branchDisplayName, navigateToPath, pathType]);
190-
191-
192184
const renderSegmentWithHighlight = (segment: BreadcrumbSegment) => {
193185
if (!segment.highlightRange) {
194186
return segment.name;
@@ -224,17 +216,18 @@ export const PathHeader = ({
224216
</>
225217
)}
226218

227-
<div
219+
<Link
228220
className={cn("font-medium cursor-pointer hover:underline", repoNameClassName)}
229-
onClick={() => navigateToPath({
221+
href={getBrowsePath({
230222
repoName: repo.name,
231-
path: '',
223+
path: '/',
232224
pathType: 'tree',
233225
revisionName: branchDisplayName,
226+
domain,
234227
})}
235228
>
236229
{info?.displayName}
237-
</div>
230+
</Link>
238231
{branchDisplayName && (
239232
<p
240233
className="text-xs font-semibold text-gray-500 dark:text-gray-400 mt-[3px] flex items-center gap-0.5"
@@ -263,13 +256,21 @@ export const PathHeader = ({
263256
</DropdownMenuTrigger>
264257
<DropdownMenuContent align="start" className="min-w-[200px]">
265258
{hiddenSegments.map((segment) => (
266-
<DropdownMenuItem
259+
<Link
260+
href={getBrowsePath({
261+
repoName: repo.name,
262+
path: segment.fullPath,
263+
pathType: segment.isLastSegment ? pathType : 'tree',
264+
revisionName: branchDisplayName,
265+
domain,
266+
})}
267+
className="font-mono text-sm hover:cursor cursor-pointer"
267268
key={segment.fullPath}
268-
onClick={() => onBreadcrumbClick(segment)}
269-
className="font-mono text-sm cursor-pointer"
270269
>
271-
{renderSegmentWithHighlight(segment)}
272-
</DropdownMenuItem>
270+
<DropdownMenuItem className="hover:cursor cursor-pointer">
271+
{renderSegmentWithHighlight(segment)}
272+
</DropdownMenuItem>
273+
</Link>
273274
))}
274275
</DropdownMenuContent>
275276
</DropdownMenu>
@@ -281,14 +282,20 @@ export const PathHeader = ({
281282
{(isFileIconVisible && index === visibleSegments.length - 1) && (
282283
<VscodeFileIcon fileName={segment.name} className="h-4 w-4 mr-1" />
283284
)}
284-
<span
285+
<Link
285286
className={cn(
286287
"font-mono text-sm truncate cursor-pointer hover:underline",
287288
)}
288-
onClick={() => onBreadcrumbClick(segment)}
289+
href={getBrowsePath({
290+
repoName: repo.name,
291+
path: segment.fullPath,
292+
pathType: segment.isLastSegment ? pathType : 'tree',
293+
revisionName: branchDisplayName,
294+
domain,
295+
})}
289296
>
290297
{renderSegmentWithHighlight(segment)}
291-
</span>
298+
</Link>
292299
{index < visibleSegments.length - 1 && (
293300
<ChevronRight className="h-3 w-3 mx-0.5 text-muted-foreground flex-shrink-0" />
294301
)}
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,47 @@
11
'use client';
22

3-
import { useCallback } from "react";
43
import { SearchResultFile, SearchResultChunk } from "@/features/search/types";
54
import { LightweightCodeHighlighter } from "@/app/[domain]/components/lightweightCodeHighlighter";
5+
import Link from "next/link";
6+
import { getBrowsePath } from "@/app/[domain]/browse/hooks/useBrowseNavigation";
7+
import { useDomain } from "@/hooks/useDomain";
68

79

810
interface FileMatchProps {
911
match: SearchResultChunk;
1012
file: SearchResultFile;
11-
onOpen: (startLineNumber: number, endLineNumber: number, isCtrlKeyPressed: boolean) => void;
1213
}
1314

1415
export const FileMatch = ({
1516
match,
1617
file,
17-
onOpen: _onOpen,
1818
}: FileMatchProps) => {
19-
const onOpen = useCallback((isCtrlKeyPressed: boolean) => {
20-
const startLineNumber = match.contentStart.lineNumber;
21-
const endLineNumber = match.content.trimEnd().split('\n').length + startLineNumber - 1;
22-
23-
_onOpen(startLineNumber, endLineNumber, isCtrlKeyPressed);
24-
}, [match.content, match.contentStart.lineNumber, _onOpen]);
19+
const domain = useDomain();
2520

2621
// If it's just the title, don't show a code preview
2722
if (match.matchRanges.length === 0) {
2823
return null;
2924
}
3025

3126
return (
32-
<div
27+
<Link
3328
tabIndex={0}
3429
className="cursor-pointer focus:ring-inset focus:ring-4 bg-background hover:bg-editor-lineHighlight"
35-
onKeyDown={(e) => {
36-
if (e.key !== "Enter") {
37-
return;
30+
href={getBrowsePath({
31+
repoName: file.repository,
32+
revisionName: file.branches?.[0] ?? 'HEAD',
33+
path: file.fileName.text,
34+
pathType: 'blob',
35+
domain,
36+
highlightRange: {
37+
start: {
38+
lineNumber: match.contentStart.lineNumber,
39+
},
40+
end: {
41+
lineNumber: match.content.trimEnd().split('\n').length + match.contentStart.lineNumber - 1,
42+
}
3843
}
39-
40-
onOpen(e.metaKey || e.ctrlKey);
41-
}}
42-
onClick={(e) => {
43-
onOpen(e.metaKey || e.ctrlKey);
44-
}}
44+
})}
4545
title="open file: click, open file preview: cmd/ctrl + click"
4646
>
4747
<LightweightCodeHighlighter
@@ -53,6 +53,6 @@ export const FileMatch = ({
5353
>
5454
{match.content}
5555
</LightweightCodeHighlighter>
56-
</div>
56+
</Link>
5757
);
5858
}

packages/web/src/app/[domain]/search/components/searchResultsPanel/fileMatchContainer.tsx

Lines changed: 0 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ import { useMemo } from "react";
77
import { FileMatch } from "./fileMatch";
88
import { RepositoryInfo, SearchResultFile } from "@/features/search/types";
99
import { Button } from "@/components/ui/button";
10-
import { useBrowseNavigation } from "@/app/[domain]/browse/hooks/useBrowseNavigation";
1110

1211
export const MAX_MATCHES_TO_PREVIEW = 3;
1312

@@ -33,7 +32,6 @@ export const FileMatchContainer = ({
3332
const matchCount = useMemo(() => {
3433
return file.chunks.length;
3534
}, [file]);
36-
const { navigateToPath } = useBrowseNavigation();
3735

3836
const matches = useMemo(() => {
3937
const sortedMatches = file.chunks.sort((a, b) => {
@@ -123,29 +121,6 @@ export const FileMatchContainer = ({
123121
<FileMatch
124122
match={match}
125123
file={file}
126-
onOpen={(startLineNumber, endLineNumber, isCtrlKeyPressed) => {
127-
if (isCtrlKeyPressed) {
128-
const matchIndex = matches.slice(0, index).reduce((acc, match) => {
129-
return acc + match.matchRanges.length;
130-
}, 0);
131-
onOpenFilePreview(matchIndex);
132-
} else {
133-
navigateToPath({
134-
repoName: file.repository,
135-
revisionName: file.branches?.[0] ?? 'HEAD',
136-
path: file.fileName.text,
137-
pathType: 'blob',
138-
highlightRange: {
139-
start: {
140-
lineNumber: startLineNumber,
141-
},
142-
end: {
143-
lineNumber: endLineNumber,
144-
}
145-
}
146-
});
147-
}
148-
}}
149124
/>
150125
{(index !== matches.length - 1 || isMoreContentButtonVisible) && (
151126
<Separator className="bg-accent" />

0 commit comments

Comments
 (0)