add information about assignment status

This commit is contained in:
Özgür Kesim 2023-12-28 17:03:33 +01:00
parent ba0d009881
commit 2f6c7f2a7d
Signed by: oec
GPG Key ID: F136A7F922D018D7
3 changed files with 149 additions and 94 deletions

View File

@ -36,7 +36,7 @@ type Issue struct {
Category KeyVal Category KeyVal
TargetVersion KeyVal `json:"target_version"` TargetVersion KeyVal `json:"target_version"`
Reporter KeyVal Reporter KeyVal
handler KeyVal Handler KeyVal
Status KeyVal Status KeyVal
Resolution KeyVal Resolution KeyVal
ViewState KeyVal `json:"view_state"` ViewState KeyVal `json:"view_state"`
@ -103,6 +103,15 @@ func (b ByCategory) Less(i, j int) bool {
} }
func (b ByCategory) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b ByCategory) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
type ByAssignment []Issue
func (b ByAssignment) Len() int { return len(b) }
func (b ByAssignment) Less(i, j int) bool {
return strings.Compare(b[i].Handler.Name, b[j].Handler.Name) < 0
}
func (b ByAssignment) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
type ById []Issue type ById []Issue
func (b ById) Len() int { return len(b) } func (b ById) Len() int { return len(b) }
@ -117,6 +126,19 @@ func (b ByTarget) Less(i, j int) bool {
} }
func (b ByTarget) Swap(i, j int) { b[i], b[j] = b[j], b[i] } func (b ByTarget) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
type ByHandlerAndId []Issue
func (b ByHandlerAndId) Len() int { return len(b) }
func (b ByHandlerAndId) Less(i, j int) bool {
if (b[i].Handler.Name == "") == (b[j].Handler.Name == "") {
return b[i].Id < b[j].Id
} else if b[i].Handler.Name == "" {
return true
}
return false
}
func (b ByHandlerAndId) Swap(i, j int) { b[i], b[j] = b[j], b[i] }
func (i Issues) Tags() (tags []string) { func (i Issues) Tags() (tags []string) {
var m = map[string]bool{} var m = map[string]bool{}
for _, issue := range i { for _, issue := range i {
@ -131,6 +153,19 @@ func (i Issues) Tags() (tags []string) {
return return
} }
func (is Issues) Assigned(assigned bool) (n int) {
for _, i := range is {
if assigned == (i.Handler.Name != "") {
n += 1
}
}
return n
}
func (i *Issue) IsHandled() bool {
return i.Handler.Name != ""
}
func (i Issues) TargetVersions() (targets []string) { func (i Issues) TargetVersions() (targets []string) {
var m = map[string]bool{} var m = map[string]bool{}
for _, issue := range i { for _, issue := range i {
@ -164,7 +199,7 @@ func (i Issues) ByCategory(cat string) (issues Issues) {
issues = append(issues, issue) issues = append(issues, issue)
} }
} }
sort.Sort(ById(issues)) sort.Sort(sort.Reverse(ByHandlerAndId(issues)))
return issues return issues
} }
@ -175,6 +210,6 @@ func (i Issues) ByCategoryAndTarget(cat, tar string) (issues Issues) {
issues = append(issues, is) issues = append(issues, is)
} }
} }
sort.Sort(ById(issues)) sort.Sort(sort.Reverse(ByHandlerAndId(issues)))
return return
} }

View File

@ -42,14 +42,18 @@ pre {
<h4>Features</h4> <h4>Features</h4>
{{- range $features.ByCategory $cat }} {{- range $features.ByCategory $cat }}
<details> <details>
<summary><a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}</summary> <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> {{.Summary}}</summary>
<pre>{{ .Description }}</pre> <pre>{{ .Description }}</pre>
</details> </details>
{{ end -}} {{ end -}}
<h4>Issues</h4> <h4>Issues</h4>
{{- range $issues.ByCategory $cat }} {{- range $issues.ByCategory $cat }}
<details> <details>
<summary><a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}</summary> <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> {{.Summary}}</summary>
<pre>{{ .Description }}</pre> <pre>{{ .Description }}</pre>
</details> </details>
{{ end -}} {{ end -}}

View File

