aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorÖzgür Kesim <oec@codeblau.de>2023-12-30 17:42:58 +0100
committerÖzgür Kesim <oec@codeblau.de>2023-12-30 17:42:58 +0100
commitab4fc1c85cff109d8799da3bd49e210a7fa708b0 (patch)
treeac583fc049241fdd79f8c4279e6ff8f74c4f5c52
parentcbc12b958b78d5934fc76a99605f177abb79125c (diff)
sort by multiple layers; common severity
-rw-r--r--data.go5
-rw-r--r--issues.go85
-rw-r--r--list.tmpl115
-rw-r--r--severity.tmpl7
-rw-r--r--table.tmpl48
5 files changed, 170 insertions, 90 deletions
diff --git a/data.go b/data.go
index 1e1c59c..4b782eb 100644
--- a/data.go
+++ b/data.go
@@ -61,7 +61,10 @@ func NewData(ctx context.Context, url, token string, num int) *Data {
ctx: ctx,
num: num,
}
- data.tmpl = template.Must(template.New("index").ParseFS(content, "*.tmpl"))
+ funcMap := map[string]any{
+ "OrderedBy": OrderedBy,
+ }
+ data.tmpl = template.Must(template.New("index").Funcs(funcMap).ParseFS(content, "*.tmpl"))
return data
}
diff --git a/issues.go b/issues.go
index 055b720..48ced5f 100644
--- a/issues.go
+++ b/issues.go
@@ -21,6 +21,7 @@ package main
*/
import (
+ "log"
"sort"
"strings"
"time"
@@ -103,7 +104,7 @@ func (b ByCategory) Less(i, j int) bool {
}
func (b ByCategory) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-type ByAssignment []Issue
+type ByAssignment []Issue
func (b ByAssignment) Len() int { return len(b) }
func (b ByAssignment) Less(i, j int) bool {
@@ -111,7 +112,6 @@ func (b ByAssignment) Less(i, j int) bool {
}
func (b ByAssignment) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
-
type ById []Issue
func (b ById) Len() int { return len(b) }
@@ -199,7 +199,7 @@ func (i Issues) ByCategory(cat string) (issues Issues) {
issues = append(issues, issue)
}
}
- sort.Sort(sort.Reverse(ByHandlerAndId(issues)))
+ sort.Sort(sort.Reverse(ByHandlerAndId(issues)))
return issues
}
@@ -213,3 +213,82 @@ func (i Issues) ByCategoryAndTarget(cat, tar string) (issues Issues) {
sort.Sort(sort.Reverse(ByHandlerAndId(issues)))
return
}
+
+// Follow the example for multiSort in https://pkg.go.dev/sort
+
+type lessFunc func(i1, i2 *Issue) bool
+
+type multiSorter struct {
+ issues Issues
+ less []lessFunc
+}
+
+func (ms *multiSorter) Len() int {
+ return len(ms.issues)
+}
+
+func (ms *multiSorter) Sort(issues Issues) Issues {
+ ms.issues = issues
+ sort.Sort(ms)
+ return ms.issues
+}
+
+func (ms *multiSorter) Swap(i, j int) {
+ ms.issues[i], ms.issues[j] = ms.issues[j], ms.issues[i]
+}
+
+func (ms *multiSorter) Less(i, j int) bool {
+ p, q := &ms.issues[i], &ms.issues[j]
+ var k int
+ for k = 0; k < len(ms.less)-1; k++ {
+ less := ms.less[k]
+ switch {
+ case less(p, q):
+ return true
+ case less(q, p):
+ return false
+ }
+ }
+ return ms.less[k](p, q)
+}
+
+var severityOrder = map[string]int{
+ "block": 0,
+ "crash": 1,
+ "major": 2,
+ "minor": 3,
+ "text": 4,
+ "trivial": 5,
+ "tweak": 6}
+
+var lessFuncs = map[string]lessFunc{
+ "Category": func(i1, i2 *Issue) bool { return strings.Compare(i1.Category.Name, i2.Category.Name) < 0 },
+ "Assignment": func(i1, i2 *Issue) bool { return strings.Compare(i1.Handler.Name, i2.Handler.Name) < 0 },
+ "Handler": func(i1, i2 *Issue) bool { return strings.Compare(i1.Handler.Name, i2.Handler.Name) < 0 },
+ "Target": func(i1, i2 *Issue) bool { return strings.Compare(i1.TargetVersion.Name, i2.TargetVersion.Name) < 0 },
+ "Id": func(i1, i2 *Issue) bool { return i1.Id < i2.Id },
+ "Severity": func(i1, i2 *Issue) bool {
+ s1, ok := severityOrder[i1.Severity.Name]
+ if !ok {
+ return true
+ }
+ s2, ok := severityOrder[i2.Severity.Name]
+ if !ok {
+ return false
+ }
+ return s1 < s2
+ },
+}
+
+func OrderedBy(fields ...string) *multiSorter {
+ m := &multiSorter{}
+ for _, field := range fields {
+ fn, ok := lessFuncs[field]
+ if !ok {
+ log.Printf("unknown field to order by: %s\n", field)
+ return nil
+ }
+ m.less = append(m.less, fn)
+ }
+ return m
+}
diff --git a/list.tmpl b/list.tmpl
index 0433d0c..90b6fe0 100644
--- a/list.tmpl
+++ b/list.tmpl
@@ -1,75 +1,70 @@
<!DOCTYPE html>
- <head><title>GNU Taler Dashboard</title>
+<head><title>GNU Taler Dashboard</title>
<style>
body {
- margin-left:1%;
- margin-right:1%;
- font-family:sans-serif;
+ margin-left:1%;
+ margin-right:1%;
+ font-family:sans-serif;
}
h3 {
- color: brown;
+ color: brown;
}
h4 {
- margin-left: 5%;
+ margin-left: 5%;
}
details {
- margin-left: 5%;
- margin-right: 5%;
+ margin-left: 5%;
+ margin-right: 5%;
}
pre {
- max-width: 100%;
- overflow: scroll;
- text-overflow: wrap,ellipsis;
+ max-width: 100%;
+ overflow: scroll;
+ text-overflow: wrap,ellipsis;
}
-.severity-block { color: red; font-style: bold; }
-.severity-crash { color: red; }
-.severity-major { color: brown; }
-.severity-minor { color: darkorange; }
-.severity-text { color: black; }
-.severity-trivial { color: blue; }
-.severity-tweak { color: grey; }
+{{template "severity.tmpl"}}
</style></head>
- <body>
- <h1>GNU Taler Dashboard</h1>
- <h2><a href="/">Table view</a> | List View </h2>
- Data from {{ .Timestamp.Format "02 Jan 06 15:04 MST"}}, updateting every {{ .Freq }} (no auto-refresh)
- {{ with .Lasterror }}, Last error: {{ . }} {{end}}
- {{- $top := . }}
- {{- $features := .Features }}
- {{- $issues := .Issues }}
- {{- $versions := .VersionsByDate }}
- <!-- p>
- {{- range $top.Tags }}
- <button>{{ . }}</button>
- {{ end -}}
- </p -->
+ <body>
+ <h1>GNU Taler Dashboard</h1>
+ <h2><a href="/">Table view</a> | List View </h2>
+ Data from {{ .Timestamp.Format "02 Jan 06 15:04 MST"}}, updateting every {{ .Freq }} (no auto-refresh)
+ {{ with .Lasterror }}, Last error: {{ . }} {{end}}
+ {{- $top := . }}
+ {{- $features := .Features }}
+ {{- $issues := .Issues }}
+ {{- $versions := .VersionsByDate }}
+ {{- $sorter := OrderedBy "Severity" "Handler" "Id" -}}
+ <!-- p>
+ {{- range $top.Tags }}
+ <button>{{ . }}</button>
+ {{ end -}}
+ </p -->
- {{- range $cat := $top.Categories }}
- <h3>{{ . }}</h3>
- <h4>Features</h4>
- {{- range $features.ByCategory $cat }}
- <details>
- <summary>
- {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
- <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
- <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
- </summary>
- <pre>{{ .Description }}</pre>
- </details>
- {{ end -}}
- <h4>Issues</h4>
- {{- range $issues.ByCategory $cat }}
- <details>
- <summary>
- {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
- <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
- <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
- </summary>
- <pre>{{ .Description }}</pre>
- </details>
- {{ end -}}
- {{ end -}}
- <p>
- <i>taler-dashboard - version: {{.Commit}} - <a href="https://git.kesim.org/taler/taler-dashboard">https://git.kesim.org/taler/taler-dashboard</a> </i>
- </body>
+ {{- range $cat := $top.Categories }}
+ <h3>{{ . }}</h3>
+ <h4>Features</h4>
+ {{- range $sorter.Sort ($features.ByCategory $cat) }}
+ <details>
+ <summary>
+ {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
+ <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
+ <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
+ </summary>
+ <pre>{{ .Description }}</pre>
+ </details>
+ {{ end -}}
+ <h4>Issues</h4>
+ {{- range $sorter.Sort ($issues.ByCategory $cat) }}
+ <details>
+ <summary>
+ {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
+ <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
+ <span class="severity-{{.Severity.Name}}" title="severity {{.Severity.Name}}">{{.Summary}}</span><br>
+ </summary>
+ <pre>{{ .Description }}</pre>
+ </details>
+ {{ end -}}
+ {{ end -}}
+ <p>
+ <i>taler-dashboard - version: {{.Commit}} - <a href="https://git.kesim.org/taler/taler-dashboard">https://git.kesim.org/taler/taler-dashboard</a> </i>
+ </body>
</html>
diff --git a/severity.tmpl b/severity.tmpl
new file mode 100644
index 0000000..d8a7230
--- /dev/null
+++ b/severity.tmpl
@@ -0,0 +1,7 @@
+.severity-block { color: red; font-weight: bold; }
+.severity-crash { color: deeppink; font-weight: bold; }
+.severity-major { color: crimson; }
+.severity-minor { color: sienna; }
+.severity-text { color: black; }
+.severity-trivial { color: grey; }
+.severity-tweak { color: steelblue; }
diff --git a/table.tmpl b/table.tmpl
index d28833e..43925a2 100644
--- a/table.tmpl
+++ b/table.tmpl
@@ -26,21 +26,15 @@ tr:hover {
background: #efefef;
}
.feature {
- background: #cdf;
+ background: powderblue;
}
.issue {
- background: #edc;
+ background: navajowhite;
}
.minh {
min-height: 5em;
}
-.severity-block { color: red; font-style: bold; }
-.severity-crash { color: red; }
-.severity-major { color: brown; }
-.severity-minor { color: darkorange; }
-.severity-text { color: black; }
-.severity-trivial { color: blue; }
-.severity-tweak { color: grey; }
+{{template "severity.tmpl"}}
summary {
display: flex;
justify-content: space-between;
@@ -74,19 +68,19 @@ details.version {
text-align: justify;
}
details[open].feature {
- background: aliceblue;
- border: 2px midnightblue solid;
+ background: ghostwhite;
+ border: 4px powderblue solid;
}
details[open].issue {
- background: lightyellow;
- border: 2px brown solid;
+ background: ghostwhite;
+ border: 4px navajowhite solid;
}
</style></head>
<body>
<h1>GNU Taler Dashboard</h1>
<h2>Table view | <a href="/list">List View</a></h2>
Data from {{ .Timestamp.Format "02 Jan 06 15:04 MST"}}, updated every {{ .Freq }} (no auto-refresh).
- {{- with .Lasterror }}, Last error: {{ . }} {{end }}
+ {{- with .Lasterror }} Last error: {{ . }} {{end }}
{{- $top := . -}}
{{- $features := .Features -}}
{{- $issues := .Issues -}}
@@ -116,27 +110,29 @@ details[open].issue {
{{- with $version := $versions.Get . }}
<td><div class="minh">{{ with $features.ByCategoryAndTarget $cat $tar }}
<details class="feature">
- <summary>
- <div>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} features{{ else }}1 feature{{ end }}</div>
- <div class="assignment">{{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }}({{ $unassigned}} unassigned){{ end -}}</div>
- </summary>
- {{- range . }}
+ <summary>
+ <div>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} features{{ else }}1 feature{{ end }}</div>
+ <div class="assignment">{{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }}({{ $unassigned}} unassigned){{ end -}}</div>
+ </summary>
+ {{- $sorter := OrderedBy "Handler" "Id" -}}
+ {{- range $sorter.Sort . }}
{{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
<a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
- <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
+ <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
{{- end}}
</details>
{{- end }}
{{- with $issues.ByCategoryAndTarget $cat $tar }}
<details class="issue">
- <summary>
- <div>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} issues{{ else }}1 issue{{ end }}</div>
- <div class="assignment">{{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }} ({{ $unassigned}} unassigned){{ end -}}</div>
- </summary>
- {{- range . }}
+ <summary>
+ <div>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} issues{{ else }}1 issue{{ end }}</div>
+ <div class="assignment">{{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }} ({{ $unassigned}} unassigned){{ end -}}</div>
+ </summary>
+ {{- $sorter := OrderedBy "Severity" "Handler" "Id" -}}
+ {{- range $sorter.Sort . }}
{{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
<a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a>
- <span class="severity-{{.Severity.Name}}">{{.Summary}}</span><br>
+ <span class="severity-{{.Severity.Name}}" title="severity {{.Severity.Name}}">{{.Summary}}</span><br>
{{- end}}
</details>
{{ end -}}