FileEdit.tsx
Raw
1import type { RepositoryRow } from "../../db/index.ts";
2import type { SessionUser } from "../../middleware/session.ts";
3import { Layout } from "../layout.tsx";
4import { RepoHeader } from "../repos/RepoHeader.tsx";
5import { RepoNav } from "./RepoNav.tsx";
6
7interface FileEditProps {
8 user: SessionUser;
9 repo: RepositoryRow;
10 ref: string;
11 filePath: string;
12 content: string;
13 error?: string;
14}
15
16export function FileEdit({
17 user,
18 repo,
19 ref: editRef,
20 filePath,
21 content,
22 error,
23}: FileEditProps) {
24 const parts = filePath.split("/");
25 const filename = parts[parts.length - 1] ?? filePath;
26 return (
27 <Layout user={user} title={`Edit ${repo.name}/${filePath}`}>
28 <div class="container">
29 <RepoHeader repo={repo} />
30 <RepoNav repo={repo} active="code" user={user} />
31 <div class="breadcrumb">
32 <a href={`/${repo.name}/tree/${editRef}`}>{repo.name}</a>
33 {parts.map((part, i) => {
34 const partPath = parts.slice(0, i + 1).join("/");
35 const isLast = i === parts.length - 1;
36 return (
37 <>
38 <span class="breadcrumb-sep">/</span>
39 {isLast ? (
40 <span class="breadcrumb-current">
41 {part}
42 </span>
43 ) : (
44 <a
45 href={`/${repo.name}/tree/${editRef}/${partPath}`}
46 >
47 {part}
48 </a>
49 )}
50 </>
51 );
52 })}
53 </div>
54 <p class="form-hint">
55 WARNING: Line endings are normalized to LF (\n) on save.
56 </p>
57 {error && <p class="form-error">{error}</p>}
58 <form
59 method="POST"
60 action={`/${repo.name}/edit/${editRef}/${filePath}`}
61 >
62 <div class="file-blob-header">
63 <span class="file-blob-name">{filename}</span>
64 <div class="file-blob-actions">
65 <a
66 href={`/${repo.name}/blob/${editRef}/${filePath}`}
67 class="btn btn-sm btn-ghost"
68 >
69 Cancel
70 </a>
71 </div>
72 </div>
73 <div class="file-blob-body">
74 <textarea
75 name="content"
76 class="file-edit-textarea"
77 rows="30"
78 spellcheck="false"
79 autocorrect="off"
80 autocapitalize="off"
81 {...{ autocomplete: "off" }}
82 >
83 {content}
84 </textarea>
85 </div>
86 <div class="form-card">
87 <p
88 class="form-hint"
89 style="margin-bottom: var(--space-4);"
90 >
91 Committing directly to <strong>{editRef}</strong>
92 </p>
93 <div class="form-group">
94 <label for="message">Commit message</label>
95 <textarea
96 id="message"
97 name="message"
98 rows="3"
99 required
100 >
101 {`Edited ${filename}`}
102 </textarea>
103 </div>
104 <div class="form-actions">
105 <button type="submit" class="btn btn-primary">
106 Commit changes
107 </button>
108 <a
109 href={`/${repo.name}/blob/${editRef}/${filePath}`}
110 class="btn btn-ghost"
111 >
112 Cancel
113 </a>
114 </div>
115 </div>
116 </form>
117 </div>
118 </Layout>
119 );
120}
121