NewPatch.tsx
Raw
1import config from "../../config.ts";
2import type { LabelRow, RepositoryRow } from "../../db/index.ts";
3import { labelTextColor } from "../../lib/labelColor.ts";
4import type { SessionUser } from "../../middleware/session.ts";
5import { Layout } from "../layout.tsx";
6import { RepoHeader } from "../repos/RepoHeader.tsx";
7import { RepoNav } from "../repos/RepoNav.tsx";
8
9interface NewPatchProps {
10 user: SessionUser;
11 repo: RepositoryRow;
12 error?: string;
13 template?: string;
14 labels: LabelRow[];
15}
16
17export function NewPatch({
18 user,
19 repo,
20 error,
21 template,
22 labels,
23}: NewPatchProps) {
24 return (
25 <Layout user={user} title={`New patch — ${repo.name}`}>
26 <div class="container">
27 <RepoHeader repo={repo} />
28 <RepoNav repo={repo} active="patches" user={user} />
29 <h2 class="section-title">Upload patch</h2>
30 {!!error && (
31 <p class="form-error" safe>
32 {error}
33 </p>
34 )}
35 <form
36 method="POST"
37 action={`/${repo.name}/patches`}
38 enctype="multipart/form-data"
39 class="form-card"
40 >
41 <div class="form-group">
42 <label for="title">Title</label>
43 <input
44 id="title"
45 name="title"
46 type="text"
47 required
48 maxlength={config.MAX_TITLE_BYTES}
49 placeholder="What does this patch do?"
50 />
51 </div>
52 <div class="form-group">
53 <label for="description">
54 Description{" "}
55 <span class="text-muted">
56 (Markdown supported, optional)
57 </span>
58 </label>
59 <textarea
60 id="description"
61 name="description"
62 rows="5"
63 maxlength={config.MAX_TEXT_BODY_BYTES}
64 safe
65 >
66 {template ?? ""}
67 </textarea>
68 </div>
69 <div class="form-group">
70 <label for="patch_file">
71 Patch file <span class="text-muted">(.patch)</span>
72 </label>
73 <input
74 id="patch_file"
75 name="patch_file"
76 type="file"
77 accept=".patch"
78 required
79 />
80 </div>
81 {labels.length > 0 &&
82 (user.isAdmin || repo.allow_user_labels === 1) && (
83 <div class="form-group">
84 <span class="form-group-label">Labels</span>
85 <div class="label-checkbox-list">
86 {labels.map((label) => (
87 <label class="label-checkbox-item">
88 <input
89 type="checkbox"
90 name="label_ids"
91 value={String(label.id)}
92 />
93 <span
94 class="label-badge"
95 style={`background:${label.color};color:${labelTextColor(label.color)}`}
96 safe
97 >
98 {label.name}
99 </span>
100 </label>
101 ))}
102 </div>
103 </div>
104 )}
105 <div class="form-actions">
106 <button type="submit" class="btn btn-primary">
107 Upload patch
108 </button>
109 <a href={`/${repo.name}/patches`} class="btn">
110 Cancel
111 </a>
112 </div>
113 </form>
114 </div>
115 </Layout>
116 );
117}
118