NewIssue.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 NewIssueProps {
10 user: SessionUser;
11 repo: RepositoryRow;
12 error?: string;
13 template?: string;
14 labels: LabelRow[];
15}
16
17export function NewIssue({
18 user,
19 repo,
20 error,
21 template,
22 labels,
23}: NewIssueProps) {
24 return (
25 <Layout user={user} title={`New issue — ${repo.name}`}>
26 <div class="container">
27 <RepoHeader repo={repo} />
28 <RepoNav repo={repo} active="issues" user={user} />
29 <h2 class="section-title">New issue</h2>
30 {!!error && (
31 <p class="form-error" safe>
32 {error}
33 </p>
34 )}
35 <form
36 method="POST"
37 action={`/${repo.name}/issues`}
38 class="form-card"
39 >
40 <div class="form-group">
41 <label for="title">Title</label>
42 <input
43 id="title"
44 name="title"
45 type="text"
46 required
47 maxlength={config.MAX_TITLE_BYTES}
48 placeholder="Short, descriptive title"
49 />
50 </div>
51 <div class="form-group">
52 <label for="body">
53 Description{" "}
54 <span class="text-muted">
55 (Markdown supported, optional)
56 </span>
57 </label>
58 <textarea
59 id="body"
60 name="body"
61 rows="10"
62 maxlength={config.MAX_TEXT_BODY_BYTES}
63 placeholder="Describe the issue..."
64 safe
65 >
66 {template ?? ""}
67 </textarea>
68 </div>
69 {labels.length > 0 &&
70 (user.isAdmin || repo.allow_user_labels === 1) && (
71 <div class="form-group">
72 <span class="form-group-label">Labels</span>
73 <div class="label-checkbox-list">
74 {labels.map((label) => (
75 <label class="label-checkbox-item">
76 <input
77 type="checkbox"
78 name="label_ids"
79 value={String(label.id)}
80 />
81 <span
82 class="label-badge"
83 style={`background:${label.color};color:${labelTextColor(label.color)}`}
84 safe
85 >
86 {label.name}
87 </span>
88 </label>
89 ))}
90 </div>
91 </div>
92 )}
93 <div class="form-actions">
94 <button type="submit" class="btn btn-primary">
95 Submit issue
96 </button>
97 <a href={`/${repo.name}/issues`} class="btn">
98 Cancel
99 </a>
100 </div>
101 </form>
102 </div>
103 </Layout>
104 );
105}
106