@ -1,121 +1,137 @@
<!DOCTYPE html> <!DOCTYPE html>
<head><title>GNU Taler Dashboard</title> <head><title>GNU Taler Dashboard</title>
<style> <style>
body { body {
margin-left:1%; margin-left:1%;
margin-right:1%; margin-right:1%;
font-family:sans-serif; font-family:sans-serif;
} }
table { table {
background: white; background: white;
border-collapse: collapse; border-collapse: collapse;
} }
th, td { th, td {
padding: 8px; padding: 8px;
border: 1px solid #ddd; border: 1px solid #ddd;
vertical-align: top; vertical-align: top;
} }
td { td {
min-width: 10em; min-width: 10em;
} }
th.side { th.side {
color: brown; color: brown;
text-align: right; text-align: right;
} }
tr:hover { tr:hover {
background: #efe; background: #efefef;
} }
.feature { .feature {
background: #cde; background: #cdf;
} }
.issue { .issue {
background: #edc; background: #edc;
} }
.minh { .minh {
min-height: 5em; min-height: 5em;
}
summary {
display: flex;
justify-content: space-between;
align-items: center;
gap: 5px;
}
.assignment {
font-size: smaller;
color: grey;
} }
details { details {
max-width: 50vw; max-width: 50vw;
border-radius: 5px; border-radius: 5px;
padding: 8px; padding: 8px;
overflow-x: auto; overflow-x: auto;
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
} }
details[open] { details[open] {
position: absolute; position: absolute;
background: white; background: white;
border: 2px grey solid; border: 2px grey solid;
} }
details.version { details.version {
max-width: 30vw; max-width: 30vw;
padding: 5px; padding: 5px;
font-weight: normal; font-weight: normal;
overflow: none; overflow: none;
white-space: normal; white-space: normal;
text-align: justify; text-align: justify;
} }
details[open].feature { details[open].feature {
background: aliceblue; background: aliceblue;
border: 2px midnightblue solid; border: 2px midnightblue solid;
} }
details[open].issue { details[open].issue {
background: lightyellow; background: lightyellow;
border: 2px brown solid; border: 2px brown solid;
} }
</style></head> </style></head>
<body> <body>
<h1>GNU Taler Dashboard</h1> <h1>GNU Taler Dashboard</h1>
<h2>Table view | <a href="/list">List View</a></h2> <h2>Table view | <a href="/list">List View</a></h2>
Data from {{ .Timestamp.Format "02 Jan 06 15:04 MST"}}, updateting every {{ .Freq }} (no auto-refresh) Data from {{ .Timestamp.Format "02 Jan 06 15:04 MST"}}, updateting every {{ .Freq }} (no auto-refresh)
{{- with .Lasterror }}, Last error: {{ . }} {{end }} {{- with .Lasterror }}, Last error: {{ . }} {{end }}
{{- $top := . -}} {{- $top := . -}}
{{- $features := .Features -}} {{- $features := .Features -}}
{{- $issues := .Issues -}} {{- $issues := .Issues -}}
{{- $versions := .VersionsByDate -}} {{- $versions := .VersionsByDate -}}
<!--p> <!--p>
{{- range $top.Tags -}}<button>{{ . }}</button>{{- end -}} {{- range $top.Tags -}}<button>{{ . }}</button>{{- end -}}
</p--> </p-->
<table> <table>
<tr> <tr>
<th class="side"></th> <th class="side"></th>
{{- range $vname := $top.TargetVersions }} {{- range $vname := $top.TargetVersions }}
{{- with $version := $versions.Get . }} {{- with $version := $versions.Get . }}
<th> <th>
<details class="version"> <details class="version">
<summary><b>{{ $vname }}</b> ({{ $version.Timestamp.Format "02 Jan 06"}})</summary> <summary><b>{{ $vname }}</b> ({{ $version.Timestamp.Format "02 Jan 06"}})</summary>
<div>{{ $version.Description }}</div> <div>{{ $version.Description }}</div>
</details> </details>
</th> </th>
{{- end}} {{- end}}
{{- end}} {{- end}}
</tr> </tr>
{{- range $cat := $top.Categories }} {{- range $cat := $top.Categories }}
<tr> <tr>
<th class="side">{{ . }}</th> <th class="side">{{ . }}</th>
{{- range $tar := $top.TargetVersions }} {{- range $tar := $top.TargetVersions }}
{{- with $version := $versions.Get . }} {{- with $version := $versions.Get . }}
<td><div class="minh">{{ with $features.ByCategoryAndTarget $cat $tar }} <td><div class="minh">{{ with $features.ByCategoryAndTarget $cat $tar }}
<details class="feature"> <details class="feature">
<summary>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} features{{ else }}1 feature{{ end }}</summary> <summary>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} features{{ else }}1 feature{{ end }}
{{- range . }} {{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }} <span class="assignment">({{ $unassigned}} unassigned)</span>{{ end -}}
<a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}<br> </summary>
{{- end}} {{- range . }}
</details> {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
{{- end }} <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}<br>
{{- with $issues.ByCategoryAndTarget $cat $tar }} {{- end}}
<details class="issue"> </details>
<summary>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} issues{{ else }}1 issue{{ end }}</summary> {{- end }}
{{- range . }} {{- with $issues.ByCategoryAndTarget $cat $tar }}
<a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}<br>{{end}} <details class="issue">
</details> <summary>{{ $l := len .}}{{ if lt 1 $l }}{{ $l }} issues{{ else }}1 issue{{ end }}
{{ end -}} {{- $unassigned := .Assigned false }}{{if gt $unassigned 0 }} <span class="assignment">({{ $unassigned}} unassigned)</span>{{ end -}}
</div></td>{{ end }} </summary>
{{ end }} {{- range . }}
</tr> {{ if .IsHandled }}<span title="assigned to {{.Handler.Name}}">🥷</span>{{else}}<span title="unassigned">❓</span>{{end}}
{{- end}} <a href="https://bugs.gnunet.org/view.php?id={{.Id}}" target="_blank">{{.Id}}</a> {{.Summary}}<br>{{end}}
</table> </details>
<p> {{ end -}}
<i>taler-dashboard - version: {{.Commit}} - <a href="https://git.kesim.org/taler/taler-dashboard">https://git.kesim.org/taler/taler-dashboard</a> </i> </div></td>{{ end }}
</body> {{ end }}
</tr>
{{- end}}
</table>
<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> </html>