forked from
tangled.org/core
Monorepo for Tangled
1{{ define "title" }}
2 {{ .Pull.Title }} · pull #{{ .Pull.PullId }} · {{ .RepoInfo.FullName }}
3{{ end }}
4
5{{ define "extrameta" }}
6 {{ template "repo/pulls/fragments/og" (dict "RepoInfo" .RepoInfo "Pull" .Pull) }}
7{{ end }}
8
9{{ define "mainLayout" }}
10 <div class="px-1 flex-grow flex flex-col gap-4">
11 <div class="max-w-full md:max-w-screen-lg mx-auto">
12 {{ block "contentLayout" . }}
13 {{ block "content" . }}{{ end }}
14 {{ end }}
15 </div>
16 {{ block "contentAfterLayout" . }}
17 <main>
18 {{ block "contentAfter" . }}{{ end }}
19 </main>
20 {{ end }}
21 </div>
22 <script>
23 (function() {
24 const details = document.getElementById('bottomSheet');
25 const backdrop = document.getElementById('bottomSheetBackdrop');
26 const isDesktop = () => window.matchMedia('(min-width: 768px)').matches;
27
28 // function to update backdrop
29 const updateBackdrop = () => {
30 if (backdrop) {
31 if (details.open && !isDesktop()) {
32 backdrop.classList.remove('opacity-0', 'pointer-events-none');
33 backdrop.classList.add('opacity-100', 'pointer-events-auto');
34 document.body.style.overflow = 'hidden';
35 } else {
36 backdrop.classList.remove('opacity-100', 'pointer-events-auto');
37 backdrop.classList.add('opacity-0', 'pointer-events-none');
38 document.body.style.overflow = '';
39 }
40 }
41 };
42
43 // close on mobile initially
44 if (!isDesktop()) {
45 details.open = false;
46 }
47 updateBackdrop(); // initialize backdrop
48
49 // prevent closing on desktop
50 details.addEventListener('toggle', function(e) {
51 if (isDesktop() && !this.open) {
52 this.open = true;
53 }
54 updateBackdrop();
55 });
56
57 const mediaQuery = window.matchMedia('(min-width: 768px)');
58 mediaQuery.addEventListener('change', function(e) {
59 if (e.matches) {
60 // switched to desktop - keep open
61 details.open = true;
62 } else {
63 // switched to mobile - close
64 details.open = false;
65 }
66 updateBackdrop();
67 });
68
69 // close when clicking backdrop
70 if (backdrop) {
71 backdrop.addEventListener('click', () => {
72 if (!isDesktop()) {
73 details.open = false;
74 }
75 });
76 }
77 })();
78 </script>
79{{ end }}
80
81{{ define "repoContentLayout" }}
82 <div class="grid grid-cols-1 md:grid-cols-10 gap-4 w-full">
83 <section class="bg-white col-span-1 md:col-span-8 dark:bg-gray-800 p-6 rounded relative w-full mx-auto dark:text-white h-full flex-shrink">
84 {{ block "repoContent" . }}{{ end }}
85 </section>
86 <div class="flex flex-col gap-6 col-span-1 md:col-span-2">
87 {{ template "repo/fragments/labelPanel"
88 (dict "RepoInfo" $.RepoInfo
89 "Defs" $.LabelDefs
90 "Subject" $.Pull.AtUri
91 "State" $.Pull.Labels) }}
92 {{ template "repo/fragments/participants" $.Pull.Participants }}
93 {{ template "repo/fragments/backlinks"
94 (dict "RepoInfo" $.RepoInfo
95 "Backlinks" $.Backlinks) }}
96 {{ template "repo/fragments/externalLinkPanel" $.Pull.AtUri }}
97 </div>
98 </div>
99{{ end }}
100
101{{ define "contentAfter" }}
102 {{ template "repo/fragments/diff" (list .Diff .DiffOpts $) }}
103{{ end }}
104
105{{ define "repoContent" }}
106 {{ template "repo/pulls/fragments/pullHeader" . }}
107 {{ if .Pull.IsStacked }}
108 <div class="mt-8">
109 {{ template "repo/pulls/fragments/pullStack" . }}
110 </div>
111 {{ end }}
112{{ end }}
113
114{{ define "diffLayout" }}
115 {{ $diff := index . 0 }}
116 {{ $opts := index . 1 }}
117 {{ $root := index . 2 }}
118
119 <div class="flex col-span-full">
120 <!-- left panel -->
121 <div id="files" class="w-0 hidden md:block overflow-hidden sticky top-12 max-h-screen overflow-y-auto pb-12">
122 <section class="overflow-x-auto text-sm px-6 py-2 border-b border-x border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded-b rounded-t-none bg-white dark:bg-gray-800 drop-shadow-sm">
123 {{ template "repo/fragments/fileTree" $diff.FileTree }}
124 </section>
125 </div>
126
127 <!-- main content -->
128 <div class="flex-1 min-w-0 sticky top-12 pb-12">
129 {{ template "diffFiles" (list $diff $opts) }}
130 </div>
131
132 <!-- right panel -->
133 {{ template "subsPanel" $ }}
134 </div>
135{{ end }}
136
137{{ define "subsPanel" }}
138 {{ $root := index . 2 }}
139 {{ $pull := $root.Pull }}
140 <!-- backdrop overlay - only visible on mobile when open -->
141 <div id="bottomSheetBackdrop" class="fixed inset-0 bg-black/50 md:hidden opacity-0 pointer-events-none transition-opacity duration-300 z-40"></div>
142 <!-- right panel - bottom sheet on mobile, side panel on desktop -->
143 <div id="subs" class="fixed bottom-0 left-0 right-0 z-50 w-full md:static md:z-auto md:max-h-screen md:sticky md:top-12 overflow-hidden">
144 <details open id="bottomSheet" class="rounded-t-2xl md:rounded-t drop-shadow-lg md:drop-shadow-none group/panel">
145 <summary class="
146 flex gap-4 items-center justify-between
147 rounded-t-2xl md:rounded-t cursor-pointer list-none p-4 md:h-12
148 text-white md:text-black md:dark:text-white
149 bg-green-600 dark:bg-green-700
150 md:bg-white md:dark:bg-gray-800
151 drop-shadow-sm
152 border-t md:border-x md:border-t-0 border-gray-200 dark:border-gray-700">
153 <h2 class="">History</h2>
154 {{ template "subsPanelSummary" $ }}
155 </summary>
156 <div class="max-h-[85vh] md:max-h-[calc(100vh-3rem-3rem)] w-full flex flex-col-reverse gap-4 overflow-y-auto bg-slate-100 dark:bg-gray-900 md:bg-transparent">
157 {{ template "submissions" $root }}
158 </div>
159 </details>
160 </div>
161{{ end }}
162
163{{ define "subsPanelSummary" }}
164 {{ $root := index . 2 }}
165 {{ $pull := $root.Pull }}
166 {{ $rounds := len $pull.Submissions }}
167 {{ $comments := $pull.TotalComments }}
168 <div class="flex items-center gap-2 text-sm">
169 <span>
170 {{ $rounds }} round{{ if ne $rounds 1 }}s{{ end }}
171 </span>
172 <span class="select-none before:content-['\00B7']"></span>
173 <span>
174 {{ $comments }} comment{{ if ne $comments 1 }}s{{ end }}
175 </span>
176
177 <span class="md:hidden inline">
178 <span class="inline group-open:hidden">{{ i "chevron-up" "size-4" }}</span>
179 <span class="hidden group-open:inline">{{ i "chevron-down" "size-4" }}</span>
180 </span>
181 </div>
182{{ end }}
183
184{{ define "subsCheckbox" }}
185 <input type="checkbox" id="subsToggle" class="peer/subs hidden" checked/>
186{{ end }}
187
188{{ define "subsToggle" }}
189 <style>
190 /* Mobile: full width */
191 #subsToggle:checked ~ div div#subs {
192 width: 100%;
193 margin-left: 0;
194 }
195 #subsToggle:checked ~ div label[for="subsToggle"] .show-toggle { display: none; }
196 #subsToggle:checked ~ div label[for="subsToggle"] .hide-toggle { display: flex; }
197 #subsToggle:not(:checked) ~ div label[for="subsToggle"] .hide-toggle { display: none; }
198
199 /* Desktop: 25vw with left margin */
200 @media (min-width: 768px) {
201 #subsToggle:checked ~ div div#subs {
202 width: 25vw;
203 margin-left: 1rem;
204 }
205 /* Unchecked state */
206 #subsToggle:not(:checked) ~ div div#subs {
207 width: 0;
208 display: none;
209 margin-left: 0;
210 }
211 }
212 </style>
213 <label title="Toggle review panel" for="subsToggle" class="hidden md:flex items-center justify-end rounded cursor-pointer">
214 <span class="show-toggle">{{ i "message-square-more" "size-4" }}</span>
215 <span class="hide-toggle w-[25vw] flex justify-end">{{ i "message-square" "size-4" }}</span>
216 </label>
217{{ end }}
218
219
220{{ define "submissions" }}
221 {{ $lastIdx := sub (len .Pull.Submissions) 1 }}
222 {{ if not .LoggedInUser }}
223 {{ template "loginPrompt" $ }}
224 {{ end }}
225 {{ range $ridx, $item := reverse .Pull.Submissions }}
226 {{ $idx := sub $lastIdx $ridx }}
227 {{ template "submission" (list $item $idx $lastIdx $) }}
228 {{ end }}
229{{ end }}
230
231{{ define "submission" }}
232 {{ $item := index . 0 }}
233 {{ $idx := index . 1 }}
234 {{ $lastIdx := index . 2 }}
235 {{ $root := index . 3 }}
236 {{ $round := $item.RoundNumber }}
237 <div class="
238 w-full shadow-sm bg-gray-50 dark:bg-gray-900 border-2 border-t-0
239 {{ if eq $round 0 }}rounded-b{{ else }}rounded{{ end }}
240 {{ if eq $round $root.ActiveRound }}
241 border-blue-200 dark:border-blue-700
242 {{ else }}
243 border-gray-200 dark:border-gray-700
244 {{ end }}
245 ">
246 {{ template "submissionHeader" $ }}
247 {{ template "submissionComments" $ }}
248 </div>
249{{ end }}
250
251{{ define "submissionHeader" }}
252 {{ $item := index . 0 }}
253 {{ $lastIdx := index . 2 }}
254 {{ $root := index . 3 }}
255 {{ $round := $item.RoundNumber }}
256 <div class="
257 {{ if eq $round 0 }}rounded-b{{ else }}rounded{{ end }}
258 px-6 py-4 pr-2 pt-2
259 bg-white dark:bg-gray-800
260 {{ if eq $round $root.ActiveRound }}
261 border-t-2 border-blue-200 dark:border-blue-700
262 {{ else }}
263 border-b-2 border-gray-200 dark:border-gray-700
264 {{ end }}
265 flex gap-2 sticky top-0 z-20">
266 <!-- left column: just profile picture -->
267 <div class="flex-shrink-0 pt-2">
268 {{ template "user/fragments/picLink" (list $root.Pull.OwnerDid "size-8") }}
269 </div>
270 <!-- right column -->
271 <div class="flex-1 min-w-0 flex flex-col gap-1">
272 {{ template "submissionInfo" $ }}
273 {{ template "submissionCommits" $ }}
274 {{ template "submissionPipeline" $ }}
275 {{ if eq $lastIdx $round }}
276 {{ block "mergeCheck" $root }} {{ end }}
277 {{ end }}
278 </div>
279 </div>
280{{ end }}
281
282{{ define "submissionInfo" }}
283 {{ $item := index . 0 }}
284 {{ $idx := index . 1 }}
285 {{ $root := index . 3 }}
286 {{ $round := $item.RoundNumber }}
287 <div class="flex gap-2 items-center justify-between mb-1">
288 <span class="inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 pt-2">
289 {{ $handle := resolve $root.Pull.OwnerDid }}
290 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="/{{ $handle }}">{{ $handle }}</a>
291 submitted
292 <span class="px-2 py-0.5 text-black dark:text-white bg-gray-100 dark:bg-gray-700 border-gray-300 dark:border-gray-600 rounded font-mono text-xs border">
293 #{{ $round }}
294 </span>
295 <span class="select-none before:content-['\00B7']"></span>
296 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500" href="#round-#{{ $round }}">
297 {{ template "repo/fragments/shortTime" $item.Created }}
298 </a>
299 </span>
300 <div class="flex gap-2 items-center">
301 {{ if ne $root.ActiveRound $round }}
302 <a class="btn-flat flex items-center gap-2 no-underline hover:no-underline text-sm"
303 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $round }}?{{ safeUrl $root.DiffOpts.Encode }}#round-#{{ $round }}">
304 {{ i "diff" "w-4 h-4" }}
305 diff
306 </a>
307 {{ end }}
308 {{ if ne $idx 0 }}
309 <a class="btn-flat flex items-center gap-2 no-underline hover:no-underline text-sm"
310 href="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $round }}/interdiff?{{ safeUrl $root.DiffOpts.Encode }}">
311 {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }}
312 interdiff
313 </a>
314 {{ end }}
315 </div>
316 </div>
317{{ end }}
318
319{{ define "submissionCommits" }}
320 {{ $item := index . 0 }}
321 {{ $root := index . 3 }}
322 {{ $round := $item.RoundNumber }}
323 {{ $patches := $item.AsFormatPatch }}
324 {{ if $patches }}
325 <details class="group/commit">
326 <summary class="list-none cursor-pointer flex items-center gap-2">
327 <span>{{ i "git-commit-horizontal" "w-4 h-4" }}</span>
328 {{ len $patches }} commit{{ if ne (len $patches) 1 }}s{{ end }}
329 <div class="text-sm text-gray-500 dark:text-gray-400">
330 <span class="group-open/commit:hidden inline">expand</span>
331 <span class="hidden group-open/commit:inline">collapse</span>
332 </div>
333 </summary>
334 {{ range $patches }}
335 {{ template "submissionCommit" (list . $item $root) }}
336 {{ end }}
337 </details>
338 {{ end }}
339{{ end }}
340
341{{ define "submissionCommit" }}
342 {{ $patch := index . 0 }}
343 {{ $item := index . 1 }}
344 {{ $root := index . 2 }}
345 {{ $round := $item.RoundNumber }}
346 {{ with $patch }}
347 <div id="commit-{{.SHA}}" class="py-1 relative w-full md:max-w-3/5 md:w-fit flex flex-col text-gray-600 dark:text-gray-300">
348 <div class="flex items-baseline gap-2">
349 <div class="text-xs">
350 <!-- attempt to resolve $fullRepo: this is possible only on non-deleted forks and branches -->
351 {{ $fullRepo := "" }}
352 {{ if and $root.Pull.IsForkBased $root.Pull.PullSource.Repo }}
353 {{ $fullRepo = printf "%s/%s" $root.Pull.OwnerDid $root.Pull.PullSource.Repo.Name }}
354 {{ else if $root.Pull.IsBranchBased }}
355 {{ $fullRepo = $root.RepoInfo.FullName }}
356 {{ end }}
357
358 <!-- if $fullRepo was resolved, link to it, otherwise just span without a link -->
359 {{ if $fullRepo }}
360 <a href="/{{ $fullRepo }}/commit/{{ .SHA }}" class="font-mono text-gray-600 dark:text-gray-300">{{ slice .SHA 0 8 }}</a>
361 {{ else }}
362 <span class="font-mono">{{ slice .SHA 0 8 }}</span>
363 {{ end }}
364 </div>
365
366 <div>
367 <span>{{ .Title | description }}</span>
368 {{ if gt (len .Body) 0 }}
369 <button
370 class="py-1/2 px-1 mx-2 bg-gray-200 hover:bg-gray-400 rounded dark:bg-gray-700 dark:hover:bg-gray-600"
371 hx-on:click="document.getElementById('body-{{$round}}-{{.SHA}}').classList.toggle('hidden')"
372 >
373 {{ i "ellipsis" "w-3 h-3" }}
374 </button>
375 {{ end }}
376 {{ if gt (len .Body) 0 }}
377 <p id="body-{{$round}}-{{.SHA}}" class="hidden mt-1 pb-2">{{ nl2br .Body }}</p>
378 {{ end }}
379 </div>
380 </div>
381 </div>
382 {{ end }}
383{{ end }}
384
385{{ define "mergeCheck" }}
386 {{ $isOpen := .Pull.State.IsOpen }}
387 {{ if and $isOpen .MergeCheck .MergeCheck.Error }}
388 <div class="flex items-center gap-2">
389 {{ i "triangle-alert" "w-4 h-4 text-red-600 dark:text-red-500" }}
390 {{ .MergeCheck.Error }}
391 </div>
392 {{ else if and $isOpen .MergeCheck .MergeCheck.IsConflicted }}
393 <details class="group/conflict">
394 <summary class="flex items-center justify-between cursor-pointer list-none">
395 <div class="flex items-center gap-2 ">
396 {{ i "triangle-alert" "text-red-600 dark:text-red-500 w-4 h-4" }}
397 <span class="font-medium">merge conflicts detected</span>
398 <div class="text-sm text-gray-500 dark:text-gray-400">
399 <span class="group-open/conflict:hidden inline">expand</span>
400 <span class="hidden group-open/conflict:inline">collapse</span>
401 </div>
402 </div>
403 </summary>
404 {{ if gt (len .MergeCheck.Conflicts) 0 }}
405 <ul class="space-y-1 mt-2 overflow-x-auto">
406 {{ range .MergeCheck.Conflicts }}
407 {{ if .Filename }}
408 <li class="flex items-center whitespace-nowrap">
409 {{ i "file-warning" "inline-flex w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 flex-shrink-0" }}
410 <span class="font-mono">{{ .Filename }}</span>
411 </li>
412 {{ else if .Reason }}
413 <li class="flex items-center whitespace-nowrap">
414 {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 " }}
415 <span>{{.Reason}}</span>
416 </li>
417 {{ end }}
418 {{ end }}
419 </ul>
420 {{ end }}
421 </details>
422 {{ else if and $isOpen .MergeCheck }}
423 <div class="flex items-center gap-2">
424 {{ i "check" "w-4 h-4 text-green-600 dark:text-green-500" }}
425 <span>no conflicts, ready to merge</span>
426 </div>
427 {{ end }}
428{{ end }}
429
430{{ define "mergeStatus" }}
431 {{ if .Pull.State.IsClosed }}
432 <div class="bg-gray-50 dark:bg-gray-700 border border-black dark:border-gray-500 rounded drop-shadow-sm px-6 py-2 relative">
433 <div class="flex items-center gap-2 text-black dark:text-white">
434 {{ i "ban" "w-4 h-4" }}
435 <span class="font-medium">closed without merging</span
436 >
437 </div>
438 </div>
439 {{ else if .Pull.State.IsMerged }}
440 <div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative">
441 <div class="flex items-center gap-2 text-purple-500 dark:text-purple-300">
442 {{ i "git-merge" "w-4 h-4" }}
443 <span class="font-medium">pull request successfully merged</span
444 >
445 </div>
446 </div>
447 {{ else if .Pull.State.IsDeleted }}
448 <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative">
449 <div class="flex items-center gap-2 text-red-500 dark:text-red-300">
450 {{ i "git-pull-request-closed" "w-4 h-4" }}
451 <span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span>
452 </div>
453 </div>
454 {{ end }}
455{{ end }}
456
457{{ define "resubmitStatus" }}
458 {{ if .ResubmitCheck.Yes }}
459 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative">
460 <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
461 {{ i "triangle-alert" "w-4 h-4" }}
462 <span class="font-medium">this branch has been updated, consider resubmitting</span>
463 </div>
464 </div>
465 {{ end }}
466{{ end }}
467
468{{ define "submissionPipeline" }}
469 {{ $item := index . 0 }}
470 {{ $root := index . 3 }}
471 {{ $pipeline := index $root.Pipelines $item.SourceRev }}
472 {{ with $pipeline }}
473 {{ $id := .Id }}
474 {{ if .Statuses }}
475 <details class="group/pipeline">
476 <summary class="cursor-pointer list-none flex items-center gap-2">
477 {{ template "repo/pipelines/fragments/pipelineSymbol" (dict "Pipeline" $pipeline "ShortSummary" false) }}
478 <div class="text-sm text-gray-500 dark:text-gray-400">
479 <span class="group-open/pipeline:hidden inline">expand</span>
480 <span class="hidden group-open/pipeline:inline">collapse</span>
481 </div>
482 </summary>
483 <div class="my-2 grid grid-cols-1 bg-white dark:bg-gray-800 rounded border border-gray-200 dark:border-gray-700 divide-y divide-gray-200 dark:divide-gray-700">
484 {{ range $name, $all := .Statuses }}
485 <a href="/{{ $root.RepoInfo.FullName }}/pipelines/{{ $id }}/workflow/{{ $name }}" class="no-underline hover:no-underline hover:bg-gray-100/25 hover:dark:bg-gray-700/25">
486 <div
487 class="flex gap-2 items-center justify-between p-2">
488 {{ $lastStatus := $all.Latest }}
489 {{ $kind := $lastStatus.Status.String }}
490
491 <div id="left" class="flex items-center gap-2 flex-shrink-0">
492 {{ template "repo/pipelines/fragments/workflowSymbol" $all }}
493 {{ $name }}
494 </div>
495 <div id="right" class="flex items-center gap-2 flex-shrink-0">
496 <span class="font-bold">{{ $kind }}</span>
497 {{ if .TimeTaken }}
498 {{ template "repo/fragments/duration" .TimeTaken }}
499 {{ else }}
500 {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }}
501 {{ end }}
502 </div>
503 </div>
504 </a>
505 {{ end }}
506 </div>
507 </details>
508 {{ end }}
509 {{ end }}
510{{ end }}
511
512{{ define "submissionComments" }}
513 {{ $item := index . 0 }}
514 {{ $idx := index . 1 }}
515 {{ $lastIdx := index . 2 }}
516 {{ $root := index . 3 }}
517 {{ $round := $item.RoundNumber }}
518 {{ $c := len $item.Comments }}
519 <details class="relative ml-10 group/comments" {{ if or (eq $c 0) (eq $root.ActiveRound $round) }}open{{ end }}>
520 <summary class="cursor-pointer list-none">
521 <div class="hidden group-open/comments:block absolute -left-8 top-0 bottom-0 w-16 transition-colors flex items-center justify-center group/border z-4">
522 <div class="absolute left-1/2 -translate-x-1/2 top-0 bottom-0 w-0.5 group-open/comments:bg-gray-200 dark:group-open/comments:bg-gray-700 group-hover/border:bg-gray-400 dark:group-hover/border:bg-gray-500 transition-colors"> </div>
523 </div>
524 <div class="group-open/comments:hidden block relative group/summary py-4">
525 <div class="absolute -left-8 top-0 bottom-0 w-16 transition-colors flex items-center justify-center z-4">
526 <div class="absolute left-1/2 -translate-x-1/2 h-1/3 top-0 bottom-0 w-0.5 bg-gray-200 dark:bg-gray-700 group-hover/summary:bg-gray-400 dark:group-hover/summary:bg-gray-500 transition-colors"></div>
527 </div>
528 <span class="text-gray-500 dark:text-gray-400 text-sm group-hover/summary:text-gray-600 dark:group-hover/summary:text-gray-300 transition-colors flex items-center gap-2 -ml-2 relative">
529 {{ i "circle-plus" "size-4 z-5" }}
530 expand {{ $c }} comment{{ if ne $c 1 }}s{{ end }}
531 </span>
532 </div>
533 </summary>
534 <div>
535 {{ range $item.Comments }}
536 {{ template "submissionComment" . }}
537 {{ end }}
538 </div>
539
540 <div class="relative -ml-10">
541 {{ if eq $lastIdx $item.RoundNumber }}
542 {{ block "mergeStatus" $root }} {{ end }}
543 {{ block "resubmitStatus" $root }} {{ end }}
544 {{ end }}
545 </div>
546 <div class="relative -ml-10 bg-gray-50 dark:bg-gray-900">
547 {{ if $root.LoggedInUser }}
548 {{ template "repo/pulls/fragments/pullActions"
549 (dict
550 "LoggedInUser" $root.LoggedInUser
551 "Pull" $root.Pull
552 "RepoInfo" $root.RepoInfo
553 "RoundNumber" $item.RoundNumber
554 "MergeCheck" $root.MergeCheck
555 "ResubmitCheck" $root.ResubmitCheck
556 "BranchDeleteStatus" $root.BranchDeleteStatus
557 "Stack" $root.Stack) }}
558 {{ end }}
559 </div>
560 </details>
561{{ end }}
562
563{{ define "submissionComment" }}
564 <div id="comment-{{.ID}}" class="flex gap-2 -ml-4 py-4 w-full mx-auto">
565 <!-- left column: profile picture -->
566 <div class="flex-shrink-0 h-fit relative">
567 {{ template "user/fragments/picLink" (list .OwnerDid "size-8") }}
568 </div>
569 <!-- right column: name and body in two rows -->
570 <div class="flex-1 min-w-0">
571 <!-- Row 1: Author and timestamp -->
572 <div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
573 {{ $handle := resolve .OwnerDid }}
574 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="/{{ $handle }}">{{ $handle }}</a>
575 <span class="before:content-['·']"></span>
576 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.ID}}">
577 {{ template "repo/fragments/shortTime" .Created }}
578 </a>
579 </div>
580 <!-- Row 2: Body text -->
581 <div class="prose dark:prose-invert mt-1">
582 {{ .Body | markdown }}
583 </div>
584 </div>
585 </div>
586{{ end }}
587
588{{ define "loginPrompt" }}
589 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm p-2 relative flex gap-2 items-center">
590 <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
591 sign up
592 </a>
593 <span class="text-gray-500 dark:text-gray-400">or</span>
594 <a href="/login" class="underline">login</a>
595 to add to the discussion
596 </div>
597{{ end }}