- commit
- a444d69
- parent
- 603c411
- author
- Eric Bower
- date
- 2025-12-28 22:41:23 -0500 EST
style: tabbed layout for PRs
5 files changed,
+73,
-38
+25,
-0
1@@ -101,6 +101,31 @@ details {
2 overflow-x: scroll;
3 }
4
5+.pr-tabs {
6+ display: flex;
7+ gap: 0;
8+ border-bottom: 1px solid var(--grey-light);
9+ margin-bottom: var(--line-height);
10+}
11+
12+.pr-tab {
13+ padding: 0.5rem 1rem;
14+ text-decoration: none;
15+ border: 1px solid transparent;
16+ border-bottom: none;
17+ margin-bottom: -1px;
18+}
19+
20+.pr-tab:hover {
21+ background-color: var(--grey-light);
22+}
23+
24+.pr-tab-active {
25+ border-color: var(--grey-light);
26+ border-bottom: 1px solid var(--bg-color);
27+ background-color: var(--bg-color);
28+}
29+
30 @media only screen and (max-width: 40em) {
31 .collapse {
32 flex-direction: column;
+6,
-0
1@@ -0,0 +1,6 @@
2+{{define "pr-tabs"}}
3+<div class="pr-tabs">
4+ <a href="/prs/{{.Pr.ID}}" class="pr-tab{{if eq .Tab "timeline"}} pr-tab-active{{end}}">Timeline</a>
5+ <a href="/ps/{{.Patchset.ID}}" class="pr-tab{{if eq .Tab "patchsets"}} pr-tab-active{{end}}">Patchsets</a>
6+</div>
7+{{end}}
+1,
-1
1@@ -82,7 +82,7 @@
2 {{end}}
3
4 <div>
5- {{- if .Files -}}
6+ {{- if and .Files (ne .Type "add") -}}
7 {{range .Files}}
8 <div class="flex gap">
9 <div class="flex-1" style="width: 48%;">
+24,
-36
1@@ -16,10 +16,27 @@
2 {{template "pr-header" .}}
3
4 <main class="group">
5- <div class="flex gap-2 collapse">
6- <div class="group text-sm" style="width: 300px;">
7- <h3 class="text-lg">Logs</h3>
8- {{range .Logs}}
9+ {{template "pr-tabs" .}}
10+
11+ {{if eq .Tab "timeline"}}
12+ <div class="group text-sm timeline">
13+ {{range .Logs}}
14+ <div class="timeline-item">
15+ {{if .RangeDiff}}
16+ <details class="mb">
17+ <summary class="text-sm">Range Diff ↕ <code><a href="/rd/{{.Patchset.ID}}">rd-{{.Patchset.ID}}</a></code></summary>
18+ <div class="group">
19+ {{- range .RangeDiff -}}
20+ <div>
21+ <code class='{{if eq .Type "rm"}}pill-admin{{else if eq .Type "add"}}pill-success{{else if eq .Type "diff"}}pill-review{{end}}'>
22+ {{.Header}}
23+ </code>
24+ </div>
25+ {{- end -}}
26+ </div>
27+ </details>
28+ {{end}}
29+
30 <div>
31 {{template "user-pill" .UserData}}
32 <span class="font-bold">
33@@ -44,44 +61,15 @@
34 <span>on <date>{{.Date}}</date></span>
35 {{if .Data.String}}<code>{{.Data}}</code>{{end}}
36 </div>
37- {{end}}
38- </div>
39-
40- <div class="group text-sm flex-1">
41- <h3 class="text-lg">Patchsets</h3>
42-
43- {{range .Patchsets}}
44- {{if .RangeDiff}}
45- <details>
46- <summary class="text-sm">Range Diff ↕ <code><a href="/rd/{{.ID}}">rd-{{.ID}}</a></code></summary>
47- <div class="group">
48- {{- range .RangeDiff -}}
49- <div>
50- <code class='{{if eq .Type "rm"}}pill-admin{{else if eq .Type "add"}}pill-success{{else if eq .Type "diff"}}pill-review{{end}}'>
51- {{.Header}}
52- </code>
53- </div>
54- {{- end -}}
55- </div>
56- </details>
57- {{end}}
58-
59- <div>
60- <a href="/ps/{{.Patchset.ID}}"><code class="{{if .Review}}pill-review{{end}}">{{.FormattedID}}</code></a>
61- <span> by </span>
62- {{template "user-pill" .UserData}}
63- <span>on <date>{{.Date}}</date></span>
64- </div>
65- {{end}}
66 </div>
67+ {{end}}
68 </div>
69-
70- <hr class="w-full" />
71-
72+ {{else}}
73 {{if .IsRangeDiff}}
74 {{template "range-diff" .}}
75 {{else}}
76 {{template "patchset" .}}
77 {{end}}
78+ {{end}}
79 </main>
80 {{end}}
M
web.go
+17,
-1
1@@ -545,6 +545,7 @@ type EventLogData struct {
2 *Patchset
3 FormattedPatchsetID string
4 Date string
5+ RangeDiff []*RangeDiffOutput
6 }
7
8 type PatchsetData struct {
9@@ -557,6 +558,7 @@ type PatchsetData struct {
10
11 type PrDetailData struct {
12 Page string
13+ Tab string
14 Repo LinkData
15 Pr PrData
16 Patchset *Patchset
17@@ -805,6 +807,7 @@ func createPrDetail(page string) http.HandlerFunc {
18 return
19 }
20 var logps *Patchset
21+ var rangeDiff []*RangeDiffOutput
22 if eventlog.PatchsetID.Int64 > 0 {
23 logps, err = web.Pr.GetPatchsetByID(eventlog.PatchsetID.Int64)
24 if err != nil {
25@@ -812,12 +815,19 @@ func createPrDetail(page string) http.HandlerFunc {
26 w.WriteHeader(http.StatusUnprocessableEntity)
27 return
28 }
29+ for _, psData := range patchsetsData {
30+ if psData.Patchset.ID == eventlog.PatchsetID.Int64 {
31+ rangeDiff = psData.RangeDiff
32+ break
33+ }
34+ }
35 }
36
37 logData = append(logData, EventLogData{
38 EventLog: eventlog,
39 FormattedPatchsetID: getFormattedPatchsetID(eventlog.PatchsetID.Int64),
40 Patchset: logps,
41+ RangeDiff: rangeDiff,
42 UserData: UserData{
43 UserID: user.ID,
44 Name: user.Name,
45@@ -845,8 +855,14 @@ func createPrDetail(page string) http.HandlerFunc {
46
47 repoNs := web.Backend.CreateRepoNs(repoOwner.Name, repo.Name)
48 url := fmt.Sprintf("/r/%s/%s", repoOwner.Name, repo.Name)
49+ tab := "timeline"
50+ if page == "ps" || page == "rd" {
51+ tab = "patchsets"
52+ }
53+
54 err = prTmpl.Execute(w, PrDetailData{
55- Page: "pr",
56+ Page: page,
57+ Tab: tab,
58 Repo: LinkData{
59 Url: template.URL(url),
60 Text: repoNs,