Compare commits
No commits in common. "4d7f0d557ed3e795e20cc12463bfbb0cf8687e69" and "332788dd20807538c8494b67d844061e6d198feb" have entirely different histories.
4d7f0d557e
...
332788dd20
12
main.go
12
main.go
@ -535,15 +535,7 @@ func pageProblems(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// GET parameters for this page
|
problems, err := ProblemsRetrieve(true, timeFrom, timeTo)
|
||||||
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
|
||||||
@ -568,9 +560,7 @@ 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"),
|
||||||
|
30
problem.go
30
problem.go
@ -26,7 +26,7 @@ type Problem struct { // {{{
|
|||||||
SectionName string `json:"section_name"`
|
SectionName string `json:"section_name"`
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
func ProblemsRetrieve(showCurrent bool, from, to time.Time) (problems []Problem, err error) { // {{{
|
func ProblemsRetrieve(archived 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
|
||||||
@ -39,23 +39,20 @@ func ProblemsRetrieve(showCurrent bool, from, to time.Time) (problems []Problem,
|
|||||||
p.acknowledged,
|
p.acknowledged,
|
||||||
p.datapoints,
|
p.datapoints,
|
||||||
t.id AS trigger_id,
|
t.id AS trigger_id,
|
||||||
p.trigger_name AS trigger_name,
|
t.name AS trigger_name,
|
||||||
a.name AS area_name,
|
a.name AS area_name,
|
||||||
s.name AS section_name
|
s.name AS section_name
|
||||||
FROM problem p
|
FROM problem p
|
||||||
LEFT JOIN "trigger" t ON p.trigger_id = t.id
|
INNER JOIN "trigger" t ON p.trigger_id = t.id
|
||||||
LEFT JOIN section s ON t.section_id = s.id
|
INNER JOIN section s ON t.section_id = s.id
|
||||||
LEFT JOIN area a ON s.area_id = a.id
|
INNER JOIN area a ON s.area_id = a.id
|
||||||
WHERE
|
WHERE
|
||||||
CASE
|
CASE
|
||||||
WHEN NOT $1 THEN p.end IS NULL
|
WHEN $1 THEN true
|
||||||
WHEN $1 THEN
|
WHEN NOT $1 THEN p.end IS NULL
|
||||||
p.start >= $2 AND
|
END AND
|
||||||
(
|
p.start >= $2 AND
|
||||||
p.end IS NULL OR
|
p.end <= $3
|
||||||
p.end <= $3
|
|
||||||
)
|
|
||||||
END
|
|
||||||
|
|
||||||
ORDER BY
|
ORDER BY
|
||||||
p.start DESC)
|
p.start DESC)
|
||||||
@ -64,7 +61,7 @@ func ProblemsRetrieve(showCurrent bool, from, to time.Time) (problems []Problem,
|
|||||||
|
|
||||||
(SELECT
|
(SELECT
|
||||||
-1 AS id,
|
-1 AS id,
|
||||||
dp.last_value,
|
null,
|
||||||
null,
|
null,
|
||||||
false,
|
false,
|
||||||
'{}',
|
'{}',
|
||||||
@ -81,7 +78,7 @@ func ProblemsRetrieve(showCurrent bool, from, to time.Time) (problems []Problem,
|
|||||||
ORDER BY
|
ORDER BY
|
||||||
dp.name ASC)
|
dp.name ASC)
|
||||||
) AS problems`,
|
) AS problems`,
|
||||||
showCurrent,
|
archived,
|
||||||
from,
|
from,
|
||||||
to,
|
to,
|
||||||
)
|
)
|
||||||
@ -125,9 +122,8 @@ func ProblemStart(trigger Trigger) (problemID int, err error) { // {{{
|
|||||||
if openProblems == 0 {
|
if openProblems == 0 {
|
||||||
datapointValuesJson, _ := json.Marshal(trigger.DatapointValues)
|
datapointValuesJson, _ := json.Marshal(trigger.DatapointValues)
|
||||||
row = service.Db.Conn.QueryRow(
|
row = service.Db.Conn.QueryRow(
|
||||||
`INSERT INTO problem(trigger_id, trigger_name, datapoints, trigger_expression) VALUES($1, $2, $3, $4) RETURNING id`,
|
`INSERT INTO problem(trigger_id, datapoints, trigger_expression) VALUES($1, $2, $3) RETURNING id`,
|
||||||
trigger.ID,
|
trigger.ID,
|
||||||
trigger.Name,
|
|
||||||
datapointValuesJson,
|
datapointValuesJson,
|
||||||
trigger.Expression,
|
trigger.Expression,
|
||||||
)
|
)
|
||||||
|
@ -13,12 +13,3 @@ 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;
|
|
||||||
}
|
|
||||||
|
@ -213,12 +213,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -239,9 +233,6 @@ 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;
|
||||||
|
@ -21,3 +21,9 @@ input[type="datetime-local"] {
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #7bb8eb;
|
color: #7bb8eb;
|
||||||
}
|
}
|
||||||
|
#notifications .ok {
|
||||||
|
color: #0a0;
|
||||||
|
}
|
||||||
|
#notifications .error {
|
||||||
|
color: #a00;
|
||||||
|
}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
}
|
}
|
||||||
#areas .area .section {
|
#areas .area .section {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, min-content);
|
grid-template-columns: repeat(3, min-content);
|
||||||
grid-gap: 8px 12px;
|
grid-gap: 8px 12px;
|
||||||
}
|
}
|
||||||
#areas .area .section .name {
|
#areas .area .section .name {
|
||||||
|
@ -13,12 +13,3 @@ 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;
|
|
||||||
}
|
|
||||||
|
@ -213,12 +213,6 @@ 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;
|
||||||
}
|
}
|
||||||
@ -239,9 +233,6 @@ 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;
|
||||||
|
@ -21,3 +21,9 @@ input[type="datetime-local"] {
|
|||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
color: #777;
|
color: #777;
|
||||||
}
|
}
|
||||||
|
#notifications .ok {
|
||||||
|
color: #0a0;
|
||||||
|
}
|
||||||
|
#notifications .error {
|
||||||
|
color: #a00;
|
||||||
|
}
|
||||||
|
@ -45,7 +45,7 @@
|
|||||||
}
|
}
|
||||||
#areas .area .section {
|
#areas .area .section {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, min-content);
|
grid-template-columns: repeat(3, min-content);
|
||||||
grid-gap: 8px 12px;
|
grid-gap: 8px 12px;
|
||||||
}
|
}
|
||||||
#areas .area .section .name {
|
#areas .area .section .name {
|
||||||
|
@ -34,14 +34,6 @@ 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')
|
||||||
|
@ -20,14 +20,3 @@ 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;
|
|
||||||
}
|
|
||||||
|
@ -266,14 +266,6 @@ span.seconds {
|
|||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
span.ok {
|
|
||||||
color: #0a0;
|
|
||||||
}
|
|
||||||
|
|
||||||
span.error {
|
|
||||||
color: #a00;
|
|
||||||
}
|
|
||||||
|
|
||||||
label {
|
label {
|
||||||
user-select: none;
|
user-select: none;
|
||||||
}
|
}
|
||||||
@ -297,10 +289,6 @@ 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;
|
||||||
|
@ -25,4 +25,12 @@ input[type="datetime-local"] {
|
|||||||
font-weight: @bold;
|
font-weight: @bold;
|
||||||
color: @text3;
|
color: @text3;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.ok {
|
||||||
|
color: #0a0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.error {
|
||||||
|
color: #a00;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -51,7 +51,7 @@
|
|||||||
.area {
|
.area {
|
||||||
.section {
|
.section {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, min-content);
|
grid-template-columns: repeat(3, min-content);
|
||||||
grid-gap: 8px 12px;
|
grid-gap: 8px 12px;
|
||||||
|
|
||||||
.name {
|
.name {
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|
||||||
<form action="{{ .Data.TimeSubmit }}" method="get" id="form-time-selector" class="{{ if .Data.TimeHidden }}hidden{{ end }}">
|
<form action="{{ .Data.TimeSubmit }}" method="get" id="form-time-selector">
|
||||||
<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>
|
||||||
|
|
||||||
|
@ -7,22 +7,19 @@
|
|||||||
|
|
||||||
{{ block "page_label" . }}{{end}}
|
{{ block "page_label" . }}{{end}}
|
||||||
|
|
||||||
{{ block "timefilter" . }}{{ end }}
|
<div style="margin-bottom: 16px">
|
||||||
|
|
||||||
{{ 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.type = 'hidden'
|
|
||||||
inputDisplay.name = 'display'
|
inputDisplay.name = 'display'
|
||||||
inputDisplay.value = '{{ if $graph }}graph{{ else }}list{{ end }}'
|
inputDisplay.type = 'hidden'
|
||||||
document.getElementById('form-time-selector').append(inputDisplay)
|
document.getElementById('form-time-selector').append(inputDisplay);
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ if $graph }}
|
{{ if $graph }}
|
||||||
|
@ -11,22 +11,15 @@
|
|||||||
{{ 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>Unacknowledged</h2></div>
|
<div style="grid-column: 1/-1;"><h2>Current</h2></div>
|
||||||
|
|
||||||
<div class="header">Trigger</div>
|
<div class="header">Trigger</div>
|
||||||
<div class="header">Area</div>
|
<div class="header">Area</div>
|
||||||
@ -86,11 +79,6 @@
|
|||||||
<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 }}
|
||||||
@ -108,7 +96,6 @@
|
|||||||
<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>
|
||||||
|
|
||||||
@ -132,13 +119,4 @@
|
|||||||
</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 }}
|
||||||
|
Loading…
Reference in New Issue
Block a user