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 "repoContentLayout" }}
10 <div class="grid grid-cols-1 md:grid-cols-10 gap-4 w-full">
11 <div class="col-span-1 md:col-span-8">
12 <section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto dark:text-white">
13 {{ block "repoContent" . }}{{ end }}
14 </section>
15 {{ block "repoAfter" . }}{{ end }}
16 </div>
17 <div class="col-span-1 md:col-span-2 flex flex-col gap-6">
18 {{ template "repo/fragments/labelPanel"
19 (dict "RepoInfo" $.RepoInfo
20 "Defs" $.LabelDefs
21 "Subject" $.Pull.PullAt
22 "State" $.Pull.Labels) }}
23 {{ template "repo/fragments/participants" $.Pull.Participants }}
24 </div>
25 </div>
26{{ end }}
27
28{{ define "repoContent" }}
29 {{ template "repo/pulls/fragments/pullHeader" . }}
30
31 {{ if .Pull.IsStacked }}
32 <div class="mt-8">
33 {{ template "repo/pulls/fragments/pullStack" . }}
34 </div>
35 {{ end }}
36{{ end }}
37
38{{ define "repoAfter" }}
39 <section id="submissions" class="mt-4">
40 <div class="flex flex-col gap-4">
41 {{ block "submissions" . }} {{ end }}
42 </div>
43 </section>
44
45 <div id="pull-close"></div>
46 <div id="pull-reopen"></div>
47{{ end }}
48
49{{ define "submissions" }}
50 {{ $lastIdx := sub (len .Pull.Submissions) 1 }}
51 {{ $targetBranch := .Pull.TargetBranch }}
52 {{ $repoName := .RepoInfo.FullName }}
53 {{ range $idx, $item := .Pull.Submissions }}
54 {{ with $item }}
55 <details {{ if eq $idx $lastIdx }}open{{ end }}>
56 <summary id="round-#{{ .RoundNumber }}" class="list-none cursor-pointer">
57 <div class="flex flex-wrap gap-2 items-stretch">
58 <!-- round number -->
59 <div class="rounded bg-white dark:bg-gray-800 drop-shadow-sm px-3 py-2 dark:text-white">
60 <span class="flex items-center">{{ i "hash" "w-4 h-4" }}{{ .RoundNumber }}</span>
61 </div>
62 <!-- round summary -->
63 <div class="flex-1 rounded drop-shadow-sm bg-white dark:bg-gray-800 p-2 text-gray-500 dark:text-gray-400">
64 <span class="gap-1 flex items-center">
65 {{ $owner := resolve $.Pull.OwnerDid }}
66 {{ $re := "re" }}
67 {{ if eq .RoundNumber 0 }}
68 {{ $re = "" }}
69 {{ end }}
70 <span class="hidden md:inline">{{$re}}submitted</span>
71 by {{ template "user/fragments/picHandleLink" $.Pull.OwnerDid }}
72 <span class="select-none before:content-['\00B7']"></span>
73 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500" href="#round-#{{ .RoundNumber }}">{{ template "repo/fragments/shortTime" .Created }}</a>
74 <span class="select-none before:content-['·']"></span>
75 {{ $s := "s" }}
76 {{ if eq (len .Comments) 1 }}
77 {{ $s = "" }}
78 {{ end }}
79 {{ len .Comments }} comment{{$s}}
80 </span>
81 </div>
82
83 <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group"
84 hx-boost="true"
85 href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}">
86 {{ i "file-diff" "w-4 h-4" }}
87 <span class="hidden md:inline">diff</span>
88 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
89 </a>
90 {{ if ne $idx 0 }}
91 <a class="btn flex items-center gap-2 no-underline hover:no-underline p-2 group"
92 hx-boost="true"
93 href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{.RoundNumber}}/interdiff">
94 {{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }}
95 <span class="hidden md:inline">interdiff</span>
96 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
97 </a>
98 {{ end }}
99 <span id="interdiff-error-{{.RoundNumber}}"></span>
100 </div>
101 </summary>
102
103 {{ if .IsFormatPatch }}
104 {{ $patches := .AsFormatPatch }}
105 {{ $round := .RoundNumber }}
106 <details class="group py-2 md:ml-[3.5rem] text-gray-500 dark:text-gray-400 flex flex-col gap-2 relative text-sm">
107 <summary class="py-1 list-none cursor-pointer hover:text-gray-500 hover:dark:text-gray-400">
108 {{ $s := "s" }}
109 {{ if eq (len $patches) 1 }}
110 {{ $s = "" }}
111 {{ end }}
112 <div class="group-open:hidden flex items-center gap-2 ml-2">
113 {{ i "chevrons-up-down" "w-4 h-4" }} expand {{ len $patches }} commit{{$s}}
114 </div>
115 <div class="hidden group-open:flex items-center gap-2 ml-2">
116 {{ i "chevrons-down-up" "w-4 h-4" }} hide {{ len $patches }} commit{{$s}}
117 </div>
118 </summary>
119 {{ range $patches }}
120 <div id="commit-{{.SHA}}" class="py-1 px-2 relative w-full md:max-w-3/5 md:w-fit flex flex-col">
121 <div class="flex items-center gap-2">
122 {{ i "git-commit-horizontal" "w-4 h-4" }}
123 <div class="text-sm text-gray-500 dark:text-gray-400">
124 <!-- attempt to resolve $fullRepo: this is possible only on non-deleted forks and branches -->
125 {{ $fullRepo := "" }}
126 {{ if and $.Pull.IsForkBased $.Pull.PullSource.Repo }}
127 {{ $fullRepo = printf "%s/%s" $owner $.Pull.PullSource.Repo.Name }}
128 {{ else if $.Pull.IsBranchBased }}
129 {{ $fullRepo = $.RepoInfo.FullName }}
130 {{ end }}
131
132 <!-- if $fullRepo was resolved, link to it, otherwise just span without a link -->
133 {{ if $fullRepo }}
134 <a href="/{{ $fullRepo }}/commit/{{ .SHA }}" class="font-mono text-gray-500 dark:text-gray-400">{{ slice .SHA 0 8 }}</a>
135 {{ else }}
136 <span class="font-mono">{{ slice .SHA 0 8 }}</span>
137 {{ end }}
138 </div>
139 <div class="flex items-center">
140 <span>{{ .Title | description }}</span>
141 {{ if gt (len .Body) 0 }}
142 <button
143 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"
144 hx-on:click="document.getElementById('body-{{$round}}-{{.SHA}}').classList.toggle('hidden')"
145 >
146 {{ i "ellipsis" "w-3 h-3" }}
147 </button>
148 {{ end }}
149 </div>
150 </div>
151 {{ if gt (len .Body) 0 }}
152 <p id="body-{{$round}}-{{.SHA}}" class="hidden mt-1 text-sm pb-2">
153 {{ nl2br .Body }}
154 </p>
155 {{ end }}
156 </div>
157 {{ end }}
158 </details>
159 {{ end }}
160
161
162 <div class="md:pl-[3.5rem] flex flex-col gap-2 mt-2 relative">
163 {{ range $cidx, $c := .Comments }}
164 <div id="comment-{{$c.ID}}" class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-2 px-4 relative w-full">
165 {{ if gt $cidx 0 }}
166 <div class="absolute left-8 -top-2 w-px h-2 bg-gray-300 dark:bg-gray-600"></div>
167 {{ end }}
168 <div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
169 {{ template "user/fragments/picHandleLink" $c.OwnerDid }}
170 <span class="before:content-['·']"></span>
171 <a class="text-gray-500 dark:text-gray-400 hover:text-gray-500 dark:hover:text-gray-300" href="#comment-{{.ID}}">{{ template "repo/fragments/time" $c.Created }}</a>
172 </div>
173 <div class="prose dark:prose-invert">
174 {{ $c.Body | markdown }}
175 </div>
176 </div>
177 {{ end }}
178
179 {{ block "pipelineStatus" (list $ .) }} {{ end }}
180
181 {{ if eq $lastIdx .RoundNumber }}
182 {{ block "mergeStatus" $ }} {{ end }}
183 {{ block "resubmitStatus" $ }} {{ end }}
184 {{ end }}
185
186 {{ if $.LoggedInUser }}
187 {{ template "repo/pulls/fragments/pullActions"
188 (dict
189 "LoggedInUser" $.LoggedInUser
190 "Pull" $.Pull
191 "RepoInfo" $.RepoInfo
192 "RoundNumber" .RoundNumber
193 "MergeCheck" $.MergeCheck
194 "ResubmitCheck" $.ResubmitCheck
195 "BranchDeleteStatus" $.BranchDeleteStatus
196 "Stack" $.Stack) }}
197 {{ else }}
198 <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 w-fit">
199 <a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
200 sign up
201 </a>
202 <span class="text-gray-500 dark:text-gray-400">or</span>
203 <a href="/login" class="underline">login</a>
204 to add to the discussion
205 </div>
206 {{ end }}
207 </div>
208 </details>
209 {{ end }}
210 {{ end }}
211{{ end }}
212
213{{ define "mergeStatus" }}
214 {{ if .Pull.State.IsClosed }}
215 <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 w-fit">
216 <div class="flex items-center gap-2 text-black dark:text-white">
217 {{ i "ban" "w-4 h-4" }}
218 <span class="font-medium">closed without merging</span
219 >
220 </div>
221 </div>
222 {{ else if .Pull.State.IsMerged }}
223 <div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
224 <div class="flex items-center gap-2 text-purple-500 dark:text-purple-300">
225 {{ i "git-merge" "w-4 h-4" }}
226 <span class="font-medium">pull request successfully merged</span
227 >
228 </div>
229 </div>
230 {{ else if .Pull.State.IsDeleted }}
231 <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
232 <div class="flex items-center gap-2 text-red-500 dark:text-red-300">
233 {{ i "git-pull-request-closed" "w-4 h-4" }}
234 <span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span>
235 </div>
236 </div>
237 {{ else if and .MergeCheck .MergeCheck.Error }}
238 <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
239 <div class="flex items-center gap-2 text-red-500 dark:text-red-300">
240 {{ i "triangle-alert" "w-4 h-4" }}
241 <span class="font-medium">{{ .MergeCheck.Error }}</span>
242 </div>
243 </div>
244 {{ else if and .MergeCheck .MergeCheck.IsConflicted }}
245 <div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
246 <div class="flex flex-col gap-2 text-red-500 dark:text-red-300">
247 <div class="flex items-center gap-2">
248 {{ i "triangle-alert" "w-4 h-4" }}
249 <span class="font-medium">merge conflicts detected</span>
250 </div>
251 {{ if gt (len .MergeCheck.Conflicts) 0 }}
252 <ul class="space-y-1">
253 {{ range .MergeCheck.Conflicts }}
254 {{ if .Filename }}
255 <li class="flex items-center">
256 {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }}
257 <span class="font-mono">{{ .Filename }}</span>
258 </li>
259 {{ else if .Reason }}
260 <li class="flex items-center">
261 {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }}
262 <span>{{.Reason}}</span>
263 </li>
264 {{ end }}
265 {{ end }}
266 </ul>
267 {{ end }}
268 </div>
269 </div>
270 {{ else if .MergeCheck }}
271 <div class="bg-green-50 dark:bg-green-900 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
272 <div class="flex items-center gap-2 text-green-500 dark:text-green-300">
273 {{ i "circle-check-big" "w-4 h-4" }}
274 <span class="font-medium">no conflicts, ready to merge</span>
275 </div>
276 </div>
277 {{ end }}
278{{ end }}
279
280{{ define "resubmitStatus" }}
281 {{ if .ResubmitCheck.Yes }}
282 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
283 <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
284 {{ i "triangle-alert" "w-4 h-4" }}
285 <span class="font-medium">this branch has been updated, consider resubmitting</span>
286 </div>
287 </div>
288 {{ end }}
289{{ end }}
290
291{{ define "pipelineStatus" }}
292 {{ $root := index . 0 }}
293 {{ $submission := index . 1 }}
294 {{ $pipeline := index $root.Pipelines $submission.SourceRev }}
295 {{ with $pipeline }}
296 {{ $id := .Id }}
297 {{ if .Statuses }}
298 <div class="max-w-80 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">
299 {{ range $name, $all := .Statuses }}
300 <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">
301 <div
302 class="flex gap-2 items-center justify-between p-2">
303 {{ $lastStatus := $all.Latest }}
304 {{ $kind := $lastStatus.Status.String }}
305
306 <div id="left" class="flex items-center gap-2 flex-shrink-0">
307 {{ template "repo/pipelines/fragments/workflowSymbol" $all }}
308 {{ $name }}
309 </div>
310 <div id="right" class="flex items-center gap-2 flex-shrink-0">
311 <span class="font-bold">{{ $kind }}</span>
312 {{ if .TimeTaken }}
313 {{ template "repo/fragments/duration" .TimeTaken }}
314 {{ else }}
315 {{ template "repo/fragments/shortTimeAgo" $lastStatus.Created }}
316 {{ end }}
317 </div>
318 </div>
319 </a>
320 {{ end }}
321 </div>
322 {{ end }}
323 {{ end }}
324{{ end }}