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 && <p class="form-error">{error}</p>}
31 <form
32 method="POST"
33 action={`/${repo.name}/issues`}
34 class="form-card"
35 >
36 <div class="form-group">
37 <label for="title">Title</label>
38 <input
39 id="title"
40 name="title"
41 type="text"
42 required
43 maxlength={config.MAX_TITLE_BYTES}
44 placeholder="Short, descriptive title"
45 />
46 </div>
47 <div class="form-group">
48 <label for="body">
49 Description{" "}
50 <span class="text-muted">
51 (Markdown supported, optional)
52 </span>
53 </label>
54 <textarea
55 id="body"
56 name="body"
57 rows="10"
58 maxlength={config.MAX_TEXT_BODY_BYTES}
59 placeholder="Describe the issue..."
60 >
61 {template ?? ""}
62 </textarea>
63 </div>
64 {labels.length > 0 &&
65 (user.isAdmin || repo.allow_user_labels === 1) && (
66 <div class="form-group">
67 <span class="form-group-label">Labels</span>
68 <div class="label-checkbox-list">
69 {labels.map((label) => (
70 <label class="label-checkbox-item">
71 <input
72 type="checkbox"
73 name="label_ids"
74 value={String(label.id)}
75 />
76 <span
77 class="label-badge"
78 style={`background:${label.color};color:${labelTextColor(label.color)}`}
79 >
80 {label.name}
81 </span>
82 </label>
83 ))}
84 </div>
85 </div>
86 )}
87 <div class="form-actions">
88 <button type="submit" class="btn btn-primary">
89 Submit issue
90 </button>
91 <a href={`/${repo.name}/issues`} class="btn">
92 Cancel
93 </a>
94 </div>
95 </form>
96 </div>
97 </Layout>
98 );
99}
100