UI changes for problems

This commit is contained in:
Magnus Åhall 2024-07-04 15:14:24 +02:00
parent 332788dd20
commit 09241e73a5
18 changed files with 125 additions and 40 deletions

12
main.go
View File

@ -535,7 +535,15 @@ func pageProblems(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
return return
} }
problems, err := ProblemsRetrieve(true, timeFrom, timeTo) // GET parameters for this page
var selection string
if r.URL.Query().Get("selection") == "all" {
selection = "ALL"
} else {
selection = "CURRENT"
}
problems, err := ProblemsRetrieve(selection == "ALL", timeFrom, timeTo)
if err != nil { if err != nil {
httpError(w, werr.Wrap(err).Log()) httpError(w, werr.Wrap(err).Log())
return return
@ -560,7 +568,9 @@ func pageProblems(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
page.Data = map[string]any{ page.Data = map[string]any{
"Problems": problems, "Problems": problems,
"ProblemsGrouped": problemsGrouped, "ProblemsGrouped": problemsGrouped,
"Selection": selection,
"TimeHidden": selection == "CURRENT",
"TimeSubmit": "/problems", "TimeSubmit": "/problems",
"TimeFrom": timeFrom.Format("2006-01-02T15:04:05"), "TimeFrom": timeFrom.Format("2006-01-02T15:04:05"),
"TimeTo": timeTo.Format("2006-01-02T15:04:05"), "TimeTo": timeTo.Format("2006-01-02T15:04:05"),

View File

@ -26,7 +26,7 @@ type Problem struct { // {{{
SectionName string `json:"section_name"` SectionName string `json:"section_name"`
} // }}} } // }}}
func ProblemsRetrieve(archived bool, from, to time.Time) (problems []Problem, err error) { // {{{ func ProblemsRetrieve(showCurrent bool, from, to time.Time) (problems []Problem, err error) { // {{{
problems = []Problem{} problems = []Problem{}
row := service.Db.Conn.QueryRow(` row := service.Db.Conn.QueryRow(`
SELECT SELECT
@ -48,11 +48,14 @@ func ProblemsRetrieve(archived bool, from, to time.Time) (problems []Problem, er
INNER JOIN area a ON s.area_id = a.id INNER JOIN area a ON s.area_id = a.id
WHERE WHERE
CASE CASE
WHEN $1 THEN true WHEN NOT $1 THEN p.end IS NULL
WHEN NOT $1 THEN p.end IS NULL WHEN $1 THEN
END AND p.start >= $2 AND
p.start >= $2 AND (
p.end <= $3 p.end IS NULL OR
p.end <= $3
)
END
ORDER BY ORDER BY
p.start DESC) p.start DESC)
@ -61,7 +64,7 @@ func ProblemsRetrieve(archived bool, from, to time.Time) (problems []Problem, er
(SELECT (SELECT
-1 AS id, -1 AS id,
null, dp.last_value,
null, null,
false, false,
'{}', '{}',
@ -78,7 +81,7 @@ func ProblemsRetrieve(archived bool, from, to time.Time) (problems []Problem, er
ORDER BY ORDER BY
dp.name ASC) dp.name ASC)
) AS problems`, ) AS problems`,
archived, showCurrent,
from, from,
to, to,
) )

View File

@ -13,3 +13,12 @@ body {
background-color: #a00; background-color: #a00;
text-align: center; text-align: center;
} }
span.error {
color: #f66;
}
input[type="datetime-local"] {
background-color: #1b4e78;
color: #ccc;
border: 1px solid #535353;
padding: 6px;
}

View File

@ -213,6 +213,12 @@ span.time {
span.seconds { span.seconds {
display: none; display: none;
} }
span.ok {
color: #0a0;
}
span.error {
color: #a00;
}
label { label {
user-select: none; user-select: none;
} }
@ -233,6 +239,9 @@ label {
width: min-content; width: min-content;
border-radius: 6px; border-radius: 6px;
} }
#time-selector.hidden {
display: none;
}
#time-selector button { #time-selector button {
width: 100px; width: 100px;
margin-top: 12px; margin-top: 12px;

View File

@ -21,9 +21,3 @@ input[type="datetime-local"] {
font-weight: 800; font-weight: 800;
color: #7bb8eb; color: #7bb8eb;
} }
#notifications .ok {
color: #0a0;
}
#notifications .error {
color: #a00;
}

View File

