Monorepo for Tangled
tangled.org
1{{ define "title" }}{{ .RepoInfo.FullName }} at {{ .Ref }} · Tangled{{ end }}
2
3
4{{ define "extrameta" }}
5 {{ template "repo/fragments/meta" . }}
6
7 {{ template "repo/fragments/og" (dict "RepoInfo" .RepoInfo) }}
8{{ end }}
9
10{{ define "repoContent" }}
11 <main>
12 {{ if .Languages }}
13 {{ block "repoLanguages" . }}{{ end }}
14 {{ end }}
15 <div class="flex items-center justify-between pb-5">
16 {{ block "branchSelector" . }}{{ end }}
17 <div class="flex items-center gap-3">
18 <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
19 {{ i "git-commit-horizontal" "w-4" "h-4" }} {{ scaleFmt .TotalCommits }}
20 </a>
21 <a href="/{{ .RepoInfo.FullName }}/branches" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
22 {{ i "git-branch" "w-4" "h-4" }} {{ scaleFmt (len .Branches) }}
23 </a>
24 <a href="/{{ .RepoInfo.FullName }}/tags" class="inline-flex md:hidden items-center text-sm gap-1 font-bold">
25 {{ i "tags" "w-4" "h-4" }} {{ scaleFmt (len .Tags) }}
26 </a>
27 <a href="/{{ .RepoInfo.FullName }}/search" class="btn">
28 {{ i "search" "size-4" }}
29 </a>
30 {{ template "repo/fragments/cloneDropdown" . }}
31 </div>
32 </div>
33 <div class="grid grid-cols-1 md:grid-cols-2 gap-2">
34 {{ block "fileTree" . }}{{ end }}
35 {{ block "rightInfo" . }}{{ end }}
36 </div>
37 </main>
38{{ end }}
39
40{{ define "repoLanguages" }}
41 <details class="group -my-4 -m-6 mb-4">
42 <summary class="flex gap-[1px] h-4 scale-y-50 hover:scale-y-100 origin-top group-open:scale-y-100 transition-all hover:cursor-pointer overflow-hidden rounded-t">
43 {{ range $value := .Languages }}
44 <div
45 title='{{ or $value.Name "Other" }} {{ printf "%.1f" $value.Percentage }}%'
46 style="background-color: {{ $value.Color }}; width: {{ $value.Percentage }}%"
47 ></div>
48 {{ end }}
49 </summary>
50 <div class="px-4 py-2 border-b border-gray-200 dark:border-gray-600 flex items-center gap-4 flex-wrap">
51 {{ range $value := .Languages }}
52 <div
53 class="flex flex-grow items-center gap-2 text-xs align-items-center justify-center"
54 >
55 {{ template "repo/fragments/colorBall" (dict "color" (langColor $value.Name)) }}
56 <div>{{ or $value.Name "Other" }}
57 <span class="text-gray-500 dark:text-gray-400">
58 {{ if lt $value.Percentage 0.05 }}
59 0.1%
60 {{ else }}
61 {{ printf "%.1f" $value.Percentage }}%
62 {{ end }}
63 </span></div>
64 </div>
65 {{ end }}
66 </div>
67 </details>
68{{ end }}
69
70{{ define "branchSelector" }}
71 <div class="flex gap-2 items-center justify-between w-full">
72 <div class="flex gap-2 items-stretch">
73 <select
74 onchange="window.location.href = '/{{ .RepoInfo.FullName }}/tree/' + encodeURIComponent(this.value)"
75 class="p-1 border max-w-32 border-gray-200 bg-white dark:bg-gray-800 dark:text-white dark:border-gray-700"
76 >
77 <optgroup label="Branches ({{len .Branches}})" class="bold text-sm">
78 {{ range .Branches }}
79 <option
80 value="{{ .Reference.Name }}"
81 class="py-1"
82 {{ if eq .Reference.Name $.Ref }}
83 selected
84 {{ end }}
85 >
86 {{ .Reference.Name }}
87 </option>
88 {{ end }}
89 </optgroup>
90 <optgroup label="Tags ({{len .Tags}})" class="bold text-sm">
91 {{ range .Tags }}
92 <option
93 value="{{ .Reference.Name }}"
94 class="py-1"
95 {{ if eq .Reference.Name $.Ref }}
96 selected
97 {{ end }}
98 >
99 {{ .Reference.Name }}
100 </option>
101 {{ else }}
102 <option class="py-1" disabled>No tags found</option>
103 {{ end }}
104 </optgroup>
105 </select>
106 <div class="flex items-center gap-2">
107 <a
108 href="/{{ .RepoInfo.FullName }}/compare?base={{ $.Ref | urlquery }}"
109 class="btn flex items-center gap-2 no-underline hover:no-underline"
110 title="Compare branches or tags"
111 >
112 {{ i "git-compare" "w-4 h-4" }}
113 </a>
114 </div>
115 </div>
116 </div>
117{{ end }}
118
119{{ define "fileTree" }}
120 <div id="file-tree" class="col-span-1 pr-2 md:border-r md:border-gray-200 dark:md:border-gray-700" >
121 {{ $linkstyle := "no-underline hover:underline dark:text-white" }}
122
123 {{ range .Files }}
124 <div class="grid grid-cols-3 gap-4 items-center py-1">
125 <div class="col-span-2">
126 {{ $link := printf "/%s/%s/%s/%s" $.RepoInfo.FullName "tree" (urlquery $.Ref) .Name }}
127 {{ $icon := "folder" }}
128 {{ $iconStyle := "size-4 fill-current" }}
129
130 {{ if .IsSubmodule }}
131 {{ $link = printf "/%s/%s/%s/%s" $.RepoInfo.FullName "blob" (urlquery $.Ref) .Name }}
132 {{ $icon = "folder-input" }}
133 {{ $iconStyle = "size-4" }}
134 {{ end }}
135
136 {{ if .IsFile }}
137 {{ $link = printf "/%s/%s/%s/%s" $.RepoInfo.FullName "blob" (urlquery $.Ref) .Name }}
138 {{ $icon = "file" }}
139 {{ $iconStyle = "size-4" }}
140 {{ end }}
141
142 <a href="{{ $link }}" class="{{ $linkstyle }}">
143 <div class="flex items-center gap-2">
144 {{ i $icon $iconStyle "flex-shrink-0" }}
145 <span class="truncate">{{ .Name }}</span>
146 </div>
147 </a>
148 </div>
149
150 <div class="text-sm col-span-1 text-right">
151 {{ with .LastCommit }}
152 <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash }}" class="text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .When }}</a>
153 {{ end }}
154 </div>
155 </div>
156 {{ end }}
157 </div>
158{{ end }}
159
160{{ define "rightInfo" }}
161 <div id="right-info" class="hidden md:block col-span-1">
162 {{ block "commitLog" . }} {{ end }}
163 {{ block "branchList" . }} {{ end }}
164 {{ block "tagList" . }} {{ end }}
165 </div>
166{{ end }}
167
168{{ define "commitLog" }}
169<div id="commit-log" class="md:col-span-1 px-2 pb-4">
170 <div class="flex justify-between items-center">
171 <a href="/{{ .RepoInfo.FullName }}/commits/{{ .Ref | urlquery }}" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
172 {{ i "logs" "w-4 h-4" }} Commits
173 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt .TotalCommits }}</span>
174 </a>
175 </div>
176 <div class="flex flex-col gap-6">
177 {{ range .CommitsTrunc }}
178 <div>
179 <div id="commit-message">
180 {{ $messageParts := splitN .Message "\n\n" 2 }}
181 <div class="text-base cursor-pointer">
182 <div>
183 <div>
184 <a
185 href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"
186 class="inline no-underline hover:underline dark:text-white"
187 >{{ index $messageParts 0 }}</a
188 >
189 {{ if gt (len $messageParts) 1 }}
190
191 <button
192 class="py-1/2 px-1 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
193 hx-on:click="this.parentElement.nextElementSibling.classList.toggle('hidden')"
194 >
195 {{ i "ellipsis" "w-3 h-3" }}
196 </button>
197 {{ end }}
198 </div>
199 {{ if gt (len $messageParts) 1 }}
200 <p
201 class="hidden mt-1 text-sm cursor-text pb-2 dark:text-gray-300"
202 >
203 {{ nl2br (index $messageParts 1) }}
204 </p>
205 {{ end }}
206 </div>
207 </div>
208 </div>
209
210 <!-- commit info bar -->
211 <div class="text-xs mt-2 text-gray-500 dark:text-gray-400 flex items-center flex-wrap">
212 {{ $verified := $.VerifiedCommits.IsVerified .Hash.String }}
213 {{ $hashStyle := "text-gray-700 dark:text-gray-300 bg-gray-100 dark:bg-gray-900" }}
214 {{ if $verified }}
215 {{ $hashStyle = "bg-green-100 text-green-800 dark:bg-green-900 dark:text-green-200 px-2 rounded" }}
216 {{ end }}
217 <span class="font-mono">
218 <a href="/{{ $.RepoInfo.FullName }}/commit/{{ .Hash.String }}"
219 {{ if .ChangeId }}title="jj change id: {{ .ChangeId }}"{{ end }}
220 class="no-underline hover:underline {{ $hashStyle }} px-2 py-1 rounded flex items-center gap-2">
221 {{ slice .Hash.String 0 8 }}
222 {{ if $verified }}
223 {{ i "shield-check" "w-3 h-3" }}
224 {{ end }}
225 </a>
226 </span>
227 <span
228 class="mx-1 before:content-['·'] before:select-none"
229 ></span>
230 {{ template "attribution" (list . $.EmailToDid) }}
231 <div class="inline-block px-1 select-none after:content-['·']"></div>
232 {{ template "repo/fragments/time" .Committer.When }}
233
234 <!-- tags/branches -->
235 {{ $tagsForCommit := index $.TagMap .Hash.String }}
236 {{ if gt (len $tagsForCommit) 0 }}
237 <div class="inline-block px-1 select-none after:content-['·']"></div>
238 {{ end }}
239 {{ range $tagsForCommit }}
240 <span class="text-xs rounded bg-gray-100 dark:bg-gray-700 text-black dark:text-white font-mono px-2 mx-[2px] inline-flex items-center">
241 {{ . }}
242 </span>
243 {{ end }}
244
245 <!-- ci status -->
246 {{ $pipeline := index $.Pipelines .Hash.String }}
247 {{ if and $pipeline (gt (len $pipeline.Statuses) 0) }}
248 <div class="inline-block px-1 select-none after:content-['·']"></div>
249 {{ template "repo/pipelines/fragments/pipelineSymbolLong" (dict "RepoInfo" $.RepoInfo "Pipeline" $pipeline) }}
250 {{ end }}
251 </div>
252 </div>
253 {{ end }}
254 </div>
255</div>
256{{ end }}
257
258{{ define "attribution" }}
259 {{ $commit := index . 0 }}
260 {{ $map := index . 1 }}
261 <span class="flex items-center gap-1">
262 {{ $author := index $map $commit.Author.Email }}
263 {{ $coauthors := $commit.CoAuthors }}
264 {{ $all := list }}
265
266 {{ if $author }}
267 {{ $all = append $all $author }}
268 {{ end }}
269 {{ range $coauthors }}
270 {{ $co := index $map .Email }}
271 {{ if $co }}
272 {{ $all = append $all $co }}
273 {{ end }}
274 {{ end }}
275
276 {{ if $author }}
277 {{ template "fragments/tinyAvatarList" (dict "all" $all "classes" "size-6") }}
278 {{ else }}
279 {{ placeholderAvatar "tiny" }}
280 {{ end }}
281 <a href="{{ if $author }}/{{ $author }}{{ else }}mailto:{{ $commit.Author.Email }}{{ end }}"
282 class="no-underline hover:underline">
283 {{ if $author }}{{ resolve $author }}{{ else }}{{ $commit.Author.Name }}{{ end }}
284 {{ if $coauthors }} +{{ length $coauthors }}{{ end }}
285 </a>
286 </span>
287{{ end }}
288
289{{ define "branchList" }}
290 {{ if gt (len .BranchesTrunc) 0 }}
291 <div id="branches" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700">
292 <a href="/{{ .RepoInfo.FullName }}/branches" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
293 {{ i "git-branch" "w-4 h-4" }} Branches
294 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt (len .Branches) }}</span>
295 </a>
296 <div class="flex flex-col gap-1">
297 {{ range .BranchesTrunc }}
298 <div class="text-base flex items-center justify-between overflow-hidden">
299 <div class="flex items-center gap-2 min-w-0 flex-1">
300 <a href="/{{ $.RepoInfo.FullName }}/tree/{{ .Reference.Name | urlquery }}"
301 class="inline-block truncate no-underline hover:underline dark:text-white">
302 {{ .Reference.Name }}
303 </a>
304 {{ if .Commit }}
305 <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span>
306 <span class="whitespace-nowrap text-xs text-gray-500 dark:text-gray-400 shrink-0">{{ template "repo/fragments/time" .Commit.Committer.When }}</span>
307 {{ end }}
308 {{ if .IsDefault }}
309 <span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·'] shrink-0"></span>
310 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono shrink-0">Default</span>
311 {{ end }}
312 </div>
313 {{ if ne $.Ref .Reference.Name }}
314 <a href="/{{ $.RepoInfo.FullName }}/compare/{{ $.Ref | urlquery }}...{{ .Reference.Name | urlquery }}"
315 class="text-xs flex gap-2 items-center shrink-0 ml-2"
316 title="Compare branches or tags">
317 {{ i "git-compare" "w-3 h-3" }} Compare
318 </a>
319 {{ end }}
320 </div>
321 {{ end }}
322 </div>
323 </div>
324 {{ end }}
325{{ end }}
326
327{{ define "tagList" }}
328 {{ if gt (len .TagsTrunc) 0 }}
329 <div id="tags" class="md:col-span-1 px-2 py-4 border-t border-gray-200 dark:border-gray-700">
330 <div class="flex justify-between items-center">
331 <a href="/{{ .RepoInfo.FullName }}/tags" class="flex items-center gap-2 pb-2 cursor-pointer font-bold hover:text-gray-600 dark:hover:text-gray-300 hover:no-underline">
332 {{ i "tags" "w-4 h-4" }} Tags
333 <span class="bg-gray-100 dark:bg-gray-700 font-normal rounded py-1/2 px-1 text-sm">{{ scaleFmt (len .Tags) }}</span>
334 </a>
335 </div>
336 <div class="flex flex-col gap-1">
337 {{ range $idx, $tag := .TagsTrunc }}
338 {{ with $tag }}
339 <div>
340 <div class="text-base flex items-center gap-2">
341 <a href="/{{ $.RepoInfo.FullName }}/tags/{{ .Reference.Name | urlquery }}"
342 class="inline no-underline hover:underline dark:text-white">
343 {{ .Reference.Name }}
344 </a>
345 </div>
346 <div>
347 {{ with .Tag }}
348 <span class="text-xs text-gray-500 dark:text-gray-400">{{ template "repo/fragments/time" .Tagger.When }}</span>
349 {{ end }}
350 {{ if eq $idx 0 }}
351 {{ with .Tag }}<span class="px-1 text-gray-500 dark:text-gray-400 select-none after:content-['·']"></span>{{ end }}
352 <span class="bg-gray-200 dark:bg-gray-700 rounded py-1/2 px-1 text-xs font-mono">Latest</span>
353 {{ end }}
354 </div>
355 </div>
356 {{ end }}
357 {{ end }}
358 </div>
359 </div>
360 {{ end }}
361{{ end }}
362
363{{ define "repoAfter" }}
364 {{- if or .HTMLReadme .Readme -}}
365 {{ template "repo/fragments/readme" . }}
366 {{- end -}}
367{{ end }}
368