Monorepo for Tangled
at c983de83b074b714a29de09dee195dc8e9f63107 597 lines 23 kB view raw
1{{ define "title" }} 2 {{ .Pull.Title }} &middot; pull #{{ .Pull.PullId }} &middot; {{ .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 }}