FileTree.tsx
Raw
1import type { RepositoryRow } from "../../db/index.ts";
2import type { SessionUser } from "../../middleware/session.ts";
3import type { TreeEntry } from "../../services/git.ts";
4import { Layout } from "../layout.tsx";
5import { RepoHeader } from "../repos/RepoHeader.tsx";
6import { BranchSelector } from "./BranchSelector.tsx";
7import { FileTreeTable } from "./FileTreeTable.tsx";
8import { RepoNav } from "./RepoNav.tsx";
9
10interface FileTreeProps {
11 user: SessionUser | null;
12 repo: RepositoryRow;
13 ref: string;
14 subpath: string;
15 entries: TreeEntry[];
16 branches: string[];
17 tags?: string[];
18 readmeHtml?: string | null;
19 readmePath?: string;
20}
21
22export function FileTree({
23 user,
24 repo,
25 ref: treeRef,
26 subpath,
27 entries,
28 branches,
29 tags,
30 readmeHtml,
31 readmePath,
32}: FileTreeProps) {
33 const parts = subpath ? subpath.split("/") : [];
34 return (
35 <Layout
36 user={user}
37 title={`${repo.name}${subpath ? `/${subpath}` : ""}`}
38 >
39 <div class="container">
40 <RepoHeader repo={repo} />
41 <RepoNav repo={repo} active="code" user={user} />
42 <div class="tree-toolbar">
43 <BranchSelector
44 repoName={repo.name}
45 branches={branches}
46 tags={tags}
47 currentRef={treeRef}
48 view="tree"
49 path={subpath}
50 />
51 {branches.includes(treeRef) && user?.isAdmin && (
52 <a
53 href={`/${repo.name}/new-file/${treeRef}${subpath ? `?dir=${encodeURIComponent(subpath)}` : ""}`}
54 class="btn btn-sm btn-primary"
55 >
56 New file
57 </a>
58 )}
59 </div>
60 {!!subpath && (
61 <div class="breadcrumb">
62 <a href={`/${repo.name}/tree/${treeRef}`} safe>
63 {repo.name}
64 </a>
65 {parts.map((part, i) => {
66 const partPath = parts.slice(0, i + 1).join("/");
67 return (
68 <>
69 <span class="breadcrumb-sep">/</span>
70 <a
71 href={`/${repo.name}/tree/${treeRef}/${partPath}`}
72 safe
73 >
74 {part}
75 </a>
76 </>
77 );
78 })}
79 </div>
80 )}
81 <FileTreeTable
82 repoName={repo.name}
83 treeRef={treeRef}
84 subpath={subpath}
85 entries={entries}
86 />
87 {!!readmeHtml && (
88 <div class="readme-section">
89 <div class="readme-header">
90 <span>README</span>
91 {!!readmePath && (
92 <a
93 href={`/${repo.name}/raw/${treeRef}/${readmePath}`}
94 class="btn btn-sm"
95 >
96 Raw
97 </a>
98 )}
99 </div>
100 <div class="markdown-body">{readmeHtml as "safe"}</div>
101 </div>
102 )}
103 </div>
104 </Layout>
105 );
106}
107