v0.35.1 2aca1df

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}

Keyboard shortcuts

Single-key shortcuts are on. ctrl k and esc work whatever this says.

ctrl k :
go to a section, branch, tag, file or repository
?
this list
j k
move the row cursor down / up
enter
open the row under the cursor; on Files, a directory opens or closes in place
↑ ↓ ← → home end
in the file tree (focus on a row): previous / next row, close / open a directory or go to its parent / first entry, first / last row. They never open a file
l h
on Files: open a directory or a file / close a directory or go up to its parent, then to the parent page. Elsewhere: into the side panel (on a merge request, its files) / back to the content; there j k move between its controls
g g G
first / last row
/
filter the list; on Files, find a file anywhere in the repository (esc clears, enter opens the best match)
b
switch branch or tag
g s g f g c g b g m g i g r g a
tabs: summary, files, commits, branches & tags, merge requests, issues, releases, actions (when available)
g h
home
w
wide mode: use the whole width of the screen, or not (remembered)
y
copy a permalink pinned to the commit
d u x
diff: split / unified / collapse or expand all
e E
diff: the whole file in view / every file, with the lines the hunks hide
n
merge request: next note in the diff
esc
close a dialog, leave a field

Branches 4

Tags 45

↑↓ moveenter openesc close