components.templ RawHistoryFolder
1// SPDX-License-Identifier: AGPL-3.0-or-later
2
3package web
4
5// Facts is a key/value block on an 11ch key column.
6templ Facts(facts []Fact) {
7 <dl class="kv">
8 for _, f := range facts {
9 <dt>{ f.Key }</dt>
10 @FactValue(f)
11 }
12 </dl>
13}
14
15// CloneBlock is a block of copyable shell lines; each has its own [copy]
16// button, whose label says "copied" for 1.5 s.
17templ CloneBlock(c Clone) {
18 <div class="clone" id={ c.ID }>
19 for _, line := range c.Lines {
20 <div class="clone-line">
21 <span class="mute" aria-hidden="true">$ </span><code>{ line }</code>
22 <button
23 type="button"
24 class="btn copy"
25 data-js
26 data-label="Copy"
27 aria-label={ "copy: " + line }
28 hx-on:click="ermite.copy(this)"
29 >Copy</button>
30 </div>
31 }
32 </div>
33}
34
35// HomeRowView is the row of a repository in the home list: what it is, its
36// latest run, and its newest commits. Its id is the target of SSE swaps; the
37// name link comes first, `enter` follows it.
38templ HomeRowView(r HomeRow) {
39 <li id={ r.ID } class="repo" data-cursor?={ r.Cursor }>
40 <div class="repo-main">
41 <h2 class="repo-name">
42 <a href={ templ.SafeURL(r.Href) }>{ r.Name }</a>
43 if r.Private {
44 <span class="pill">private</span>
45 }
46 if r.Fresh {
47 <span class="pill new">new push</span>
48 }
49 </h2>
50 if r.Desc != "" {
51 <p class="repo-desc">{ r.Desc }</p>
52 } else {
53 <p class="repo-desc mute">no description</p>
54 }
55 <dl class="repo-stats" aria-label={ "Figures of " + r.Name }>
56 if s := r.Stats; s != nil {
57 <div><dt>commits</dt><dd>{ s.Commits }</dd></div>
58 <div><dt>last 30 days</dt><dd>{ s.Recent }</dd></div>
59 if s.Tag != "" {
60 <div>
61 <dt>latest tag</dt>
62 if s.TagHref != "" {
63 <dd><a href={ templ.SafeURL(s.TagHref) } title={ "made " + s.TagWhen }>{ s.Tag }</a></dd>
64 } else {
65 <dd title={ "made " + s.TagWhen }>{ s.Tag }</dd>
66 }
67 </div>
68 }
69 }
70 <div>
71 <dt>last activity</dt>
72 if r.ActiveAt != "" {
73 <dd><time datetime={ r.ActiveAt } title={ r.ActiveAt }>{ r.Active }</time></dd>
74 } else {
75 <dd class="mute">never</dd>
76 }
77 </div>
78 </dl>
79 </div>
80 if r.CI != nil {
81 <a class="repo-ci" href={ templ.SafeURL(r.CI.Href) } title={ r.CI.Title }>
82 <span class={ "ck", "ck-" + r.CI.Kind } aria-hidden="true"></span>
83 <span class="sr">CI: </span>{ r.CI.Label }
84 </a>
85 }
86 if len(r.Commits) > 0 {
87 <ul class="repo-commits" aria-label={ "Recent commits of " + r.Name }>
88 for _, c := range r.Commits {
89 <li>
90 <a class="rc-sha" href={ templ.SafeURL(c.CHref) }>{ c.Short }</a>
91 <span class="rc-subject" title={ c.Subject }>{ c.Subject }</span>
92 if c.WhenAt != "" {
93 <time class="dim" datetime={ c.WhenAt } title={ c.WhenAt }>{ c.When }</time>
94 }
95 </li>
96 }
97 </ul>
98 } else if r.NoCommits {
99 <p class="repo-commits mute">no commits yet</p>
100 }
101 </li>
102}
103
104// Outline is the README outline; levels indent by 2ch, the h1 is bold.
105templ Outline(headings []Heading) {
106 <nav class="outline" aria-label="Outline">
107 for _, h := range headings {
108 <a class={ "l" + itoa(h.Level) } href={ templ.SafeURL("#" + h.ID) }>{ h.Text }</a>
109 }
110 </nav>
111}
112
113// ReadmeCard is a README in a card whose header names the file.
114templ ReadmeCard(r Readme) {
115 <section class="card readme" aria-labelledby="readme-h">
116 <h2 class="card-h" id="readme-h">
117 <span class="ico i-file" aria-hidden="true"></span>
118 { r.Name }
119 </h2>
120 @ReadmeView(r)
121 </section>
122}
123
124// ReadmeView is a rendered README. Its HTML comes from the Markdown
125// renderer, which drops raw HTML and filters URLs.
126templ ReadmeView(r Readme) {
127 <article class="prose" aria-label={ r.Name } hx-ignore>
128 if r.Note != "" {
129 <p class="dim">{ r.Note }</p>
130 } else {
131 @templ.Raw(r.HTML)
132 }
133 </article>
134}
135
136// CommitRows is a cursor table of commits: sha, subject with inline refs,
137// author, relative date (absolute in the title).
138templ CommitRows(rows []CommitRow) {
139 <table class="list commits" aria-label="Commits">
140 <tbody data-rows>
141 for _, c := range rows {
142 <tr
143 if c.ID != "" {
144 id={ c.ID }
145 }
146 data-cursor?={ c.Cursor }
147 >
148 <td class="c-sha mute">{ c.Short }</td>
149 <td class="c-subject">
150 <a href={ templ.SafeURL(c.CHref) }>{ c.Subject }</a>
151 if c.Merge {
152 <span class="pill">merge</span>
153 }
154 for _, b := range c.Branches {
155 <span class="pill">{ b }</span>
156 }
157 for _, t := range c.Tags {
158 <span class="pill tag"><span class="sr">tag </span>{ t }</span>
159 }
160 </td>
161 <td class="c-ck">@CommitChecks(c.Checks)</td>
162 <td class="c-who dim">{ c.Author }</td>
163 <td class="c-when nowrap dim"><time datetime={ c.WhenAt } title={ c.WhenAt }>{ c.When }</time></td>
164 </tr>
165 }
166 </tbody>
167 </table>
168}