inbox.templ RawHistoryFolder
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5// Inbox is the owner's inbox: what is open across every repository. The
6// counters, the filter and the lists are fragments with an id that the live
7// stream replaces as a whole (ermiteLive.swap).
8templ Inbox(l Layout, p InboxPage) {
9 @Shell(l, nil) {
10 <h1 class="sr">Inbox</h1>
11 <div class="inbox">
12 @InboxCounters(p)
13 @InboxRepos(p)
14 @InboxPending(p)
15 @InboxRuns(p)
16 @InboxMRs(p)
17 @InboxIssues(p)
18 </div>
19 }
20}
21
22templ InboxCounters(p InboxPage) {
23 <p id="inbox-counts" class="inbox-counts">
24 <strong>{ itoa(p.MergeRequests) }</strong> merge requests · <strong>{ itoa(p.Issues) }</strong> issues · <strong>{ itoa(p.PendingCount) }</strong> awaiting moderation · <strong>{ itoa(p.Running) }</strong> running
25 </p>
26}
27
28templ InboxRepos(p InboxPage) {
29 <nav id="inbox-repos" class="since" aria-label="Repository">
30 for _, r := range p.Repos {
31 <a
32 href={ templ.SafeURL(r.Href) }
33 if r.Current {
34 aria-current="page"
35 }
36 >{ r.Label }</a>
37 }
38 </nav>
39}
40
41// InboxPending is the issues awaiting moderation, first on the page. Their
42// texts come from anonymous visitors: they are shown as plain text, escaped,
43// never as Markdown.
44templ InboxPending(p InboxPage) {
45 <section id="inbox-pending" aria-labelledby="inbox-pending-h">
46 <h2 id="inbox-pending-h" class="rule-h"><span>Awaiting moderation</span><span class="count">{ itoa(p.PendingCount) }</span></h2>
47 if len(p.Pending) > 0 {
48 <ul class="pending-list">
49 for _, m := range p.Pending {
50 <li class="pending">
51 <div class="p-head">
52 <a href={ templ.SafeURL(m.RepoHref) }>{ m.Repo }</a>
53 <span>{ m.Author }</span>
54 if m.WhenAt != "" {
55 <time datetime={ m.WhenAt } title={ m.WhenAt }>{ m.When }</time>
56 }
57 </div>
58 <p class="p-title">{ m.Title }</p>
59 if m.Preview != "" {
60 <p class="p-body">{ m.Preview }</p>
61 }
62 if m.Approve != "" {
63 <div class="p-btns">
64 <form method="post" action={ templ.SafeURL(m.Approve) }><button type="submit" class="btn primary">Approve</button></form>
65 <form method="post" action={ templ.SafeURL(m.Reject) }><button type="submit" class="btn">Reject</button></form>
66 <form method="post" action={ templ.SafeURL(m.Ban) }><button type="submit" class="btn danger">Reject and ban</button></form>
67 </div>
68 }
69 </li>
70 }
71 </ul>
72 } else {
73 <p class="lede dim">nothing awaits moderation.</p>
74 }
75 </section>
76}
77
78templ InboxMRs(p InboxPage) {
79 <section id="inbox-mrs" aria-labelledby="inbox-mrs-h">
80 <h2 id="inbox-mrs-h" class="rule-h"><span>Open merge requests</span><span class="count">{ itoa(len(p.MRs)) }</span></h2>
81 @inboxRows(p.MRs, "Open merge requests")
82 if len(p.MRs) == 0 {
83 <p class="lede dim">no open merge requests.</p>
84 }
85 </section>
86}
87
88templ InboxIssues(p InboxPage) {
89 <section id="inbox-issues" aria-labelledby="inbox-issues-h">
90 <h2 id="inbox-issues-h" class="rule-h"><span>Open issues</span><span class="count">{ itoa(len(p.IssueRows)) }</span></h2>
91 @inboxRows(p.IssueRows, "Open issues")
92 if len(p.IssueRows) == 0 {
93 <p class="lede dim">no open issues.</p>
94 }
95 </section>
96}
97
98templ inboxRows(rows []InboxRow, label string) {
99 if len(rows) > 0 {
100 <table class="list mrs" aria-label={ label }>
101 <tbody data-rows>
102 for _, m := range rows {
103 <tr data-cursor?={ m.Cursor } data-state="open">
104 <td class="c-n mute">{ m.Number }</td>
105 <td class="c-subject"><a href={ templ.SafeURL(m.Href) }>{ m.Title }</a> <a class="mute" href={ templ.SafeURL(m.RepoHref) }>{ m.Repo }</a></td>
106 <td class="c-when nowrap dim">
107 if m.WhenAt != "" {
108 <time datetime={ m.WhenAt } title={ m.WhenAt }>{ m.When }</time>
109 }
110 </td>
111 </tr>
112 }
113 </tbody>
114 </table>
115 }
116}
117
118// InboxRuns stays as an empty fragment when CI is disabled.
119templ InboxRuns(p InboxPage) {
120 <section id="inbox-runs" hidden?={ !p.RunsEnabled }
121 if p.RunsEnabled {
122 aria-labelledby="inbox-runs-h"
123 }
124 >
125 if p.RunsEnabled {
126 <h2 id="inbox-runs-h" class="rule-h"><span>Running</span><span class="count">{ itoa(len(p.Runs)) }</span></h2>
127 if len(p.Runs) == 0 {
128 <p class="lede dim">no runs in progress.</p>
129 } else {
130 <table class="list mrs" aria-label="Running">
131 <tbody data-rows>
132 for _, r := range p.Runs {
133 <tr>
134 <td class="c-st">@CheckIcon(r.Kind, r.State)<span class="dim">{ r.State }</span></td>
135 <td class="c-subject"><a href={ templ.SafeURL(r.Href) }>{ r.Workflow }{ " " }{ r.Number }</a> <a class="mute" href={ templ.SafeURL(r.RepoHref) }>{ r.Repo }</a> <span class="dim">{ r.Ref }{ " " }{ r.Event }</span></td>
136 <td class="c-when nowrap dim">
137 if r.WhenAt != "" {
138 <time datetime={ r.WhenAt } title={ r.WhenAt }>{ r.When }</time>
139 }
140 </td>
141 </tr>
142 }
143 </tbody>
144 </table>
145 }
146 }
147 </section>
148}