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