From 25e7686a70ac6ffe770a70908017f5efd13ad2bd Mon Sep 17 00:00:00 2001 From: Quentin Gliech Date: Sun, 29 Mar 2026 23:13:11 +0200 Subject: [PATCH] refactor(web)!: restructure code browser to GitHub-style URLs MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit replace search-param-based code browser with proper URL segments: /$repo/tree/$ref/...path → directory view /$repo/blob/$ref/...path → file view /$repo/commits/$ref → commit history /$repo/ → redirect to tree/{defaultRef} add pathless _code layout route that: - preloads refs (branches/tags) in beforeLoad - renders shared header: breadcrumb, ref selector, history toggle - child routes (tree, blob, commits) render inside Outlet convert CodeBreadcrumb segments from onClick handlers to typed Links update Header "Code" NavLink and repo picker to use new URL structure Co-Authored-By: Claude Opus 4.6 (1M context) --- webui2/src/components/code/CodeBreadcrumb.tsx | 28 +- webui2/src/components/code/FileViewer.tsx | 18 +- webui2/src/components/layout/Header.tsx | 7 +- webui2/src/routeTree.gen.ts | 89 ++++++ webui2/src/routes/$repo/_code.tsx | 136 ++++++++ webui2/src/routes/$repo/_code/blob/$ref/$.tsx | 43 +++ .../src/routes/$repo/_code/commits/$ref.tsx | 16 + webui2/src/routes/$repo/_code/tree/$ref/$.tsx | 150 +++++++++ webui2/src/routes/$repo/index.tsx | 301 ++---------------- webui2/src/routes/index.tsx | 2 - 10 files changed, 483 insertions(+), 307 deletions(-) create mode 100644 webui2/src/routes/$repo/_code.tsx create mode 100644 webui2/src/routes/$repo/_code/blob/$ref/$.tsx create mode 100644 webui2/src/routes/$repo/_code/commits/$ref.tsx create mode 100644 webui2/src/routes/$repo/_code/tree/$ref/$.tsx diff --git a/webui2/src/components/code/CodeBreadcrumb.tsx b/webui2/src/components/code/CodeBreadcrumb.tsx index bc8f0c7df35fc3687e60cf2494cd39df6d491cbf..c5518447781ad1a83d19dcdc8c99d7d04e31db24 100644 --- a/webui2/src/components/code/CodeBreadcrumb.tsx +++ b/webui2/src/components/code/CodeBreadcrumb.tsx @@ -1,26 +1,27 @@ +import { Link } from "@tanstack/react-router"; import { ChevronRight } from "lucide-react"; interface CodeBreadcrumbProps { repoName: string; - ref: string; + currentRef: string; path: string; - // called when user clicks a breadcrumb segment — returns new path - onNavigate: (path: string) => void; + repo: string; } -// Path breadcrumb for the code browser: repo name / ref / path segments. -// Each segment is clickable to navigate up the tree. -export function CodeBreadcrumb({ repoName, ref, path, onNavigate }: CodeBreadcrumbProps) { +// Path breadcrumb for the code browser: repo name / path segments. +// Each segment is a Link to the corresponding tree path. +export function CodeBreadcrumb({ repoName, currentRef, path, repo }: CodeBreadcrumbProps) { const parts = path ? path.split("/").filter(Boolean) : []; return (
- + {parts.map((part, i) => { const partPath = parts.slice(0, i + 1).join("/"); @@ -31,18 +32,19 @@ export function CodeBreadcrumb({ repoName, ref, path, onNavigate }: CodeBreadcru {isLast ? ( {part} ) : ( - + )} ); })} - @ {ref} + @ {currentRef}
); } diff --git a/webui2/src/components/code/FileViewer.tsx b/webui2/src/components/code/FileViewer.tsx index 842a966a9b4c97b05472d1b306eb5df2ab07cb98..122ca26653944a3f5a6af5b6d2b6dbf49daca3ee 100644 --- a/webui2/src/components/code/FileViewer.tsx +++ b/webui2/src/components/code/FileViewer.tsx @@ -9,11 +9,23 @@ import { Button } from "@/components/ui/button"; import { Skeleton } from "@/components/ui/skeleton"; interface FileViewerProps { - blob: GitBlob; + blob: GitBlob | null; loading?: boolean; } -export function FileViewer({ blob, loading }: FileViewerProps) { +export function FileViewer({ blob, loading = false }: FileViewerProps) { + if (loading || !blob) { + return ( +
+
+ +
+
+ +
+
+ ); + } const [highlighted, setHighlighted] = useState<{ html: string; lineCount: number } | null>(null); useEffect(() => { @@ -43,7 +55,7 @@ export function FileViewer({ blob, loading }: FileViewerProps) { const { html, lineCount } = highlighted; function copyToClipboard() { - if (blob.text) void navigator.clipboard.writeText(blob.text); + if (blob?.text) void navigator.clipboard.writeText(blob.text); } return ( diff --git a/webui2/src/components/layout/Header.tsx b/webui2/src/components/layout/Header.tsx index 0ed2677d468dded56886288dee076e0707fb19d3..e37cbf4c6d83a7c9fe9d2c7728fa4c6acaabde54 100644 --- a/webui2/src/components/layout/Header.tsx +++ b/webui2/src/components/layout/Header.tsx @@ -54,12 +54,7 @@ export function Header() { {/* Repo-scoped nav links — only shown when inside a repo */} {effectiveRepo && (