Added timefilter to problems

This commit is contained in:
Magnus Åhall 2024-07-04 13:37:06 +02:00
parent 9700bc9d3c
commit f7dcb4a079
4 changed files with 62 additions and 62 deletions

20
main.go
View File

@ -521,7 +521,21 @@ func pageProblems(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
CONFIG: smonConfig.Settings, CONFIG: smonConfig.Settings,
} }
problems, err := ProblemsRetrieve() // Manage the values from the timefilter component
var err error
var timeFrom, timeTo time.Time
timeFrom, timeTo, err = timefilterParse(
r.URL.Query().Get("time-f"),
r.URL.Query().Get("time-t"),
r.URL.Query().Get("time-offset"),
r.URL.Query().Get("time-preset"),
)
if err != nil {
httpError(w, err)
return
}
problems, err := ProblemsRetrieve(true, timeFrom, timeTo)
if err != nil { if err != nil {
httpError(w, werr.Wrap(err).Log()) httpError(w, werr.Wrap(err).Log())
return return
@ -546,6 +560,10 @@ 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,
"TimeSubmit": "/problems",
"TimeFrom": timeFrom.Format("2006-01-02T15:04:05"),
"TimeTo": timeTo.Format("2006-01-02T15:04:05"),
} }
page.Render(w, r) page.Render(w, r)
return return

View File

