+7
-20
appview/pages/funcmap.go
+7
-20
appview/pages/funcmap.go
···
334
},
335
"deref": func(v any) any {
336
val := reflect.ValueOf(v)
337
-
if val.Kind() == reflect.Pointer && !val.IsNil() {
338
return val.Elem().Interface()
339
}
340
return nil
···
366
return p.AvatarUrl(handle, "")
367
},
368
"langColor": enry.GetColor,
369
-
"reverse": func(s any) any {
370
-
if s == nil {
371
-
return nil
372
-
}
373
374
-
v := reflect.ValueOf(s)
375
-
376
-
if v.Kind() != reflect.Slice {
377
-
return s
378
-
}
379
-
380
-
length := v.Len()
381
-
reversed := reflect.MakeSlice(v.Type(), length, length)
382
-
383
-
for i := range length {
384
-
reversed.Index(i).Set(v.Index(length - 1 - i))
385
-
}
386
-
387
-
return reversed.Interface()
388
-
},
389
"normalizeForHtmlId": func(s string) string {
390
normalized := strings.ReplaceAll(s, ":", "_")
391
normalized = strings.ReplaceAll(normalized, ".", "_")
···
334
},
335
"deref": func(v any) any {
336
val := reflect.ValueOf(v)
337
+
if val.Kind() == reflect.Ptr && !val.IsNil() {
338
return val.Elem().Interface()
339
}
340
return nil
···
366
return p.AvatarUrl(handle, "")
367
},
368
"langColor": enry.GetColor,
369
+
"layoutSide": func() string {
370
+
return "col-span-1 md:col-span-2 lg:col-span-3"
371
+
},
372
+
"layoutCenter": func() string {
373
+
return "col-span-1 md:col-span-8 lg:col-span-6"
374
+
},
375
376
"normalizeForHtmlId": func(s string) string {
377
normalized := strings.ReplaceAll(s, ":", "_")
378
normalized = strings.ReplaceAll(normalized, ".", "_")
-2
appview/pages/pages.go
-2
appview/pages/pages.go
-1
appview/pages/templates/fragments/tabSelector.html
-1
appview/pages/templates/fragments/tabSelector.html
+1
-1
appview/pages/templates/layouts/repobase.html
+1
-1
appview/pages/templates/layouts/repobase.html
+1
-1
appview/pages/templates/repo/fragments/diff.html
+1
-1
appview/pages/templates/repo/fragments/diff.html
···
18
{{ range $idx, $hunk := $diff }}
19
{{ with $hunk }}
20
<details open id="file-{{ .Id }}" class="group border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm" tabindex="{{ add $idx 1 }}">
21
-
<summary class="list-none cursor-pointer sticky top-12">
22
<div id="diff-file-header" class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between">
23
<div id="left-side-items" class="p-2 flex gap-2 items-center overflow-x-auto">
24
<span class="group-open:hidden inline">{{ i "chevron-right" "w-4 h-4" }}</span>
···
18
{{ range $idx, $hunk := $diff }}
19
{{ with $hunk }}
20
<details open id="file-{{ .Id }}" class="group border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm" tabindex="{{ add $idx 1 }}">
21
+
<summary class="list-none cursor-pointer sticky top-0">
22
<div id="diff-file-header" class="rounded cursor-pointer bg-white dark:bg-gray-800 flex justify-between">
23
<div id="left-side-items" class="p-2 flex gap-2 items-center overflow-x-auto">
24
<span class="group-open:hidden inline">{{ i "chevron-right" "w-4 h-4" }}</span>
+8
-1
appview/pages/templates/repo/fragments/diffChangedFiles.html
+8
-1
appview/pages/templates/repo/fragments/diffChangedFiles.html
···
1
{{ define "repo/fragments/diffChangedFiles" }}
2
{{ $fileTree := fileTree .ChangedFiles }}
3
<section class="overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded bg-white dark:bg-gray-800 drop-shadow-sm">
4
-
{{ template "repo/fragments/fileTree" $fileTree }}
5
</section>
6
{{ end }}
···
1
{{ define "repo/fragments/diffChangedFiles" }}
2
+
{{ $stat := .Stat }}
3
{{ $fileTree := fileTree .ChangedFiles }}
4
<section class="overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto min-h-full rounded bg-white dark:bg-gray-800 drop-shadow-sm">
5
+
<div class="diff-stat">
6
+
<div class="flex gap-2 items-center">
7
+
<strong class="text-sm uppercase dark:text-gray-200">Changed files</strong>
8
+
{{ template "repo/fragments/diffStatPill" $stat }}
9
+
</div>
10
+
{{ template "repo/fragments/fileTree" $fileTree }}
11
+
</div>
12
</section>
13
{{ end }}
+25
-22
appview/pages/templates/repo/fragments/diffOpts.html
+25
-22
appview/pages/templates/repo/fragments/diffOpts.html
···
1
{{ define "repo/fragments/diffOpts" }}
2
-
{{ $active := "unified" }}
3
-
{{ if .Split }}
4
-
{{ $active = "split" }}
5
-
{{ end }}
6
7
-
{{ $unified :=
8
-
(dict
9
-
"Key" "unified"
10
-
"Value" "unified"
11
-
"Icon" "square-split-vertical"
12
-
"Meta" "") }}
13
-
{{ $split :=
14
-
(dict
15
-
"Key" "split"
16
-
"Value" "split"
17
-
"Icon" "square-split-horizontal"
18
-
"Meta" "") }}
19
-
{{ $values := list $unified $split }}
20
21
-
{{ template "fragments/tabSelector"
22
-
(dict
23
-
"Name" "diff"
24
-
"Values" $values
25
-
"Active" $active) }}
26
{{ end }}
27
···
1
{{ define "repo/fragments/diffOpts" }}
2
+
<section class="flex flex-col gap-2 overflow-x-auto text-sm px-6 py-2 border border-gray-200 dark:border-gray-700 w-full mx-auto rounded bg-white dark:bg-gray-800 drop-shadow-sm">
3
+
<strong class="text-sm uppercase dark:text-gray-200">options</strong>
4
+
{{ $active := "unified" }}
5
+
{{ if .Split }}
6
+
{{ $active = "split" }}
7
+
{{ end }}
8
9
+
{{ $unified :=
10
+
(dict
11
+
"Key" "unified"
12
+
"Value" "unified"
13
+
"Icon" "square-split-vertical"
14
+
"Meta" "") }}
15
+
{{ $split :=
16
+
(dict
17
+
"Key" "split"
18
+
"Value" "split"
19
+
"Icon" "square-split-horizontal"
20
+
"Meta" "") }}
21
+
{{ $values := list $unified $split }}
22
23
+
{{ template "fragments/tabSelector"
24
+
(dict
25
+
"Name" "diff"
26
+
"Values" $values
27
+
"Active" $active) }}
28
+
</section>
29
{{ end }}
30
+22
-35
appview/pages/templates/repo/issues/fragments/commentList.html
+22
-35
appview/pages/templates/repo/issues/fragments/commentList.html
···
1
{{ define "repo/issues/fragments/commentList" }}
2
-
<div class="flex flex-col gap-4">
3
{{ range $item := .CommentList }}
4
{{ template "commentListing" (list $ .) }}
5
{{ end }}
···
19
<div class="rounded border border-gray-200 dark:border-gray-700 w-full overflow-hidden shadow-sm bg-gray-50 dark:bg-gray-800/50">
20
{{ template "topLevelComment" $params }}
21
22
-
<div class="relative ml-10 border-l-2 border-gray-200 dark:border-gray-700">
23
{{ range $index, $reply := $comment.Replies }}
24
-
<div class="-ml-4">
25
-
{{
26
-
template "replyComment"
27
-
(dict
28
-
"RepoInfo" $root.RepoInfo
29
-
"LoggedInUser" $root.LoggedInUser
30
-
"Issue" $root.Issue
31
-
"Comment" $reply)
32
-
}}
33
</div>
34
{{ end }}
35
</div>
···
39
{{ end }}
40
41
{{ define "topLevelComment" }}
42
-
<div class="rounded px-6 py-4 bg-white dark:bg-gray-800 flex gap-2 ">
43
-
<div class="flex-shrink-0">
44
-
<img
45
-
src="{{ tinyAvatar .Comment.Did }}"
46
-
alt=""
47
-
class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900"
48
-
/>
49
-
</div>
50
-
<div class="flex-1 min-w-0">
51
-
{{ template "repo/issues/fragments/issueCommentHeader" . }}
52
-
{{ template "repo/issues/fragments/issueCommentBody" . }}
53
-
</div>
54
</div>
55
{{ end }}
56
57
{{ define "replyComment" }}
58
-
<div class="py-4 pr-4 w-full mx-auto overflow-hidden flex gap-2 ">
59
-
<div class="flex-shrink-0">
60
-
<img
61
-
src="{{ tinyAvatar .Comment.Did }}"
62
-
alt=""
63
-
class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900"
64
-
/>
65
-
</div>
66
-
<div class="flex-1 min-w-0">
67
-
{{ template "repo/issues/fragments/issueCommentHeader" . }}
68
-
{{ template "repo/issues/fragments/issueCommentBody" . }}
69
-
</div>
70
</div>
71
{{ end }}
···
1
{{ define "repo/issues/fragments/commentList" }}
2
+
<div class="flex flex-col gap-8">
3
{{ range $item := .CommentList }}
4
{{ template "commentListing" (list $ .) }}
5
{{ end }}
···
19
<div class="rounded border border-gray-200 dark:border-gray-700 w-full overflow-hidden shadow-sm bg-gray-50 dark:bg-gray-800/50">
20
{{ template "topLevelComment" $params }}
21
22
+
<div class="relative ml-4 border-l-2 border-gray-200 dark:border-gray-700">
23
{{ range $index, $reply := $comment.Replies }}
24
+
<div class="relative ">
25
+
<!-- Horizontal connector -->
26
+
<div class="absolute left-0 top-6 w-4 h-1 bg-gray-200 dark:bg-gray-700"></div>
27
+
28
+
<div class="pl-2">
29
+
{{
30
+
template "replyComment"
31
+
(dict
32
+
"RepoInfo" $root.RepoInfo
33
+
"LoggedInUser" $root.LoggedInUser
34
+
"Issue" $root.Issue
35
+
"Comment" $reply)
36
+
}}
37
+
</div>
38
</div>
39
{{ end }}
40
</div>
···
44
{{ end }}
45
46
{{ define "topLevelComment" }}
47
+
<div class="rounded px-6 py-4 bg-white dark:bg-gray-800">
48
+
{{ template "repo/issues/fragments/issueCommentHeader" . }}
49
+
{{ template "repo/issues/fragments/issueCommentBody" . }}
50
</div>
51
{{ end }}
52
53
{{ define "replyComment" }}
54
+
<div class="p-4 w-full mx-auto overflow-hidden">
55
+
{{ template "repo/issues/fragments/issueCommentHeader" . }}
56
+
{{ template "repo/issues/fragments/issueCommentBody" . }}
57
</div>
58
{{ end }}
+63
appview/pages/templates/repo/issues/fragments/globalIssueListing.html
+63
appview/pages/templates/repo/issues/fragments/globalIssueListing.html
···
···
1
+
{{ define "repo/issues/fragments/globalIssueListing" }}
2
+
<div class="flex flex-col gap-2">
3
+
{{ range .Issues }}
4
+
<div class="rounded drop-shadow-sm bg-white px-6 py-4 dark:bg-gray-800 dark:border-gray-700">
5
+
<div class="pb-2 mb-3">
6
+
<div class="flex items-center gap-3 mb-2">
7
+
<a
8
+
href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}"
9
+
class="text-blue-600 dark:text-blue-400 font-medium hover:underline text-sm"
10
+
>
11
+
{{ resolve .Repo.Did }}/{{ .Repo.Name }}
12
+
</a>
13
+
</div>
14
+
<a
15
+
href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}/issues/{{ .IssueId }}"
16
+
class="no-underline hover:underline"
17
+
>
18
+
{{ .Title | description }}
19
+
<span class="text-gray-500">#{{ .IssueId }}</span>
20
+
</a>
21
+
</div>
22
+
<div class="text-sm text-gray-500 dark:text-gray-400 flex flex-wrap items-center gap-1">
23
+
{{ $bgColor := "bg-gray-800 dark:bg-gray-700" }}
24
+
{{ $icon := "ban" }}
25
+
{{ $state := "closed" }}
26
+
{{ if .Open }}
27
+
{{ $bgColor = "bg-green-600 dark:bg-green-700" }}
28
+
{{ $icon = "circle-dot" }}
29
+
{{ $state = "open" }}
30
+
{{ end }}
31
+
32
+
<span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm">
33
+
{{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }}
34
+
<span class="text-white dark:text-white">{{ $state }}</span>
35
+
</span>
36
+
37
+
<span class="ml-1">
38
+
{{ template "user/fragments/picHandleLink" .Did }}
39
+
</span>
40
+
41
+
<span class="before:content-['ยท']">
42
+
{{ template "repo/fragments/time" .Created }}
43
+
</span>
44
+
45
+
<span class="before:content-['ยท']">
46
+
{{ $s := "s" }}
47
+
{{ if eq (len .Comments) 1 }}
48
+
{{ $s = "" }}
49
+
{{ end }}
50
+
<a href="/{{ resolve .Repo.Did }}/{{ .Repo.Name }}/issues/{{ .IssueId }}" class="text-gray-500 dark:text-gray-400">{{ len .Comments }} comment{{$s}}</a>
51
+
</span>
52
+
53
+
{{ $state := .Labels }}
54
+
{{ range $k, $d := $.LabelDefs }}
55
+
{{ range $v, $s := $state.GetValSet $d.AtUri.String }}
56
+
{{ template "labels/fragments/label" (dict "def" $d "val" $v "withPrefix" true) }}
57
+
{{ end }}
58
+
{{ end }}
59
+
</div>
60
+
</div>
61
+
{{ end }}
62
+
</div>
63
+
{{ end }}
+1
-2
appview/pages/templates/repo/issues/fragments/issueCommentHeader.html
+1
-2
appview/pages/templates/repo/issues/fragments/issueCommentHeader.html
···
1
{{ define "repo/issues/fragments/issueCommentHeader" }}
2
<div class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-400 ">
3
-
{{ resolve .Comment.Did }}
4
{{ template "hats" $ }}
5
-
<span class="before:content-['ยท']"></span>
6
{{ template "timestamp" . }}
7
{{ $isCommentOwner := and .LoggedInUser (eq .LoggedInUser.Did .Comment.Did) }}
8
{{ if and $isCommentOwner (not .Comment.Deleted) }}
···
1
{{ define "repo/issues/fragments/issueCommentHeader" }}
2
<div class="flex flex-wrap items-center gap-2 text-sm text-gray-500 dark:text-gray-400 ">
3
+
{{ template "user/fragments/picHandleLink" .Comment.Did }}
4
{{ template "hats" $ }}
5
{{ template "timestamp" . }}
6
{{ $isCommentOwner := and .LoggedInUser (eq .LoggedInUser.Did .Comment.Did) }}
7
{{ if and $isCommentOwner (not .Comment.Deleted) }}
+2
-2
appview/pages/templates/repo/issues/fragments/issueListing.html
+2
-2
appview/pages/templates/repo/issues/fragments/issueListing.html
+1
-1
appview/pages/templates/repo/issues/fragments/putIssue.html
+1
-1
appview/pages/templates/repo/issues/fragments/putIssue.html
+3
-3
appview/pages/templates/repo/issues/fragments/replyIssueCommentPlaceholder.html
+3
-3
appview/pages/templates/repo/issues/fragments/replyIssueCommentPlaceholder.html
···
1
{{ define "repo/issues/fragments/replyIssueCommentPlaceholder" }}
2
-
<div class="py-2 px-6 border-t flex gap-2 items-center border-gray-300 dark:border-gray-700">
3
{{ if .LoggedInUser }}
4
<img
5
src="{{ tinyAvatar .LoggedInUser.Did }}"
6
alt=""
7
-
class="rounded-full size-8 mr-1 border-2 border-gray-300 dark:border-gray-700"
8
/>
9
{{ end }}
10
<input
11
-
class="w-full p-0 border-none focus:outline-none"
12
placeholder="Leave a reply..."
13
hx-get="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment/{{ .Comment.Id }}/reply"
14
hx-trigger="focus"
···
1
{{ define "repo/issues/fragments/replyIssueCommentPlaceholder" }}
2
+
<div class="p-2 border-t flex gap-2 items-center border-gray-300 dark:border-gray-700">
3
{{ if .LoggedInUser }}
4
<img
5
src="{{ tinyAvatar .LoggedInUser.Did }}"
6
alt=""
7
+
class="rounded-full h-6 w-6 mr-1 border border-gray-300 dark:border-gray-700"
8
/>
9
{{ end }}
10
<input
11
+
class="w-full py-2 border-none focus:outline-none"
12
placeholder="Leave a reply..."
13
hx-get="/{{ .RepoInfo.FullName }}/issues/{{ .Issue.IssueId }}/comment/{{ .Comment.Id }}/reply"
14
hx-trigger="focus"
+5
-5
appview/pages/templates/repo/issues/issue.html
+5
-5
appview/pages/templates/repo/issues/issue.html
···
58
{{ $icon = "circle-dot" }}
59
{{ end }}
60
<div class="inline-flex items-center gap-2">
61
-
<span class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }}">
62
-
{{ i $icon "w-3 h-3 mr-1.5 text-white dark:text-white" }}
63
-
<span class="text-white dark:text-white text-sm">{{ .Issue.State }}</span>
64
-
</span>
65
-
66
<span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1">
67
opened by
68
{{ template "user/fragments/picHandleLink" .Issue.Did }}
···
58
{{ $icon = "circle-dot" }}
59
{{ end }}
60
<div class="inline-flex items-center gap-2">
61
+
<div id="state"
62
+
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}">
63
+
{{ i $icon "w-4 h-4 mr-1.5 text-white" }}
64
+
<span class="text-white">{{ .Issue.State }}</span>
65
+
</div>
66
<span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1">
67
opened by
68
{{ template "user/fragments/picHandleLink" .Issue.Did }}
+17
-17
appview/pages/templates/repo/pulls/fragments/pullActions.html
+17
-17
appview/pages/templates/repo/pulls/fragments/pullActions.html
···
22
{{ $isLastRound := eq $roundNumber $lastIdx }}
23
{{ $isSameRepoBranch := .Pull.IsBranchBased }}
24
{{ $isUpToDate := .ResubmitCheck.No }}
25
-
<div id="actions-{{$roundNumber}}" class="flex flex-wrap gap-2 relative p-2">
26
<button
27
hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/comment"
28
hx-target="#actions-{{$roundNumber}}"
29
hx-swap="outerHtml"
30
-
class="btn-flat p-2 flex items-center gap-2 no-underline hover:no-underline group">
31
-
{{ i "message-square-plus" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
32
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
33
-
comment
34
</button>
35
{{ if .BranchDeleteStatus }}
36
<button
37
hx-delete="/{{ .BranchDeleteStatus.Repo.Did }}/{{ .BranchDeleteStatus.Repo.Name }}/branches"
38
hx-vals='{"branch": "{{ .BranchDeleteStatus.Branch }}" }'
39
hx-swap="none"
40
-
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">
41
{{ i "git-branch" "w-4 h-4" }}
42
<span>delete branch</span>
43
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
···
52
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge"
53
hx-swap="none"
54
hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?"
55
-
class="btn-flat p-2 flex items-center gap-2 group" {{ $disabled }}>
56
-
{{ i "git-merge" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
57
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
58
-
merge{{if $stackCount}} {{$stackCount}}{{end}}
59
</button>
60
{{ end }}
61
···
74
{{ end }}
75
76
hx-disabled-elt="#resubmitBtn"
77
-
class="btn-flat p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group" {{ $disabled }}
78
79
{{ if $disabled }}
80
title="Update this branch to resubmit this pull request"
···
82
title="Resubmit this pull request"
83
{{ end }}
84
>
85
-
{{ i "rotate-ccw" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
86
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
87
-
resubmit
88
</button>
89
{{ end }}
90
···
92
<button
93
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close"
94
hx-swap="none"
95
-
class="btn-flat p-2 flex items-center gap-2 group">
96
-
{{ i "ban" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
97
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
98
-
close
99
</button>
100
{{ end }}
101
···
103
<button
104
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen"
105
hx-swap="none"
106
-
class="btn-flat p-2 flex items-center gap-2 group">
107
-
{{ i "refresh-ccw-dot" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
108
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
109
-
reopen
110
</button>
111
{{ end }}
112
</div>
···
22
{{ $isLastRound := eq $roundNumber $lastIdx }}
23
{{ $isSameRepoBranch := .Pull.IsBranchBased }}
24
{{ $isUpToDate := .ResubmitCheck.No }}
25
+
<div id="actions-{{$roundNumber}}" class="flex flex-wrap gap-2 relative">
26
<button
27
hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ $roundNumber }}/comment"
28
hx-target="#actions-{{$roundNumber}}"
29
hx-swap="outerHtml"
30
+
class="btn p-2 flex items-center gap-2 no-underline hover:no-underline group">
31
+
{{ i "message-square-plus" "w-4 h-4" }}
32
+
<span>comment</span>
33
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
34
</button>
35
{{ if .BranchDeleteStatus }}
36
<button
37
hx-delete="/{{ .BranchDeleteStatus.Repo.Did }}/{{ .BranchDeleteStatus.Repo.Name }}/branches"
38
hx-vals='{"branch": "{{ .BranchDeleteStatus.Branch }}" }'
39
hx-swap="none"
40
+
class="btn 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">
41
{{ i "git-branch" "w-4 h-4" }}
42
<span>delete branch</span>
43
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
···
52
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/merge"
53
hx-swap="none"
54
hx-confirm="Are you sure you want to merge pull #{{ .Pull.PullId }} into the `{{ .Pull.TargetBranch }}` branch?"
55
+
class="btn p-2 flex items-center gap-2 group" {{ $disabled }}>
56
+
{{ i "git-merge" "w-4 h-4" }}
57
+
<span>merge{{if $stackCount}} {{$stackCount}}{{end}}</span>
58
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
59
</button>
60
{{ end }}
61
···
74
{{ end }}
75
76
hx-disabled-elt="#resubmitBtn"
77
+
class="btn p-2 flex items-center gap-2 disabled:opacity-50 disabled:cursor-not-allowed group" {{ $disabled }}
78
79
{{ if $disabled }}
80
title="Update this branch to resubmit this pull request"
···
82
title="Resubmit this pull request"
83
{{ end }}
84
>
85
+
{{ i "rotate-ccw" "w-4 h-4" }}
86
+
<span>resubmit</span>
87
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
88
</button>
89
{{ end }}
90
···
92
<button
93
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/close"
94
hx-swap="none"
95
+
class="btn p-2 flex items-center gap-2 group">
96
+
{{ i "ban" "w-4 h-4" }}
97
+
<span>close</span>
98
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
99
</button>
100
{{ end }}
101
···
103
<button
104
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/reopen"
105
hx-swap="none"
106
+
class="btn p-2 flex items-center gap-2 group">
107
+
{{ i "refresh-ccw-dot" "w-4 h-4" }}
108
+
<span>reopen</span>
109
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
110
</button>
111
{{ end }}
112
</div>
+7
-6
appview/pages/templates/repo/pulls/fragments/pullHeader.html
+7
-6
appview/pages/templates/repo/pulls/fragments/pullHeader.html
···
1
{{ define "repo/pulls/fragments/pullHeader" }}
2
-
<header class="pb-2">
3
<h1 class="text-2xl dark:text-white">
4
{{ .Pull.Title | description }}
5
<span class="text-gray-500 dark:text-gray-400">#{{ .Pull.PullId }}</span>
···
17
{{ $icon = "git-merge" }}
18
{{ end }}
19
20
-
<section>
21
<div class="flex items-center gap-2">
22
-
<span
23
-
class="inline-flex items-center rounded px-2 py-[5px] {{ $bgColor }} text-sm"
24
>
25
-
{{ i $icon "w-3 h-3 mr-1.5 text-white" }}
26
<span class="text-white">{{ .Pull.State.String }}</span>
27
-
</span>
28
<span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1">
29
opened by
30
{{ template "user/fragments/picHandleLink" .Pull.OwnerDid }}
···
1
{{ define "repo/pulls/fragments/pullHeader" }}
2
+
<header class="pb-4">
3
<h1 class="text-2xl dark:text-white">
4
{{ .Pull.Title | description }}
5
<span class="text-gray-500 dark:text-gray-400">#{{ .Pull.PullId }}</span>
···
17
{{ $icon = "git-merge" }}
18
{{ end }}
19
20
+
<section class="mt-2">
21
<div class="flex items-center gap-2">
22
+
<div
23
+
id="state"
24
+
class="inline-flex items-center rounded px-3 py-1 {{ $bgColor }}"
25
>
26
+
{{ i $icon "w-4 h-4 mr-1.5 text-white" }}
27
<span class="text-white">{{ .Pull.State.String }}</span>
28
+
</div>
29
<span class="text-gray-500 dark:text-gray-400 text-sm flex flex-wrap items-center gap-1">
30
opened by
31
{{ template "user/fragments/picHandleLink" .Pull.OwnerDid }}
+24
-39
appview/pages/templates/repo/pulls/fragments/pullNewComment.html
+24
-39
appview/pages/templates/repo/pulls/fragments/pullNewComment.html
···
1
{{ define "repo/pulls/fragments/pullNewComment" }}
2
<div
3
id="pull-comment-card-{{ .RoundNumber }}"
4
-
class="w-full flex flex-col gap-2">
5
-
{{ template "user/fragments/picHandleLink" .LoggedInUser.Did }}
6
<form
7
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/comment"
8
hx-swap="none"
9
-
hx-on::after-request="if(event.detail.successful) this.reset()"
10
-
hx-disabled-elt="#reply-{{ .RoundNumber }}"
11
-
class="w-full flex flex-wrap gap-2 group"
12
>
13
<textarea
14
name="body"
15
class="w-full p-2 rounded border border-gray-200"
16
-
rows=8
17
placeholder="Add to the discussion..."></textarea
18
>
19
-
{{ template "replyActions" . }}
20
<div id="pull-comment"></div>
21
</form>
22
</div>
23
{{ end }}
24
-
25
-
{{ define "replyActions" }}
26
-
<div class="flex flex-wrap items-stretch justify-end gap-2 text-gray-500 dark:text-gray-400 text-sm w-full">
27
-
{{ template "cancel" . }}
28
-
{{ template "reply" . }}
29
-
</div>
30
-
{{ end }}
31
-
32
-
{{ define "cancel" }}
33
-
<button
34
-
type="button"
35
-
class="btn text-red-500 dark:text-red-400 flex gap-2 items-center group"
36
-
hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/actions"
37
-
hx-swap="outerHTML"
38
-
hx-target="#actions-{{.RoundNumber}}"
39
-
>
40
-
{{ i "x" "w-4 h-4" }}
41
-
<span>cancel</span>
42
-
</button>
43
-
{{ end }}
44
-
45
-
{{ define "reply" }}
46
-
<button
47
-
type="submit"
48
-
id="reply-{{ .RoundNumber }}"
49
-
class="btn-create flex items-center gap-2">
50
-
{{ i "reply" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
51
-
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
52
-
reply
53
-
</button>
54
-
{{ end }}
55
-
···
1
{{ define "repo/pulls/fragments/pullNewComment" }}
2
<div
3
id="pull-comment-card-{{ .RoundNumber }}"
4
+
class="bg-white dark:bg-gray-800 rounded drop-shadow-sm p-4 relative w-full flex flex-col gap-2">
5
+
<div class="text-sm text-gray-500 dark:text-gray-400">
6
+
{{ resolve .LoggedInUser.Did }}
7
+
</div>
8
<form
9
hx-post="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/comment"
10
+
hx-indicator="#create-comment-spinner"
11
hx-swap="none"
12
+
class="w-full flex flex-wrap gap-2"
13
>
14
<textarea
15
name="body"
16
class="w-full p-2 rounded border border-gray-200"
17
placeholder="Add to the discussion..."></textarea
18
>
19
+
<button type="submit" class="btn flex items-center gap-2">
20
+
{{ i "message-square" "w-4 h-4" }}
21
+
<span>comment</span>
22
+
<span id="create-comment-spinner" class="group">
23
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
24
+
</span>
25
+
</button>
26
+
<button
27
+
type="button"
28
+
class="btn flex items-center gap-2 group"
29
+
hx-get="/{{ .RepoInfo.FullName }}/pulls/{{ .Pull.PullId }}/round/{{ .RoundNumber }}/actions"
30
+
hx-swap="outerHTML"
31
+
hx-target="#pull-comment-card-{{ .RoundNumber }}"
32
+
>
33
+
{{ i "x" "w-4 h-4" }}
34
+
<span>cancel</span>
35
+
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
36
+
</button>
37
<div id="pull-comment"></div>
38
</form>
39
</div>
40
{{ end }}
-20
appview/pages/templates/repo/pulls/fragments/replyPullCommentPlaceholder.html
-20
appview/pages/templates/repo/pulls/fragments/replyPullCommentPlaceholder.html
···
1
-
{{ define "repo/pulls/fragments/replyPullCommentPlaceholder" }}
2
-
<div class="py-2 px-6 border-t flex gap-2 items-center border-gray-300 dark:border-gray-700">
3
-
{{ if .LoggedInUser }}
4
-
<img
5
-
src="{{ tinyAvatar .LoggedInUser.Did }}"
6
-
alt=""
7
-
class="rounded-full size-8 mr-1 border-2 border-gray-300 dark:border-gray-700"
8
-
/>
9
-
{{ end }}
10
-
<input
11
-
class="w-full p-0 border-none focus:outline-none"
12
-
placeholder="Leave a reply..."
13
-
hx-get="/{{ .Submission.ID }}/reply"
14
-
hx-trigger="focus"
15
-
hx-target="closest div"
16
-
hx-swap="outerHTML"
17
-
>
18
-
</input>
19
-
</div>
20
-
{{ end }}
···
+30
-277
appview/pages/templates/repo/pulls/pull.html
+30
-277
appview/pages/templates/repo/pulls/pull.html
···
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
-
{{ end }}
16
-
17
{{ define "repoContentLayout" }}
18
-
<div class="grid grid-cols-1 md:grid-cols-10 gap-y-2 gap-x-4 w-full">
19
-
<div class="col-span-1 md:col-span-7">
20
-
<section class="bg-white dark:bg-gray-800 p-6 rounded relative w-full mx-auto dark:text-white h-full">
21
{{ block "repoContent" . }}{{ end }}
22
</section>
23
{{ block "repoAfter" . }}{{ end }}
24
</div>
25
-
<div class="col-span-1 md:col-span-3 flex flex-col gap-6">
26
{{ template "repo/fragments/labelPanel"
27
(dict "RepoInfo" $.RepoInfo
28
"Defs" $.LabelDefs
···
34
"Backlinks" $.Backlinks) }}
35
{{ template "repo/fragments/externalLinkPanel" $.Pull.AtUri }}
36
</div>
37
-
38
-
<style>
39
-
#filesToggle:checked ~ div label[for="filesToggle"] .show-text { display: none; }
40
-
#filesToggle:checked ~ div label[for="filesToggle"] .hide-text { display: inline; }
41
-
#filesToggle:not(:checked) ~ div label[for="filesToggle"] .hide-text { display: none; }
42
-
43
-
#filesToggle:checked ~ div div#files { width: 10vw; margin-right: 1rem; }
44
-
#filesToggle:not(:checked) ~ div div#files { width: 0; display: hidden; margin-right: 0; }
45
-
46
-
#subsToggle:checked ~ div div#subs { width: 25vw; margin-left: 1rem; }
47
-
#subsToggle:not(:checked) ~ div div#subs { width: 0; display: hidden; margin-left: 0; }
48
-
</style>
49
-
50
-
<!-- Checkboxes must come first as siblings -->
51
-
<input type="checkbox" id="filesToggle" class="peer/files hidden" checked/>
52
-
<input type="checkbox" id="subsToggle" class="peer/subs hidden" checked/>
53
-
54
-
<!-- Top bar with controls -->
55
-
<div class="sticky top-0 z-30 bg-slate-100 dark:bg-gray-900 flex items-center gap-2 col-span-full h-12">
56
-
<label for="filesToggle" class="inline-flex items-center justify-center rounded cursor-pointer p-2 text-normal font-normal normalcase">
57
-
<span class="show-text">{{ i "panel-left-open" "size-5" }}</span>
58
-
<span class="hide-text">{{ i "panel-left-close" "size-5" }}</span>
59
-
</label>
60
-
{{ template "repo/fragments/diffStatPill" .Diff.Stat }}
61
-
{{ .Diff.Stat.FilesChanged }} changed file{{ if ne .Diff.Stat.FilesChanged 1 }}s{{ end }}
62
-
<div class="flex-grow"></div>
63
-
{{ template "repo/fragments/diffOpts" .DiffOpts }}
64
-
<label for="subsToggle" class="inline-flex items-center justify-center rounded cursor-pointer p-2">
65
-
{{ i "message-square-more" "size-5" }}
66
-
</label>
67
-
</div>
68
-
69
-
<div class="flex col-span-full">
70
-
<!-- left panel -->
71
-
<div id="files" class="w-0 overflow-hidden sticky top-12 max-h-screen overflow-y-auto pb-12">
72
-
{{ template "repo/fragments/diffChangedFiles" .Diff }}
73
-
</div>
74
-
75
-
<!-- main content -->
76
-
<div class="flex-1 min-w-0 sticky top-12 pb-12">
77
-
{{ template "repo/fragments/diff" (list .Diff .DiffOpts) }}
78
-
</div>
79
-
80
-
<!-- right panel -->
81
-
<div id="subs" class="w-0 overflow-hidden max-h-screen flex flex-col sticky top-12 pb-12">
82
-
<div class="z-20 sticky top-0 rounded-t p-3 bg-white dark:bg-gray-800 border border-gray-200 dark:border-gray-700">
83
-
<h2 class="font-bold uppercase">history</h2>
84
-
</div>
85
-
<div class="flex flex-col-reverse gap-4 overflow-y-auto">
86
-
{{ template "submissions2" . }}
87
-
</div>
88
-
</div>
89
-
</div>
90
</div>
91
{{ end }}
92
93
{{ define "repoContent" }}
94
{{ template "repo/pulls/fragments/pullHeader" . }}
95
{{ if .Pull.IsStacked }}
96
<div class="mt-8">
97
{{ template "repo/pulls/fragments/pullStack" . }}
···
100
{{ end }}
101
102
{{ define "repoAfter" }}
103
-
<div id="pull-close"></div>
104
-
<div id="pull-reopen"></div>
105
-
{{ end }}
106
-
107
-
{{ define "submissions2" }}
108
-
{{ $lastIdx := sub (len .Pull.Submissions) 1 }}
109
-
{{ range $ridx, $item := reverse .Pull.Submissions }}
110
-
{{ $idx := sub $lastIdx $ridx }}
111
-
<div class="rounded border border-gray-200 dark:border-gray-700 w-full shadow-sm bg-gray-50 dark:bg-gray-800/50">
112
-
{{ with $item }}
113
-
{{ $patches := .AsFormatPatch }}
114
-
{{ $round := .RoundNumber }}
115
-
<div class="rounded px-6 py-4 bg-white dark:bg-gray-800 flex gap-2">
116
-
<div class="flex-shrink-0">
117
-
<img
118
-
src="{{ tinyAvatar $.Pull.OwnerDid }}"
119
-
alt=""
120
-
class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900"
121
-
/>
122
-
</div>
123
-
<!-- right column: name and body in two rows -->
124
-
<div class="flex-1 min-w-0 flex flex-col gap-2">
125
-
<div class="flex gap-2 items-center justify-between mb-1">
126
-
<span class="inline-flex items-center gap-2 text-sm text-gray-500 dark:text-gray-400 hover:text-gray-500">
127
-
{{ resolve $.Pull.OwnerDid }} submitted v{{ $round }}
128
-
<span class="select-none before:content-['\00B7']"></span>
129
-
<a class="text-gray-500 dark:text-gray-400 hover:text-gray-500" href="#round-#{{ $round }}">{{ template "repo/fragments/shortTimeAgo" .Created }}</a>
130
-
</span>
131
-
{{ if ne $idx 0 }}
132
-
<a class="flex items-center gap-2 no-underline hover:no-underline text-sm"
133
-
hx-boost="true"
134
-
href="/{{ $.RepoInfo.FullName }}/pulls/{{ $.Pull.PullId }}/round/{{$round}}/interdiff">
135
-
{{ i "chevrons-left-right-ellipsis" "w-4 h-4 rotate-90" }}
136
-
<span class="hidden md:inline">interdiff</span>
137
-
</a>
138
-
{{ end }}
139
-
</div>
140
-
<div>
141
-
{{ if eq 1 (len $patches) }}
142
-
<!-- only one commit, just inline the message into the round header -->
143
-
{{ $commit := index $patches 0 }}
144
-
<span>{{ $commit.Title | description }}</span>
145
-
{{ if gt (len $commit.Body) 0 }}
146
-
<p id="body-{{$round}}-{{$commit.SHA}}" class="mt-1 pb-2">
147
-
{{ nl2br $commit.Body }}
148
-
</p>
149
-
{{ end }}
150
-
{{ else }}
151
-
<span>Commits:</span>
152
-
{{ range $patches }}
153
-
<div id="commit-{{.SHA}}" class="py-1 px-2 relative w-full md:max-w-3/5 md:w-fit flex flex-col">
154
-
<div class="flex items-center gap-2">
155
-
{{ i "git-commit-horizontal" "w-4 h-4 flex-shrink-0" }}
156
-
<div class="flex items-center">
157
-
<span>{{ .Title | description }}</span>
158
-
{{ if gt (len .Body) 0 }}
159
-
<button
160
-
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"
161
-
hx-on:click="document.getElementById('body-{{$round}}-{{.SHA}}').classList.toggle('hidden')"
162
-
>
163
-
{{ i "ellipsis" "w-3 h-3" }}
164
-
</button>
165
-
{{ end }}
166
-
</div>
167
-
</div>
168
-
{{ if gt (len .Body) 0 }}
169
-
<p id="body-{{$round}}-{{.SHA}}" class="hidden mt-1 text-sm pb-2">
170
-
{{ nl2br .Body }}
171
-
</p>
172
-
{{ end }}
173
-
</div>
174
-
{{ end }}
175
-
{{ end }}
176
-
</div>
177
-
<div>
178
-
{{ block "pipelineStatus" (list $ .) }} {{ end }}
179
-
</div>
180
-
</div>
181
-
</div>
182
-
<div class="relative ml-10 border-l-2 border-gray-200 dark:border-gray-700">
183
-
{{ range $cidx, $c := .Comments }}
184
-
<div id="comment-{{$c.ID}}" class="flex gap-2 -ml-4 py-4 w-full mx-auto">
185
-
<!-- left column: profile picture -->
186
-
<div class="flex-shrink-0">
187
-
<img
188
-
src="{{ tinyAvatar $c.OwnerDid }}"
189
-
alt=""
190
-
class="rounded-full size-8 mr-1 border-2 border-gray-100 dark:border-gray-900"
191
-
/>
192
-
</div>
193
-
<!-- right column: name and body in two rows -->
194
-
<div class="flex-1 min-w-0">
195
-
<!-- Row 1: Author and timestamp -->
196
-
<div class="text-sm text-gray-500 dark:text-gray-400 flex items-center gap-1">
197
-
<span>{{ resolve $c.OwnerDid }}</span>
198
-
<span class="before:content-['ยท']"></span>
199
-
<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>
200
-
</div>
201
-
<!-- Row 2: Body text -->
202
-
<div class="prose dark:prose-invert mt-1">
203
-
{{ $c.Body | markdown }}
204
-
</div>
205
-
</div>
206
-
</div>
207
-
{{ end }}
208
-
</div>
209
-
{{ end }}
210
-
{{ if eq $lastIdx .RoundNumber }}
211
-
{{ block "mergeStatus" $ }} {{ end }}
212
-
{{ block "resubmitStatus" $ }} {{ end }}
213
-
{{ end }}
214
-
{{ if $.LoggedInUser }}
215
-
{{ template "repo/pulls/fragments/pullActions"
216
-
(dict
217
-
"LoggedInUser" $.LoggedInUser
218
-
"Pull" $.Pull
219
-
"RepoInfo" $.RepoInfo
220
-
"RoundNumber" .RoundNumber
221
-
"MergeCheck" $.MergeCheck
222
-
"ResubmitCheck" $.ResubmitCheck
223
-
"BranchDeleteStatus" $.BranchDeleteStatus
224
-
"Stack" $.Stack) }}
225
-
{{ else }}
226
-
<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">
227
-
<a href="/signup" class="btn-create py-0 hover:no-underline hover:text-white flex items-center gap-2">
228
-
sign up
229
-
</a>
230
-
<span class="text-gray-500 dark:text-gray-400">or</span>
231
-
<a href="/login" class="underline">login</a>
232
-
to add to the discussion
233
-
</div>
234
-
{{ end }}
235
-
</div>
236
-
{{ end }}
237
-
{{ end }}
238
-
239
-
{{ define "newComment" }}
240
-
{{ $root := index . 0 }}
241
-
{{ $submission := index . 1 }}
242
-
<form
243
-
id="comment-form"
244
-
hx-post="/{{ $root.RepoInfo.FullName }}/pulls/{{ $root.Pull.PullId }}/round/{{ $submission.RoundNumber }}/comment"
245
-
hx-on::after-request="if(event.detail.successful) this.reset()"
246
-
>
247
-
<div class="bg-white dark:bg-gray-800 rounded drop-shadow-sm py-4 px-4 relative w-full">
248
-
<div class="text-sm pb-2 text-gray-500 dark:text-gray-400">
249
-
{{ template "user/fragments/picHandleLink" $root.LoggedInUser.Did }}
250
</div>
251
-
<textarea
252
-
id="comment-textarea"
253
-
name="body"
254
-
class="w-full p-2 rounded border border-gray-200 dark:border-gray-700"
255
-
placeholder="Add to the discussion"
256
-
rows="8"
257
-
></textarea>
258
-
<div id="pull-comment"></div>
259
-
</div>
260
-
{{ template "replyActions" . }}
261
-
</form>
262
-
{{ end }}
263
264
-
{{ define "replyActions" }}
265
-
<div class="flex flex-wrap items-stretch justify-end gap-2 text-gray-500 dark:text-gray-400 text-sm">
266
-
{{ template "cancel" . }}
267
-
{{ template "reply" . }}
268
-
</div>
269
-
{{ end }}
270
-
271
-
{{ define "cancel" }}
272
-
<button
273
-
class="btn text-red-500 dark:text-red-400 flex gap-2 items-center group"
274
-
hx-get="TODO"
275
-
hx-target="TODO"
276
-
hx-swap="outerHTML">
277
-
{{ i "x" "size-4" }}
278
-
cancel
279
-
</button>
280
-
{{ end }}
281
-
282
-
{{ define "reply" }}
283
-
<button
284
-
id="TODO"
285
-
type="submit"
286
-
class="btn-create flex items-center gap-2 no-underline hover:no-underline">
287
-
{{ i "reply" "w-4 h-4 inline group-[.htmx-request]:hidden" }}
288
-
{{ i "loader-circle" "w-4 h-4 animate-spin hidden group-[.htmx-request]:inline" }}
289
-
reply
290
-
</button>
291
{{ end }}
292
293
{{ define "submissions" }}
···
456
457
{{ define "mergeStatus" }}
458
{{ if .Pull.State.IsClosed }}
459
-
<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">
460
<div class="flex items-center gap-2 text-black dark:text-white">
461
{{ i "ban" "w-4 h-4" }}
462
<span class="font-medium">closed without merging</span
···
464
</div>
465
</div>
466
{{ else if .Pull.State.IsMerged }}
467
-
<div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative">
468
<div class="flex items-center gap-2 text-purple-500 dark:text-purple-300">
469
{{ i "git-merge" "w-4 h-4" }}
470
<span class="font-medium">pull request successfully merged</span
···
472
</div>
473
</div>
474
{{ else if .Pull.State.IsDeleted }}
475
-
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative">
476
<div class="flex items-center gap-2 text-red-500 dark:text-red-300">
477
{{ i "git-pull-request-closed" "w-4 h-4" }}
478
<span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span>
479
</div>
480
</div>
481
{{ else if and .MergeCheck .MergeCheck.Error }}
482
-
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative">
483
<div class="flex items-center gap-2 text-red-500 dark:text-red-300">
484
{{ i "triangle-alert" "w-4 h-4" }}
485
<span class="font-medium">{{ .MergeCheck.Error }}</span>
486
</div>
487
</div>
488
{{ else if and .MergeCheck .MergeCheck.IsConflicted }}
489
-
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative">
490
-
<details class="text-red-500 dark:text-red-300 group">
491
-
<summary class="flex items-center justify-between cursor-pointer list-none">
492
-
<div class="flex items-center gap-2 ">
493
-
{{ i "triangle-alert" "w-4 h-4" }}
494
-
<span class="font-medium">merge conflicts detected</span>
495
-
</div>
496
-
<div>
497
-
<span class="group-open:hidden inline">{{ i "chevrons-up-down" "w-4 h-4" }}</span>
498
-
<span class="hidden group-open:inline">{{ i "chevrons-down-up" "w-4 h-4" }}</span>
499
-
</div>
500
-
</summary>
501
{{ if gt (len .MergeCheck.Conflicts) 0 }}
502
-
<ul class="space-y-1 mt-2">
503
{{ range .MergeCheck.Conflicts }}
504
{{ if .Filename }}
505
-
<li class="flex items-center">
506
-
{{ i "file-warning" "inline-flex w-4 h-4 mr-1.5 text-red-500 dark:text-red-300 flex-shrink-0" }}
507
-
<span class="font-mono" style="word-break: keep-all; overflow-wrap: break-word;">{{ .Filename }}</span>
508
-
</li>
509
{{ else if .Reason }}
510
<li class="flex items-center">
511
{{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }}
···
515
{{ end }}
516
</ul>
517
{{ end }}
518
-
</details>
519
</div>
520
{{ else if .MergeCheck }}
521
-
<div class="bg-green-50 dark:bg-green-900 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative">
522
<div class="flex items-center gap-2 text-green-500 dark:text-green-300">
523
{{ i "circle-check-big" "w-4 h-4" }}
524
<span class="font-medium">no conflicts, ready to merge</span>
···
529
530
{{ define "resubmitStatus" }}
531
{{ if .ResubmitCheck.Yes }}
532
-
<div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative">
533
<div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
534
{{ i "triangle-alert" "w-4 h-4" }}
535
<span class="font-medium">this branch has been updated, consider resubmitting</span>
···
545
{{ with $pipeline }}
546
{{ $id := .Id }}
547
{{ if .Statuses }}
548
-
<span>Workflows:</span>
549
-
<div class=" 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">
550
{{ range $name, $all := .Statuses }}
551
<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">
552
<div
···
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
···
26
"Backlinks" $.Backlinks) }}
27
{{ template "repo/fragments/externalLinkPanel" $.Pull.AtUri }}
28
</div>
29
</div>
30
{{ end }}
31
32
{{ define "repoContent" }}
33
{{ template "repo/pulls/fragments/pullHeader" . }}
34
+
35
{{ if .Pull.IsStacked }}
36
<div class="mt-8">
37
{{ template "repo/pulls/fragments/pullStack" . }}
···
40
{{ end }}
41
42
{{ define "repoAfter" }}
43
+
<section id="submissions" class="mt-4">
44
+
<div class="flex flex-col gap-4">
45
+
{{ block "submissions" . }} {{ end }}
46
</div>
47
+
</section>
48
49
+
<div id="pull-close"></div>
50
+
<div id="pull-reopen"></div>
51
{{ end }}
52
53
{{ define "submissions" }}
···
216
217
{{ define "mergeStatus" }}
218
{{ if .Pull.State.IsClosed }}
219
+
<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">
220
<div class="flex items-center gap-2 text-black dark:text-white">
221
{{ i "ban" "w-4 h-4" }}
222
<span class="font-medium">closed without merging</span
···
224
</div>
225
</div>
226
{{ else if .Pull.State.IsMerged }}
227
+
<div class="bg-purple-50 dark:bg-purple-900 border border-purple-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
228
<div class="flex items-center gap-2 text-purple-500 dark:text-purple-300">
229
{{ i "git-merge" "w-4 h-4" }}
230
<span class="font-medium">pull request successfully merged</span
···
232
</div>
233
</div>
234
{{ else if .Pull.State.IsDeleted }}
235
+
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
236
<div class="flex items-center gap-2 text-red-500 dark:text-red-300">
237
{{ i "git-pull-request-closed" "w-4 h-4" }}
238
<span class="font-medium">This pull has been deleted (possibly by jj abandon or jj squash)</span>
239
</div>
240
</div>
241
{{ else if and .MergeCheck .MergeCheck.Error }}
242
+
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
243
<div class="flex items-center gap-2 text-red-500 dark:text-red-300">
244
{{ i "triangle-alert" "w-4 h-4" }}
245
<span class="font-medium">{{ .MergeCheck.Error }}</span>
246
</div>
247
</div>
248
{{ else if and .MergeCheck .MergeCheck.IsConflicted }}
249
+
<div class="bg-red-50 dark:bg-red-900 border border-red-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
250
+
<div class="flex flex-col gap-2 text-red-500 dark:text-red-300">
251
+
<div class="flex items-center gap-2">
252
+
{{ i "triangle-alert" "w-4 h-4" }}
253
+
<span class="font-medium">merge conflicts detected</span>
254
+
</div>
255
{{ if gt (len .MergeCheck.Conflicts) 0 }}
256
+
<ul class="space-y-1">
257
{{ range .MergeCheck.Conflicts }}
258
{{ if .Filename }}
259
+
<li class="flex items-center">
260
+
{{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }}
261
+
<span class="font-mono">{{ .Filename }}</span>
262
+
</li>
263
{{ else if .Reason }}
264
<li class="flex items-center">
265
{{ i "file-warning" "w-4 h-4 mr-1.5 text-red-500 dark:text-red-300" }}
···
269
{{ end }}
270
</ul>
271
{{ end }}
272
+
</div>
273
</div>
274
{{ else if .MergeCheck }}
275
+
<div class="bg-green-50 dark:bg-green-900 border border-green-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
276
<div class="flex items-center gap-2 text-green-500 dark:text-green-300">
277
{{ i "circle-check-big" "w-4 h-4" }}
278
<span class="font-medium">no conflicts, ready to merge</span>
···
283
284
{{ define "resubmitStatus" }}
285
{{ if .ResubmitCheck.Yes }}
286
+
<div class="bg-amber-50 dark:bg-amber-900 border border-amber-500 rounded drop-shadow-sm px-6 py-2 relative w-fit">
287
<div class="flex items-center gap-2 text-amber-500 dark:text-amber-300">
288
{{ i "triangle-alert" "w-4 h-4" }}
289
<span class="font-medium">this branch has been updated, consider resubmitting</span>
···
299
{{ with $pipeline }}
300
{{ $id := .Id }}
301
{{ if .Statuses }}
302
+
<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">
303
{{ range $name, $all := .Statuses }}
304
<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">
305
<div
+2
-11
appview/pulls/pulls.go
+2
-11
appview/pulls/pulls.go
···
232
defs[l.AtUri().String()] = &l
233
}
234
235
-
patch := pull.LatestSubmission().CombinedPatch()
236
-
diff := patchutil.AsNiceDiff(patch, pull.TargetBranch)
237
-
var diffOpts types.DiffOpts
238
-
if d := r.URL.Query().Get("diff"); d == "split" {
239
-
diffOpts.Split = true
240
-
}
241
-
242
-
log.Println(s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{
243
LoggedInUser: user,
244
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
245
Pull: pull,
···
250
MergeCheck: mergeCheckResponse,
251
ResubmitCheck: resubmitResult,
252
Pipelines: m,
253
-
Diff: &diff,
254
-
DiffOpts: diffOpts,
255
256
OrderedReactionKinds: models.OrderedReactionKinds,
257
Reactions: reactionMap,
258
UserReacted: userReactions,
259
260
LabelDefs: defs,
261
-
}))
262
}
263
264
func (s *Pulls) mergeCheck(r *http.Request, f *models.Repo, pull *models.Pull, stack models.Stack) types.MergeCheckResponse {
···
232
defs[l.AtUri().String()] = &l
233
}
234
235
+
s.pages.RepoSinglePull(w, pages.RepoSinglePullParams{
236
LoggedInUser: user,
237
RepoInfo: s.repoResolver.GetRepoInfo(r, user),
238
Pull: pull,
···
243
MergeCheck: mergeCheckResponse,
244
ResubmitCheck: resubmitResult,
245
Pipelines: m,
246
247
OrderedReactionKinds: models.OrderedReactionKinds,
248
Reactions: reactionMap,
249
UserReacted: userReactions,
250
251
LabelDefs: defs,
252
+
})
253
}
254
255
func (s *Pulls) mergeCheck(r *http.Request, f *models.Repo, pull *models.Pull, stack models.Stack) types.MergeCheckResponse {
+5
-6
docs/template.html
+5
-6
docs/template.html
-13
input.css
-13
input.css
···
124
dark:text-gray-100 dark:before:bg-gray-800 dark:before:border-gray-700;
125
}
126
127
-
.btn-flat {
128
-
@apply relative z-10 inline-flex min-h-[30px] cursor-pointer items-center justify-center
129
-
bg-transparent px-2 pb-[0.2rem] text-sm text-gray-900
130
-
before:absolute before:inset-0 before:-z-10 before:block before:rounded
131
-
before:border before:border-gray-200 before:bg-white
132
-
before:content-[''] before:transition-all before:duration-150 before:ease-in-out
133
-
hover:before:bg-gray-50
134
-
dark:hover:before:bg-gray-700
135
-
focus:outline-none focus-visible:before:outline focus-visible:before:outline-2 focus-visible:before:outline-gray-400
136
-
disabled:cursor-not-allowed disabled:opacity-50
137
-
dark:text-gray-100 dark:before:bg-gray-800 dark:before:border-gray-700;
138
-
}
139
-
140
.btn-create {
141
@apply btn text-white
142
before:bg-green-600 hover:before:bg-green-700
+3
nix/modules/appview.nix
+3
nix/modules/appview.nix
+2
-4
types/diff.go
+2
-4
types/diff.go
···
27
}
28
29
type DiffStat struct {
30
-
Insertions int64
31
-
Deletions int64
32
-
FilesChanged int
33
}
34
35
func (d *Diff) Stats() DiffStat {
···
38
stats.Insertions += f.LinesAdded
39
stats.Deletions += f.LinesDeleted
40
}
41
-
stats.FilesChanged = len(d.TextFragments)
42
return stats
43
}
44