@ -45,7 +45,7 @@
} }
#areas .area .section { #areas .area .section {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
grid-gap: 8px 12px; grid-gap: 8px 12px;
} }
#areas .area .section .name { #areas .area .section .name {

View File

@ -13,3 +13,12 @@ body {
background-color: #a00; background-color: #a00;
text-align: center; text-align: center;
} }
span.error {
color: #f66;
}
input[type="datetime-local"] {
background-color: #202020;
color: #ccc;
border: 1px solid #535353;
padding: 6px;
}

View File

@ -213,6 +213,12 @@ span.time {
span.seconds { span.seconds {
display: none; display: none;
} }
span.ok {
color: #0a0;
}
span.error {
color: #a00;
}
label { label {
user-select: none; user-select: none;
} }
@ -233,6 +239,9 @@ label {
width: min-content; width: min-content;
border-radius: 6px; border-radius: 6px;
} }
#time-selector.hidden {
display: none;
}
#time-selector button { #time-selector button {
width: 100px; width: 100px;
margin-top: 12px; margin-top: 12px;

View File

@ -21,9 +21,3 @@ input[type="datetime-local"] {
font-weight: 800; font-weight: 800;
color: #777; color: #777;
} }
#notifications .ok {
color: #0a0;
}
#notifications .error {
color: #a00;
}

View File

@ -45,7 +45,7 @@
} }
#areas .area .section { #areas .area .section {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
grid-gap: 8px 12px; grid-gap: 8px 12px;
} }
#areas .area .section .name { #areas .area .section .name {

View File

@ -34,6 +34,14 @@ export class UI {
} }
} }
selectCurrent() {
location.href = '/problems?selection=current'
}
selectAll() {
location.href = '/problems?selection=all'
}
displayList() { displayList() {
document.querySelector('.display-list').classList.remove('hidden') document.querySelector('.display-list').classList.remove('hidden')
document.querySelector('.display-areas').classList.add('hidden') document.querySelector('.display-areas').classList.add('hidden')

View File

@ -20,3 +20,14 @@ body {
background-color: #a00; background-color: #a00;
text-align: center; text-align: center;
} }
span.error {
color: #f66;
}
input[type="datetime-local"] {
background-color: @bg2;
color: #ccc;
border: 1px solid #535353;
padding: 6px;
}

View File

@ -266,6 +266,14 @@ span.seconds {
display: none; display: none;
} }
span.ok {
color: #0a0;
}
span.error {
color: #a00;
}
label { label {
user-select: none; user-select: none;
} }
@ -289,6 +297,10 @@ label {
width: min-content; width: min-content;
border-radius: 6px; border-radius: 6px;
&.hidden {
display: none;
}
button { button {
width: 100px; width: 100px;
margin-top: 12px; margin-top: 12px;

View File

@ -25,12 +25,4 @@ input[type="datetime-local"] {
font-weight: @bold; font-weight: @bold;
color: @text3; color: @text3;
} }
.ok {
color: #0a0;
}
.error {
color: #a00;
}
} }

View File