@ -16,7 +16,7 @@ import (
type Problem struct { // {{{ type Problem struct { // {{{
ID int ID int
Start time.Time Start time.Time
End sql.NullTime End time.Time
Acknowledged bool Acknowledged bool
Datapoints map[string]any Datapoints map[string]any
DatapointValues map[string]any `json:"datapoints"` DatapointValues map[string]any `json:"datapoints"`
@ -26,7 +26,7 @@ type Problem struct { // {{{
SectionName string `json:"section_name"` SectionName string `json:"section_name"`
} // }}} } // }}}
func ProblemsRetrieve() (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
@ -35,7 +35,7 @@ func ProblemsRetrieve() (problems []Problem, err error) { // {{{
(SELECT (SELECT
p.id, p.id,
p.start, p.start,
p.end, TO_CHAR(p.end, 'YYYY-MM-DD"T"HH24:MI:SSTZH:TZM') AS end,
p.acknowledged, p.acknowledged,
p.datapoints, p.datapoints,
t.id AS trigger_id, t.id AS trigger_id,
@ -47,12 +47,18 @@ func ProblemsRetrieve() (problems []Problem, err error) { // {{{
INNER JOIN section s ON t.section_id = s.id INNER JOIN section s ON t.section_id = s.id
INNER JOIN area a ON s.area_id = a.id INNER JOIN area a ON s.area_id = a.id
WHERE WHERE
p.end IS NULL CASE
WHEN $1 THEN true
WHEN NOT $1 THEN p.end IS NULL
END AND
p.start >= $2 AND
p.end <= $3
ORDER BY ORDER BY
p.start DESC) p.start DESC)
UNION ALL UNION ALL
(SELECT (SELECT
-1 AS id, -1 AS id,
null, null,
@ -71,8 +77,11 @@ func ProblemsRetrieve() (problems []Problem, err error) { // {{{
dp.nodata_is_problem dp.nodata_is_problem
ORDER BY ORDER BY
dp.name ASC) dp.name ASC)
) AS problems ) AS problems`,
`) archived,
from,
to,
)
var jsonBody []byte var jsonBody []byte
err = row.Scan(&jsonBody) err = row.Scan(&jsonBody)
@ -112,7 +121,12 @@ func ProblemStart(trigger Trigger) (problemID int, err error) { // {{{
// Open up a new problem if no open exists. // Open up a new problem if no open exists.
if openProblems == 0 { if openProblems == 0 {
datapointValuesJson, _ := json.Marshal(trigger.DatapointValues) datapointValuesJson, _ := json.Marshal(trigger.DatapointValues)
row = service.Db.Conn.QueryRow(`INSERT INTO problem(trigger_id, datapoints) VALUES($1, $2) RETURNING id`, trigger.ID, datapointValuesJson) row = service.Db.Conn.QueryRow(
`INSERT INTO problem(trigger_id, datapoints, trigger_expression) VALUES($1, $2, $3) RETURNING id`,
trigger.ID,
datapointValuesJson,
trigger.Expression,
)
err = row.Scan(&problemID) err = row.Scan(&problemID)
if err != nil { if err != nil {
err = werr.Wrap(err).WithData(trigger) err = werr.Wrap(err).WithData(trigger)
@ -144,7 +158,7 @@ func ProblemAcknowledge(id int, state bool) (err error) { // {{{
return return
} // }}} } // }}}
func (p Problem) FormattedValues() string {// {{{ func (p Problem) FormattedValues() string { // {{{
out := []string{} out := []string{}
for key, val := range p.DatapointValues { for key, val := range p.DatapointValues {
var keyval string var keyval string
@ -174,4 +188,7 @@ func (p Problem) FormattedValues() string {// {{{
sort.Strings(out) sort.Strings(out)
return strings.Join(out, "\n") return strings.Join(out, "\n")
}// }}} } // }}}
func (p Problem) IsArchived() bool { // {{{
return !p.End.IsZero()
} // }}}

View File

@ -7,56 +7,20 @@
{{ block "page_label" . }}{{end}} {{ block "page_label" . }}{{end}}
<form action="/datapoint/values/{{ .Data.Datapoint.ID }}" method="get" style="margin-top: -16px"> <div style="margin-bottom: 16px">
<input type="hidden" name="preset" value=""> <input onchange="selectDisplay('graph')" name="display" type="radio" id="display-graph" {{ if $graph }} checked {{ end}}> <label for="display-graph">Graph</label>
<input type="hidden" name="offset-time" value=0> <input onchange="selectDisplay('list')" name="display" type="radio" id="display-list" {{ if not $graph }} checked {{ end }}> <label for="display-list">List</label>
</div>
{{ if eq .Data.Datapoint.Datatype "INT" }} {{ block "timefilter" . }}{{ end }}
<div>
<input name="display" value="graph" type="radio" id="display-graph" {{ if $graph }} checked {{ end}}> <label for="display-graph">Graph</label>
<input name="display" value="list" type="radio" id="display-list" {{ if not $graph }} checked {{ end }}> <label for="display-list">List</label>
</div>
{{ end }}
<div class="value-selector"> <script type="text/javascript">
<div>Values from</div> const inputDisplay = document.createElement('input')
<div>Values to</div> inputDisplay.id = 'input-display'
inputDisplay.name = 'display'
<input name="f" type="datetime-local" step="1" value="{{ .Data.TimeFrom }}"> inputDisplay.type = 'hidden'
<input name="t" type="datetime-local" step="1" value="{{ .Data.TimeTo }}"> document.getElementById('form-time-selector').append(inputDisplay);
</script>
<div class="time-offset">
<div class="header-1">Presets</div>
<div class="header-2">Offsets</div>
<div class="preset"><a href="#" onclick="preset(1)">Last hour</a></div>
<div><a href="#" onclick="offsetTime(-3600)">◀</a></div>
<div>Hour</div>
<div><a href="#" onclick="offsetTime(3600)">▶</a></div>
<div class="preset"><a href="#" onclick="preset(24)">Last 24 hours</a></div>
<div><a href="#" onclick="offsetTime(-86400)">◀</a></div>
<div>Day</div>
<div><a href="#" onclick="offsetTime(86400)">▶</a></div>
<div class="preset"><a href="#" onclick="preset(24 * 7)">Last 7 days</a></div>
<div><a href="#" onclick="offsetTime(-7 * 86400)">◀</a></div>
<div>Week</div>
<div><a href="#" onclick="offsetTime(7 * 86400)">▶</a></div>
<div class="preset"><a href="#" onclick="preset(24 * 31)">Last 31 days</a></div>
<div><a href="#" onclick="offsetTime(-31 * 86400)">◀</a></div>
<div>Month</div>
<div><a href="#" onclick="offsetTime(31 * 86400)">▶</a></div>
</div>
<button>OK</button>
</div>
</form>
{{ if $graph }} {{ if $graph }}
<div class="graph"> <div class="graph">
@ -72,7 +36,6 @@
{{ .Data.Datapoint.ID }}, {{ .Data.Datapoint.ID }},
{{ .Data.Values }}, {{ .Data.Values }},
) )
</script> </script>
{{ else }} {{ else }}
<div id="values"> <div id="values">

View File

@ -8,13 +8,15 @@
</script> </script>
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/{{ .CONFIG.THEME }}/problems.css"> <link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/{{ .CONFIG.THEME }}/problems.css">
{{ block "page_label" . }}{{end}} {{ block "page_label" . }}{{ end }}
<div> <div style="margin-bottom: 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>