This repository has no description
1{{ define "repo/pulls/fragments/pullActions" }}
2 {{ $lastIdx := sub (len .Pull.Submissions) 1 }}
3 {{ $roundNumber := .RoundNumber }}
4 {{ $stack := .Stack }}
5 {{ $loading := .Loading }}
6
7 {{ $totalPulls := sub 0 1 }}
8 {{ $below := sub 0 1 }}
9 {{ $stackCount := "" }}
10 {{ if (gt (len .Stack) 1) }}
11 {{ $totalPulls = len $stack }}
12 {{ $below = $stack.Below .Pull }}
13 {{ $mergeable := len $below.Mergeable }}
14 {{ $stackCount = printf "%d/%d" $mergeable $totalPulls }}
15 {{ end }}
16
17 {{ $isPushAllowed := .RepoInfo.Roles.IsPushAllowed }}
18 {{ $isMerged := .Pull.State.IsMerged }}
19 {{ $isClosed := .Pull.State.IsClosed }}
20 {{ $isOpen := .Pull.State.IsOpen }}
21 {{ $isConflicted := and .MergeCheck (or .MergeCheck.Error .MergeCheck.IsConflicted) }}
22 {{ $isPullAuthor := and .LoggedInUser (eq .LoggedInUser.Did .Pull.OwnerDid) }}
23 {{ $isLastRound := eq $roundNumber $lastIdx }}
24 {{ $isSameRepoBranch := .Pull.IsBranchBased }}
25 {{ $isUpToDate := .ResubmitCheck.No }}
26 {{ $isForkBased := .Pull.IsForkBased }}
27 {{ $showRunCI := and (not $loading) $isPushAllowed $isOpen $isLastRound $isForkBased (not .HasPipeline) (ne .RepoInfo.Spindle "") }}
28
29 <div id="action-card-{{$roundNumber}}" class="{{ if .LoggedInUser }}relative p-2 flex flex-col gap-2{{ else }}hidden{{ end }}"
30 {{ if $loading }}
31 hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/actions"
32 hx-trigger="load"
33 hx-swap="outerHTML"
34 hx-target="this"
35 {{ end }}
36 >
37 {{ if and (not $loading) $isLastRound }}
38 {{ template "resubmitStatus" . }}
39 {{ end }}
40 <input type="checkbox" id="comment-toggle-{{$roundNumber}}" class="peer/comment hidden"/>
41 <div class="hidden peer-checked/comment:flex flex-col gap-2">
42 <form
43 class="w-full flex flex-wrap gap-2 group"
44 hx-post="/comment"
45 hx-trigger="submit, keydown[(ctrlKey || metaKey) && key=='Enter'] from:find textarea"
46 hx-target="#pull-comments-{{ .RoundNumber }}"
47 hx-swap="beforeend"
48 hx-disabled-elt="find button[type='submit']"
49 hx-on::after-request="if(event.target === this && event.detail.successful) htmx.ajax('GET', '/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/actions', {target: '#action-card-{{ .RoundNumber }}', swap: 'outerHTML'})"
50 >
51 <input name="subject-uri" type="hidden" value="{{ .Pull.AtUri }}">
52 <input name="pull-round-idx" type="hidden" value="{{ .RoundNumber }}">
53 {{ template "fragments/markdownEditor"
54 (dict "Name" "body"
55 "BlobName" "blob"
56 "Rows" 8
57 "Required" true
58 "Placeholder" "Add to the discussion...") }}
59 <div class="flex flex-wrap items-stretch justify-end gap-2 text-gray-500 dark:text-gray-400 text-sm w-full">
60 <label title="Toggle comment form" for="comment-toggle-{{$roundNumber}}" class="btn-flat text-red-500 dark:text-red-400 flex gap-2 items-center">
61 {{ i "x" "size-4" }}
62 <span>Cancel</span>
63 </label>
64 <button
65 type="submit"
66 class="btn-create-flat flex items-center gap-2">
67 {{ i "reply" "size-4 inline group-[.htmx-request]:hidden" }}
68 {{ i "loader-circle" "size-4 animate-spin hidden group-[.htmx-request]:inline" }}
69 Reply
70 </button>
71 </div>
72 <div id="comment-error-{{ .RoundNumber }}" class="error"></div>
73 </form>
74 </div>
75 <div id="actions-{{$roundNumber}}" hx-target="this" class="peer-checked/comment:hidden flex flex-wrap gap-2 relative"
76 {{ if $loading }}
77 hx-swap="outerHTML"
78 {{ end }}
79 >
80 {{ if .LoggedInUser }}
81 <label title="Toggle comment form" for="comment-toggle-{{$roundNumber}}" class="btn-flat">
82 {{ i "message-square-plus" "size-4" }}
83 <span>Comment</span>
84 </label>
85 {{ end }}
86 {{ if and (not $loading) .BranchDeleteStatus }}
87 <button
88 hx-delete="/{{ resolve .BranchDeleteStatus.Repo.Did }}/{{ .BranchDeleteStatus.Repo.Slug }}/branches"
89 hx-vals='{"branch": "{{ .BranchDeleteStatus.Branch }}" }'
90 hx-swap="none"
91 class="btn-flat p-2 flex items-center gap-2 no-underline hover:no-underline group text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300">
92 {{ i "git-branch" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
93 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
94 Delete branch
95 </button>
96 {{ end }}
97 {{ if $showRunCI }}
98 {{ template "runCiModal" . }}
99 {{ end }}
100 {{ if and $isPushAllowed $isOpen $isLastRound }}
101 <button
102 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge"
103 hx-swap="none"
104 hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?"
105 class="btn-flat p-2 flex items-center gap-2 group"
106 {{ if or $loading $isConflicted }}disabled{{ end }}
107 >
108 {{ if $loading }}
109 {{ i "loader-circle" "w-4 h-4 animate-spin" }}
110 {{ else }}
111 {{ i "git-merge" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
112 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
113 {{ end }}
114 Merge{{if $stackCount}} {{$stackCount}}{{end}}
115 </button>
116 {{ end }}
117
118 {{ if and $isPullAuthor $isOpen $isLastRound }}
119 <button id="resubmitBtn"
120 {{ if not .Pull.IsPatchBased }}
121 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit"
122 hx-swap="none"
123 {{ else }}
124 hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/resubmit"
125 {{ end }}
126
127 hx-disabled-elt="#resubmitBtn"
128 class="btn-flat p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group"
129
130 {{ if $loading }}
131 title="Checking for updates…"
132 disabled
133 {{ else if $isUpToDate }}
134 title="Update this branch to resubmit this pull request"
135 disabled
136 {{ else }}
137 title="Resubmit this pull request"
138 {{ end }}
139 >
140 {{ if $loading }}
141 {{ i "loader-circle" "w-4 h-4 animate-spin" }}
142 {{ else }}
143 {{ i "rotate-ccw" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
144 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
145 {{ end }}
146 Resubmit
147 </button>
148 {{ end }}
149
150 {{ if and (or $isPullAuthor $isPushAllowed) $isOpen $isLastRound }}
151 <button
152 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close"
153 hx-swap="none"
154 class="btn-flat p-2 flex items-center gap-2 group">
155 {{ i "ban" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
156 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
157 Close
158 </button>
159 {{ end }}
160
161 {{ if and (or $isPullAuthor $isPushAllowed) $isClosed $isLastRound }}
162 <button
163 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen"
164 hx-swap="none"
165 class="btn-flat p-2 flex items-center gap-2 group">
166 {{ i "refresh-ccw-dot" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
167 {{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
168 Reopen
169 </button>
170 {{ end }}
171 </div>
172 </div>
173
174 {{ if and (not $loading) $isLastRound }}
175 <div id="mergecheck-banner" hx-swap-oob="innerHTML">
176 {{ if and $isOpen $isForkBased (not .HasPipeline) (ne .RepoInfo.Spindle "") }}
177 {{ template "workflowWarning" . }}
178 {{ end }}
179 {{ template "mergeCheck" . }}
180 </div>
181 {{ end }}
182{{ end }}
183
184{{ define "workflowWarning" }}
185 {{ if .WorkflowsChanged }}
186 <details class="group/ci">
187 <summary class="flex items-center gap-2 cursor-pointer list-none">
188 {{ i "triangle-alert" "w-4 h-4 text-amber-600 dark:text-amber-500" }}
189 <span class="font-medium text-amber-600 dark:text-amber-500">Workflow files changed</span>
190 <div class="text-sm text-gray-500 dark:text-gray-400">
191 <span class="group-open/ci:hidden inline">Expand</span>
192 <span class="hidden group-open/ci:inline">Collapse</span>
193 </div>
194 </summary>
195 <ul class="space-y-1 mt-2 overflow-x-auto">
196 {{ range .ChangedWorkflowFiles }}
197 <li class="flex items-center whitespace-nowrap">
198 {{ i "file-warning" "inline-flex w-4 h-4 mr-1.5 text-amber-600 dark:text-amber-500 flex-shrink-0" }}
199 <span class="font-mono">{{ . }}</span>
200 </li>
201 {{ end }}
202 </ul>
203 </details>
204 {{ else }}
205 <div class="flex items-center gap-2 text-amber-600 dark:text-amber-500">
206 {{ i "triangle-alert" "w-4 h-4" }}
207 <span class="font-medium">Workflow needs approval</span>
208 </div>
209 {{ end }}
210{{ end }}
211
212{{ define "runCiModal" }}
213 <button
214 class="btn-flat p-2 flex items-center gap-2 flex-shrink-0 group"
215 popovertarget="run-ci-{{ .Pull.PullId }}"
216 popovertargetaction="toggle"
217 >
218 {{ i "circle-play" "w-4 h-4 inline" }}
219 Run CI
220 </button>
221
222 <div
223 id="run-ci-{{ .Pull.PullId }}"
224 popover
225 class="bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700 dark:text-white backdrop:bg-gray-400/50 dark:backdrop:bg-gray-800/50 w-full md:w-96 p-4 rounded drop-shadow overflow-visible"
226 >
227 <form
228 hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/trigger-ci?confirm=1"
229 hx-swap="none"
230 hx-indicator="#run-ci-spinner-{{ .Pull.PullId }}"
231 class="flex flex-col gap-2"
232 >
233 <label class="text-lg font-medium p-0">Run CI</label>
234 {{ if .WorkflowsChanged }}
235 <div class="flex items-center gap-2 text-amber-600 dark:text-amber-500">
236 {{ i "triangle-alert" "size-4" }}
237 <span class="font-medium">Workflow files changed</span>
238 </div>
239 <ul class="space-y-1 overflow-x-auto pl-6">
240 {{ range .ChangedWorkflowFiles }}
241 <li class="flex items-center whitespace-nowrap">
242 {{ i "file-warning" "size-4 mr-1.5 text-amber-600 dark:text-amber-500 flex-shrink-0" }}
243 <span class="font-mono text-sm">{{ . }}</span>
244 </li>
245 {{ end }}
246 </ul>
247 <p class="text-sm text-gray-500 dark:text-gray-400">Workflow files changed in this round. Are you sure you want to run CI?</p>
248 {{ else }}
249 <div class="flex items-center gap-2 text-amber-600 dark:text-amber-500">
250 {{ i "triangle-alert" "size-4" }}
251 <span class="font-medium">Workflow needs approval</span>
252 </div>
253 <p class="text-sm text-gray-500 dark:text-gray-400">This fork-based pull request needs approval to run CI. Are you sure?</p>
254 {{ end }}
255 <div class="flex gap-2 pt-2">
256 <button
257 type="button"
258 popovertarget="run-ci-{{ .Pull.PullId }}"
259 popovertargetaction="hide"
260 class="btn w-1/2 flex items-center gap-2 text-red-500 hover:text-red-700 dark:text-red-400 dark:hover:text-red-300"
261 >
262 {{ i "x" "size-4" }} Cancel
263 </button>
264 <button type="submit" class="btn w-1/2 flex items-center">
265 <span class="inline-flex gap-2 items-center">{{ i "shield-check" "size-4" }} Approve</span>
266 <span id="run-ci-spinner-{{ .Pull.PullId }}" class="group">
267 {{ i "loader-circle" "ml-2 w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
268 </span>
269 </button>
270 </div>
271 <div id="pull-error" class="text-red-500 dark:text-red-400"></div>
272 </form>
273 </div>
274{{ end }}
275
276{{ define "mergeCheck" }}
277 {{ $isOpen := .Pull.State.IsOpen }}
278 {{ if and $isOpen .MergeCheck .MergeCheck.Error }}
279 <div class="flex items-center gap-2 text-red-600 dark:text-red-500">
280 {{ i "triangle-alert" "w-4 h-4" }}
281 <span class="font-medium">{{ .MergeCheck.Error }}</span>
282 </div>
283 {{ else if and $isOpen .MergeCheck .MergeCheck.IsConflicted }}
284 <details class="group/conflict">
285 <summary class="flex items-center justify-between cursor-pointer list-none">
286 <div class="flex items-center gap-2 text-red-600 dark:text-red-500">
287 {{ i "triangle-alert" "w-4 h-4" }}
288 <span class="font-medium">Merge conflicts detected</span>
289 <div class="text-sm text-gray-500 dark:text-gray-400">
290 <span class="group-open/conflict:hidden inline">Expand</span>
291 <span class="hidden group-open/conflict:inline">Collapse</span>
292 </div>
293 </div>
294 </summary>
295 {{ if gt (len .MergeCheck.Conflicts) 0 }}
296 <ul class="space-y-1 mt-2 overflow-x-auto">
297 {{ range .MergeCheck.Conflicts }}
298 {{ if .Filename }}
299 <li class="flex items-center whitespace-nowrap">
300 {{ i "file-warning" "inline-flex w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 flex-shrink-0" }}
301 <span class="font-mono">{{ .Filename }}</span>
302 </li>
303 {{ else if .Reason }}
304 <li class="flex items-center whitespace-nowrap">
305 {{ i "file-warning" "w-4 h-4 mr-1.5 text-red-600 dark:text-red-500 " }}
306 <span>{{.Reason}}</span>
307 </li>
308 {{ end }}
309 {{ end }}
310 </ul>
311 {{ end }}
312 </details>
313 {{ else if and $isOpen .MergeCheck }}
314 <div class="flex items-center gap-2 text-green-600 dark:text-green-500">
315 {{ i "check" "w-4 h-4" }}
316 <span class="font-medium">No conflicts, ready to merge</span>
317 </div>
318 {{ end }}
319{{ end }}
320
321{{ define "resubmitStatus" }}
322 {{ if .ResubmitCheck.Yes }}
323 <div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded shadow-sm px-6 py-2 relative">
324 <div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
325 {{ i "triangle-alert" "w-4 h-4" }}
326 <span class="font-medium">This branch has been updated, consider resubmitting</span>
327 </div>
328 </div>
329 {{ end }}
330{{ end }}