@ -51,7 +51,7 @@
.area { .area {
.section { .section {
display: grid; display: grid;
grid-template-columns: repeat(3, min-content); grid-template-columns: repeat(4, min-content);
grid-gap: 8px 12px; grid-gap: 8px 12px;
.name { .name {

View File

@ -14,7 +14,7 @@
</script> </script>
<form action="{{ .Data.TimeSubmit }}" method="get" id="form-time-selector"> <form action="{{ .Data.TimeSubmit }}" method="get" id="form-time-selector" class="{{ if .Data.TimeHidden }}hidden{{ end }}">
<input type="hidden" name="time-preset" value=""> <input type="hidden" name="time-preset" value="">
<input type="hidden" name="time-offset" value=0> <input type="hidden" name="time-offset" value=0>

View File

@ -7,19 +7,22 @@
{{ block "page_label" . }}{{end}} {{ block "page_label" . }}{{end}}
<div style="margin-bottom: 16px"> {{ block "timefilter" . }}{{ end }}
{{ if eq .Data.Datapoint.Datatype "INT" }}
<div style="margin-top: 16px">
<input onchange="selectDisplay('graph')" name="display" type="radio" id="display-graph" {{ if $graph }} checked {{ end}}> <label for="display-graph">Graph</label> <input onchange="selectDisplay('graph')" name="display" type="radio" id="display-graph" {{ if $graph }} checked {{ end}}> <label for="display-graph">Graph</label>
<input onchange="selectDisplay('list')" name="display" type="radio" id="display-list" {{ if not $graph }} checked {{ end }}> <label for="display-list">List</label> <input onchange="selectDisplay('list')" name="display" type="radio" id="display-list" {{ if not $graph }} checked {{ end }}> <label for="display-list">List</label>
</div> </div>
{{ end }}
{{ block "timefilter" . }}{{ end }}
<script type="text/javascript"> <script type="text/javascript">
const inputDisplay = document.createElement('input') const inputDisplay = document.createElement('input')
inputDisplay.id = 'input-display' inputDisplay.id = 'input-display'
inputDisplay.name = 'display'
inputDisplay.type = 'hidden' inputDisplay.type = 'hidden'
document.getElementById('form-time-selector').append(inputDisplay); inputDisplay.name = 'display'
inputDisplay.value = '{{ if $graph }}graph{{ else }}list{{ end }}'
document.getElementById('form-time-selector').append(inputDisplay)
</script> </script>
{{ if $graph }} {{ if $graph }}

View File

@ -11,12 +11,19 @@
{{ block "page_label" . }}{{ end }} {{ block "page_label" . }}{{ end }}
<div style="margin-bottom: 16px"> <div style="margin-bottom: 16px">
<input {{ if eq .Data.Selection "CURRENT" }}checked{{ end }} type="radio" name="selection" id="selection-current" onclick="_ui.selectCurrent()"> <label for="selection-current">Current problems</label>
<input {{ if eq .Data.Selection "ALL" }}checked{{ end }} type="radio" name="selection" id="selection-all" onclick="_ui.selectAll()"> <label for="selection-all">Time-filtered problems</label>
</div>
<hr>
{{ block "timefilter" . }}{{ end }}
<div style="margin-top: 16px">
<input type="radio" name="display" id="display-table" onclick="_ui.displayAreas()"> <label for="display-table">Areas</label> <input type="radio" name="display" id="display-table" onclick="_ui.displayAreas()"> <label for="display-table">Areas</label>
<input type="radio" name="display" id="display-list" onclick="_ui.displayList()"> <label for="display-list">List</label> <input type="radio" name="display" id="display-list" onclick="_ui.displayList()"> <label for="display-list">List</label>
</div> </div>
{{ block "timefilter" . }}{{ end }}
<div class="display-list hidden"> <div class="display-list hidden">
<div id="problems-list"> <div id="problems-list">
<div style="grid-column: 1/-1;"><h2>Current</h2></div> <div style="grid-column: 1/-1;"><h2>Current</h2></div>
@ -79,6 +86,11 @@
<div class="section">{{ .SectionName }}</div> <div class="section">{{ .SectionName }}</div>
<div class="start">{{ format_time .Start }}</div> <div class="start">{{ format_time .Start }}</div>
<div class="acknowledge"> <div class="acknowledge">
{{ if .FormattedValues }}
<img class="info" src="/images/{{ $version }}/{{ $theme }}/info-filled.svg" title="{{ .FormattedValues }}">
{{ else }}
<img class="info" src="/images/{{ $version }}/{{ $theme }}/info-outline.svg">
{{ end }}
<a href="/problem/unacknowledge/{{ .ID }}"><img src="/images/{{ $version }}/{{ $theme }}/acknowledge-outline.svg"></a> <a href="/problem/unacknowledge/{{ .ID }}"><img src="/images/{{ $version }}/{{ $theme }}/acknowledge-outline.svg"></a>
</div> </div>
{{ end }} {{ end }}
@ -96,6 +108,7 @@
<div class="name">{{ $sectionName }}</div> <div class="name">{{ $sectionName }}</div>
{{ range $problems }} {{ range $problems }}
<div>{{ if .IsArchived }}<span class="ok">Archived</span>{{ else }}<span class="error">Current</span>{{ end }}</div>
<div class="trigger">{{ .TriggerName }}</div> <div class="trigger">{{ .TriggerName }}</div>
@ -119,4 +132,13 @@
</div> </div>
</div> </div>
<script type="text/javascript">
const form = document.getElementById('form-time-selector')
const inputSelection = document.createElement('input')
inputSelection.type = 'hidden'
inputSelection.name = 'selection'
inputSelection.value = '{{ if eq .Data.Selection "ALL" }}all{{ else }}current{{ end }}'
form.append(inputSelection)
</script>
{{ end }} {{ end }}