Managing of problems
This commit is contained in:
parent
c746343dc0
commit
d935eb282b
62
main.go
62
main.go
@ -95,14 +95,11 @@ func main() { // {{{
|
|||||||
logger.Error("application", "error", err)
|
logger.Error("application", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
_, err = service.Db.Conn.Exec(`SET TIMEZONE TO 'Europe/Stockholm'`)
|
|
||||||
if err != nil {
|
|
||||||
logger.Error("application", "error", err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
service.Register("/", false, false, staticHandler)
|
service.Register("/", false, false, staticHandler)
|
||||||
service.Register("/problems", false, false, pageProblems)
|
service.Register("/problems", false, false, pageProblems)
|
||||||
|
service.Register("/problem/acknowledge/{id}", false, false, pageProblemAcknowledge)
|
||||||
|
service.Register("/problem/unacknowledge/{id}", false, false, pageProblemUnacknowledge)
|
||||||
|
|
||||||
service.Register("/datapoints", false, false, pageDatapoints)
|
service.Register("/datapoints", false, false, pageDatapoints)
|
||||||
service.Register("/datapoint/edit/{id}", false, false, pageDatapointEdit)
|
service.Register("/datapoint/edit/{id}", false, false, pageDatapointEdit)
|
||||||
@ -247,8 +244,10 @@ func getPage(layout, page string) (tmpl *template.Template, err error) { // {{{
|
|||||||
}
|
}
|
||||||
|
|
||||||
funcMap := template.FuncMap{
|
funcMap := template.FuncMap{
|
||||||
"format_time": func(t time.Time) string {
|
"format_time": func(t time.Time) template.HTML {
|
||||||
return t.Local().Format("2006-01-02 15:04:05")
|
return template.HTML(
|
||||||
|
t.Local().Format(`<span class="date">2006-01-02</span> <span class="time">15:04<span class="seconds">:05</span></span>`),
|
||||||
|
)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,25 +282,56 @@ func pageProblems(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
|||||||
PAGE: "problems",
|
PAGE: "problems",
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
problems, err := ProblemsRetrieve()
|
||||||
areas, err := ProblemsRetrieve()
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, we.Wrap(err).Log())
|
httpError(w, we.Wrap(err).Log())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
sort.SliceStable(areas, func(i, j int) bool {
|
|
||||||
return areas[i].Name < areas[j].Name
|
|
||||||
})
|
|
||||||
|
|
||||||
logger.Info("problems", "areas", areas)
|
|
||||||
*/
|
|
||||||
|
|
||||||
page.Data = map[string]any{
|
page.Data = map[string]any{
|
||||||
//"Areas": areas,
|
"Problems": problems,
|
||||||
}
|
}
|
||||||
page.Render(w)
|
page.Render(w)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
|
func pageProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
|
idStr := r.PathValue("id")
|
||||||
|
id, err := strconv.Atoi(idStr)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, we.Wrap(err).Log())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ProblemAcknowledge(id, true)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, we.Wrap(err).Log())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Location", "/problems")
|
||||||
|
w.WriteHeader(302)
|
||||||
|
|
||||||
|
return
|
||||||
|
} // }}}
|
||||||
|
func pageProblemUnacknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
|
idStr := r.PathValue("id")
|
||||||
|
id, err := strconv.Atoi(idStr)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, we.Wrap(err).Log())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = ProblemAcknowledge(id, false)
|
||||||
|
if err != nil {
|
||||||
|
httpError(w, we.Wrap(err).Log())
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
w.Header().Add("Location", "/problems")
|
||||||
|
w.WriteHeader(302)
|
||||||
|
|
||||||
|
return
|
||||||
|
} // }}}
|
||||||
|
|
||||||
func pageDatapoints(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageDatapoints(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
page := Page{
|
page := Page{
|
||||||
|
65
problem.go
65
problem.go
@ -6,17 +6,61 @@ import (
|
|||||||
|
|
||||||
// Standard
|
// Standard
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"encoding/json"
|
||||||
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
/*
|
|
||||||
type Problem struct {
|
type Problem struct {
|
||||||
ID int
|
ID int
|
||||||
Name string
|
Start time.Time
|
||||||
SectionID int
|
End sql.NullTime
|
||||||
Expression string
|
Acknowledged bool
|
||||||
DatapointNames []string
|
TriggerID int `json:"trigger_id"`
|
||||||
|
TriggerName string `json:"trigger_name"`
|
||||||
|
AreaName string `json:"area_name"`
|
||||||
|
SectionName string `json:"section_name"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func ProblemsRetrieve() (problems []Problem, err error) {
|
||||||
|
problems = []Problem{}
|
||||||
|
row := service.Db.Conn.QueryRow(`
|
||||||
|
SELECT
|
||||||
|
jsonb_agg(p.*)
|
||||||
|
FROM (
|
||||||
|
SELECT
|
||||||
|
p.id,
|
||||||
|
p.start,
|
||||||
|
p.end,
|
||||||
|
p.acknowledged,
|
||||||
|
t.id AS trigger_id,
|
||||||
|
t.name AS trigger_name,
|
||||||
|
a.name AS area_name,
|
||||||
|
s.name AS section_name
|
||||||
|
FROM problem p
|
||||||
|
INNER JOIN "trigger" t ON p.trigger_id = t.id
|
||||||
|
INNER JOIN section s ON t.section_id = s.id
|
||||||
|
INNER JOIN area a ON s.area_id = a.id
|
||||||
|
|
||||||
|
WHERE
|
||||||
|
p.end IS NULL
|
||||||
|
|
||||||
|
ORDER BY p.start DESC
|
||||||
|
) p
|
||||||
|
`)
|
||||||
|
|
||||||
|
var jsonBody []byte
|
||||||
|
err = row.Scan(&jsonBody)
|
||||||
|
if err != nil {
|
||||||
|
err = we.Wrap(err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
err = json.Unmarshal(jsonBody, &problems)
|
||||||
|
if err != nil {
|
||||||
|
err = we.Wrap(err)
|
||||||
|
}
|
||||||
|
return
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
|
|
||||||
func ProblemStart(trigger Trigger) (err error) {
|
func ProblemStart(trigger Trigger) (err error) {
|
||||||
row := service.Db.Conn.QueryRow(`
|
row := service.Db.Conn.QueryRow(`
|
||||||
@ -54,3 +98,12 @@ func ProblemClose(trigger Trigger) (err error) {
|
|||||||
}
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func ProblemAcknowledge(id int, state bool) (err error) {
|
||||||
|
_, err = service.Db.Conn.Exec(`UPDATE problem SET "acknowledged"=$2 WHERE id=$1`, id, state)
|
||||||
|
if err != nil {
|
||||||
|
err = we.Wrap(err).WithData(id)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
return
|
||||||
|
}
|
||||||
|
@ -77,6 +77,24 @@ button {
|
|||||||
button:focus {
|
button:focus {
|
||||||
background: #333;
|
background: #333;
|
||||||
}
|
}
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid #4e4e4e;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #d5c4a1;
|
||||||
|
}
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
#datapoints {
|
#datapoints {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(4, min-content);
|
grid-template-columns: repeat(4, min-content);
|
||||||
@ -102,10 +120,10 @@ button:focus {
|
|||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
.widgets .datapoints {
|
.widgets .datapoints {
|
||||||
font: "Roboto Mono", monospace;
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: min-content 1fr;
|
grid-template-columns: min-content 1fr;
|
||||||
gap: 6px 8px;
|
gap: 6px 8px;
|
||||||
|
font-family: "Roboto Mono", monospace;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
.widgets .action {
|
.widgets .action {
|
||||||
|
@ -77,6 +77,24 @@ button {
|
|||||||
button:focus {
|
button:focus {
|
||||||
background: #333;
|
background: #333;
|
||||||
}
|
}
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid #4e4e4e;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #d5c4a1;
|
||||||
|
}
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
#layout {
|
#layout {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-areas: "menu content";
|
grid-template-areas: "menu content";
|
||||||
|
124
static/css/problems.css
Normal file
124
static/css/problems.css
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
html {
|
||||||
|
box-sizing: border-box;
|
||||||
|
}
|
||||||
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
|
box-sizing: inherit;
|
||||||
|
}
|
||||||
|
*:focus {
|
||||||
|
outline: none;
|
||||||
|
}
|
||||||
|
[onClick] {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
html,
|
||||||
|
body {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
body {
|
||||||
|
background: #282828;
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-size: 11pt;
|
||||||
|
}
|
||||||
|
h1,
|
||||||
|
h2 {
|
||||||
|
margin-top: 0px;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
h1 {
|
||||||
|
font-size: 1.5em;
|
||||||
|
color: #fb4934;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
font-size: 1.25em;
|
||||||
|
}
|
||||||
|
a {
|
||||||
|
color: #fabd2f;
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
b {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
.roboto-light {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-weight: 300;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
.roboto-medium {
|
||||||
|
font-family: "Roboto", sans-serif;
|
||||||
|
font-weight: 500;
|
||||||
|
font-style: normal;
|
||||||
|
}
|
||||||
|
input[type="text"],
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
|
font-family: "Roboto Mono", monospace;
|
||||||
|
background: #202020;
|
||||||
|
color: #d5c4a1;
|
||||||
|
padding: 4px 8px;
|
||||||
|
border: none;
|
||||||
|
font-size: 1em;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
background: #202020;
|
||||||
|
color: #d5c4a1;
|
||||||
|
padding: 8px 32px;
|
||||||
|
border: 1px solid #535353;
|
||||||
|
font-size: 1em;
|
||||||
|
height: 3em;
|
||||||
|
}
|
||||||
|
button:focus {
|
||||||
|
background: #333;
|
||||||
|
}
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid #4e4e4e;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #d5c4a1;
|
||||||
|
}
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
#problems-list,
|
||||||
|
#acknowledged-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, min-content);
|
||||||
|
grid-gap: 4px 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
}
|
||||||
|
#problems-list div,
|
||||||
|
#acknowledged-list div {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#problems-list .header,
|
||||||
|
#acknowledged-list .header {
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
#problems-list .trigger,
|
||||||
|
#acknowledged-list .trigger {
|
||||||
|
color: #fb4934;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
#problems-list .acknowledge img,
|
||||||
|
#acknowledged-list .acknowledge img {
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
#acknowledged-list.hidden {
|
||||||
|
display: none;
|
||||||
|
}
|
@ -77,3 +77,21 @@ button {
|
|||||||
button:focus {
|
button:focus {
|
||||||
background: #333;
|
background: #333;
|
||||||
}
|
}
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid #4e4e4e;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #d5c4a1;
|
||||||
|
}
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
@ -77,6 +77,24 @@ button {
|
|||||||
button:focus {
|
button:focus {
|
||||||
background: #333;
|
background: #333;
|
||||||
}
|
}
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid #4e4e4e;
|
||||||
|
}
|
||||||
|
span.date {
|
||||||
|
color: #d5c4a1;
|
||||||
|
font-weight: 500;
|
||||||
|
}
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: #d5c4a1;
|
||||||
|
}
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
.widgets {
|
.widgets {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: min-content 1fr;
|
grid-template-columns: min-content 1fr;
|
||||||
|
67
static/images/acknowledge-filled.svg
Normal file
67
static/images/acknowledge-filled.svg
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="31.999987"
|
||||||
|
height="29.090721"
|
||||||
|
viewBox="0 0 8.4666629 7.6969202"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||||
|
sodipodi:docname="acknowledge-filled.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="11.5"
|
||||||
|
inkscape:cy="10"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="2190"
|
||||||
|
inkscape:window-height="1404"
|
||||||
|
inkscape:window-x="1463"
|
||||||
|
inkscape:window-y="16"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:showpageshadow="true"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d6d6d6"
|
||||||
|
showborder="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-89.958296,-148.43122)">
|
||||||
|
<title
|
||||||
|
id="title1">thumb-up</title>
|
||||||
|
<path
|
||||||
|
d="m 98.424959,151.89488 c 0,-0.42719 -0.346361,-0.7697 -0.769692,-0.7697 h -2.432224 l 0.369452,-1.75874 c 0.0077,-0.0385 0.01149,-0.0809 0.01149,-0.1232 0,-0.15778 -0.06542,-0.30402 -0.169332,-0.40794 l -0.407941,-0.40408 -2.532284,2.53229 c -0.142399,0.1424 -0.227059,0.33482 -0.227059,0.54648 v 3.84845 a 0.76969147,0.76969147 0 0 0 0.769691,0.7697 h 3.463611 c 0.319422,0 0.592664,-0.19242 0.708117,-0.46951 l 1.162234,-2.71317 c 0.03463,-0.0884 0.05388,-0.18087 0.05388,-0.28093 v -0.7697 m -8.466606,4.23331 h 1.539382 v -4.61815 h -1.539382 z"
|
||||||
|
id="path1"
|
||||||
|
style="stroke-width:0.384845;fill:#fb4934;fill-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.4 KiB |
69
static/images/acknowledge-outline.svg
Normal file
69
static/images/acknowledge-outline.svg
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||||
|
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||||
|
|
||||||
|
<svg
|
||||||
|
width="31.999987"
|
||||||
|
height="29.090721"
|
||||||
|
viewBox="0 0 8.4666629 7.6969202"
|
||||||
|
version="1.1"
|
||||||
|
id="svg8"
|
||||||
|
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
||||||
|
sodipodi:docname="acknowledge-outline.svg"
|
||||||
|
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||||
|
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:svg="http://www.w3.org/2000/svg"
|
||||||
|
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||||
|
xmlns:cc="http://creativecommons.org/ns#"
|
||||||
|
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||||
|
<defs
|
||||||
|
id="defs2" />
|
||||||
|
<sodipodi:namedview
|
||||||
|
id="base"
|
||||||
|
pagecolor="#ffffff"
|
||||||
|
bordercolor="#666666"
|
||||||
|
borderopacity="1.0"
|
||||||
|
inkscape:pageopacity="0.0"
|
||||||
|
inkscape:pageshadow="2"
|
||||||
|
inkscape:zoom="1"
|
||||||
|
inkscape:cx="11.5"
|
||||||
|
inkscape:cy="10"
|
||||||
|
inkscape:document-units="px"
|
||||||
|
inkscape:current-layer="layer1"
|
||||||
|
showgrid="false"
|
||||||
|
units="px"
|
||||||
|
inkscape:window-width="2190"
|
||||||
|
inkscape:window-height="1404"
|
||||||
|
inkscape:window-x="1463"
|
||||||
|
inkscape:window-y="16"
|
||||||
|
inkscape:window-maximized="0"
|
||||||
|
inkscape:showpageshadow="true"
|
||||||
|
inkscape:pagecheckerboard="0"
|
||||||
|
inkscape:deskcolor="#d6d6d6"
|
||||||
|
showborder="true" />
|
||||||
|
<metadata
|
||||||
|
id="metadata5">
|
||||||
|
<rdf:RDF>
|
||||||
|
<cc:Work
|
||||||
|
rdf:about="">
|
||||||
|
<dc:format>image/svg+xml</dc:format>
|
||||||
|
<dc:type
|
||||||
|
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||||
|
</cc:Work>
|
||||||
|
</rdf:RDF>
|
||||||
|
</metadata>
|
||||||
|
<g
|
||||||
|
inkscape:label="Layer 1"
|
||||||
|
inkscape:groupmode="layer"
|
||||||
|
id="layer1"
|
||||||
|
transform="translate(-89.958296,-148.43122)">
|
||||||
|
<title
|
||||||
|
id="title1">thumb-up</title>
|
||||||
|
<title
|
||||||
|
id="title1-3">thumb-up-outline</title>
|
||||||
|
<path
|
||||||
|
d="m 91.497681,151.50999 v 4.61815 h -1.539385 v -4.61815 h 1.539385 m 1.539383,4.61815 a 0.76969186,0.76969186 0 0 1 -0.769692,-0.76969 v -3.84846 c 0,-0.21166 0.08467,-0.40408 0.22706,-0.54263 l 2.532286,-2.53614 0.407936,0.40794 c 0.103912,0.10385 0.169333,0.24631 0.169333,0.40408 l -0.01149,0.1232 -0.365604,1.75875 h 2.428378 c 0.42718,0 0.769693,0.34636 0.769693,0.76969 v 0.76969 c 0,0.10008 -0.01924,0.19242 -0.05388,0.28095 l -1.162236,2.71316 c -0.115446,0.27709 -0.388694,0.46951 -0.708116,0.46951 h -3.463613 m 0,-0.7697 h 3.47516 l 1.142991,-2.69392 v -0.76969 h -3.382795 l 0.434876,-2.04738 -1.670232,1.67408 z"
|
||||||
|
id="path1"
|
||||||
|
style="stroke-width:0.384845;fill:#fb4934;fill-opacity:1" />
|
||||||
|
</g>
|
||||||
|
</svg>
|
After Width: | Height: | Size: 2.6 KiB |
23
static/js/problems.mjs
Normal file
23
static/js/problems.mjs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
export class UI {
|
||||||
|
constructor() {
|
||||||
|
const showAcked = localStorage.getItem('show_acknowledged')
|
||||||
|
if (showAcked == 'true') {
|
||||||
|
document.getElementById('show-acked').checked = true
|
||||||
|
const list = document.getElementById('acknowledged-list')
|
||||||
|
list.classList.remove('hidden')
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
toggleAcknowledged(evt) {
|
||||||
|
const list = document.getElementById('acknowledged-list')
|
||||||
|
|
||||||
|
if (evt.target.checked) {
|
||||||
|
list.classList.remove('hidden')
|
||||||
|
localStorage.setItem('show_acknowledged', true)
|
||||||
|
} else {
|
||||||
|
list.classList.add('hidden')
|
||||||
|
localStorage.setItem('show_acknowledged', false)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -29,10 +29,10 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.datapoints {
|
.datapoints {
|
||||||
font: "Roboto Mono", monospace;
|
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: min-content 1fr;
|
grid-template-columns: min-content 1fr;
|
||||||
gap: 6px 8px;
|
gap: 6px 8px;
|
||||||
|
font-family: "Roboto Mono", monospace;
|
||||||
margin-bottom: 8px;
|
margin-bottom: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
31
static/less/problems.less
Normal file
31
static/less/problems.less
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
@import "theme.less";
|
||||||
|
|
||||||
|
#problems-list, #acknowledged-list {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(5, min-content);
|
||||||
|
grid-gap: 4px 16px;
|
||||||
|
margin-bottom: 32px;
|
||||||
|
|
||||||
|
div {
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
|
||||||
|
.header {
|
||||||
|
font-weight: @bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.trigger {
|
||||||
|
color: @color1;
|
||||||
|
font-weight: @bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
.acknowledge {
|
||||||
|
img {
|
||||||
|
height: 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#acknowledged-list.hidden{
|
||||||
|
display: none;
|
||||||
|
}
|
@ -14,11 +14,17 @@
|
|||||||
|
|
||||||
@bold: 500;
|
@bold: 500;
|
||||||
|
|
||||||
|
.lighterOrDarker(@color, @amount) {
|
||||||
|
@result: lighten(@color, @amount);
|
||||||
|
}
|
||||||
|
|
||||||
html {
|
html {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
}
|
}
|
||||||
|
|
||||||
*, *:before, *:after {
|
*,
|
||||||
|
*:before,
|
||||||
|
*:after {
|
||||||
box-sizing: inherit;
|
box-sizing: inherit;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -44,7 +50,8 @@ body {
|
|||||||
font-size: 11pt;
|
font-size: 11pt;
|
||||||
}
|
}
|
||||||
|
|
||||||
h1, h2 {
|
h1,
|
||||||
|
h2 {
|
||||||
margin-top: 0px;
|
margin-top: 0px;
|
||||||
margin-bottom: 4px;
|
margin-bottom: 4px;
|
||||||
}
|
}
|
||||||
@ -83,7 +90,9 @@ b {
|
|||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
input[type="text"], textarea, select {
|
input[type="text"],
|
||||||
|
textarea,
|
||||||
|
select {
|
||||||
font-family: "Roboto Mono", monospace;
|
font-family: "Roboto Mono", monospace;
|
||||||
background: @bg2;
|
background: @bg2;
|
||||||
color: @text1;
|
color: @text1;
|
||||||
@ -104,3 +113,26 @@ button {
|
|||||||
background: @bg3;
|
background: @bg3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.line {
|
||||||
|
grid-column: 1 / -1;
|
||||||
|
border-bottom: 1px solid .lighterOrDarker(@bg1, 15%)[@result];
|
||||||
|
}
|
||||||
|
|
||||||
|
span.date {
|
||||||
|
color: @text1;
|
||||||
|
font-weight: @bold;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.time {
|
||||||
|
font-size: 0.9em;
|
||||||
|
color: @text1;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.seconds {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
label {
|
||||||
|
user-select: none;
|
||||||
|
}
|
||||||
|
@ -12,6 +12,7 @@
|
|||||||
<div class="header">Value</div>
|
<div class="header">Value</div>
|
||||||
|
|
||||||
{{ range .Data.Datapoints }}
|
{{ range .Data.Datapoints }}
|
||||||
|
<div class="line"></div>
|
||||||
<div class="name"><a href="/datapoint/edit/{{ .ID }}">{{ .Name }}</a></div>
|
<div class="name"><a href="/datapoint/edit/{{ .ID }}">{{ .Name }}</a></div>
|
||||||
<div class="datatype">{{ .Datatype }}</div>
|
<div class="datatype">{{ .Datatype }}</div>
|
||||||
<div class="last-value">{{ format_time .LastValue }}</div>
|
<div class="last-value">{{ format_time .LastValue }}</div>
|
||||||
|
@ -1,6 +1,56 @@
|
|||||||
{{ define "page" }}
|
{{ define "page" }}
|
||||||
|
{{ $version := .VERSION }}
|
||||||
|
<script type="module" defer>
|
||||||
|
import {UI} from "/js/{{ .VERSION }}/problems.mjs"
|
||||||
|
|
||||||
|
window._ui = new UI()
|
||||||
|
</script>
|
||||||
|
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/problems.css">
|
||||||
|
|
||||||
{{ block "page_label" . }}{{end}}
|
{{ block "page_label" . }}{{end}}
|
||||||
|
|
||||||
|
<div id="problems-list">
|
||||||
|
<div style="grid-column: 1/-1; margin-top: 32px;"><h2>Current</h2></div>
|
||||||
|
|
||||||
|
<div class="header">Trigger</div>
|
||||||
|
<div class="header">Area</div>
|
||||||
|
<div class="header">Section</div>
|
||||||
|
<div class="header">Since</div>
|
||||||
|
{{ range .Data.Problems }}
|
||||||
|
{{ if .Acknowledged }}
|
||||||
|
{{ continue }}
|
||||||
|
{{ end }}
|
||||||
|
<div class="line"></div>
|
||||||
|
<div class="trigger"><a href="/trigger/edit/{{ .TriggerID }}">{{ .TriggerName }}</a></div>
|
||||||
|
<div class="area">{{ .AreaName }}</div>
|
||||||
|
<div class="section">{{ .SectionName }}</div>
|
||||||
|
<div class="start">{{ format_time .Start }}</div>
|
||||||
|
<div class="acknowledge"><a href="/problem/acknowledge/{{ .ID }}"><img src="/images/{{ $version }}/acknowledge-filled.svg"></a></div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<input type="checkbox" id="show-acked" onclick="_ui.toggleAcknowledged(event)"> <label for="show-acked">Show acknowledged</label>
|
||||||
|
|
||||||
|
<div id="acknowledged-list" class="hidden">
|
||||||
|
<div style="grid-column: 1/-1; margin-top: 32px;"><h2>Acknowledged</h2></div>
|
||||||
|
<div class="header">Trigger</div>
|
||||||
|
<div class="header">Area</div>
|
||||||
|
<div class="header">Section</div>
|
||||||
|
<div class="header">Since</div>
|
||||||
|
|
||||||
|
{{ range .Data.Problems }}
|
||||||
|
{{ if not .Acknowledged }}
|
||||||
|
{{ continue }}
|
||||||
|
{{ end }}
|
||||||
|
<div class="line"></div>
|
||||||
|
<div class="trigger"><a href="/trigger/edit/{{ .TriggerID }}">{{ .TriggerName }}</a></div>
|
||||||
|
<div class="area">{{ .AreaName }}</div>
|
||||||
|
<div class="section">{{ .SectionName }}</div>
|
||||||
|
<div class="start">{{ format_time .Start }}</div>
|
||||||
|
<div class="acknowledge"><a href="/problem/unacknowledge/{{ .ID }}"><img src="/images/{{ $version }}/acknowledge-outline.svg"></a></div>
|
||||||
|
{{ end }}
|
||||||
|
</div>
|
||||||
|
|
||||||
<div id="areas">
|
<div id="areas">
|
||||||
{{ range .Data.Areas }}
|
{{ range .Data.Areas }}
|
||||||
<div class="area">
|
<div class="area">
|
||||||
|
Loading…
Reference in New Issue
Block a user