Compare commits
No commits in common. "42b1a20531280b36c956a6c00e5fe12279ce28e6" and "72f23b9c4d1cac2a713cb0fc8a81b72f5e81c26e" have entirely different histories.
42b1a20531
...
72f23b9c4d
69
area.go
69
area.go
@ -2,10 +2,9 @@ package main
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
// External
|
// External
|
||||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
re "git.gibonuddevalla.se/go/wrappederror"
|
||||||
|
|
||||||
// Standard
|
// Standard
|
||||||
"database/sql"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
@ -42,7 +41,7 @@ func AreaRetrieve() (areas []Area, err error) { // {{{
|
|||||||
var jsonData []byte
|
var jsonData []byte
|
||||||
err = row.Scan(&jsonData)
|
err = row.Scan(&jsonData)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = re.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,74 +51,20 @@ func AreaRetrieve() (areas []Area, err error) { // {{{
|
|||||||
|
|
||||||
err = json.Unmarshal(jsonData, &areas)
|
err = json.Unmarshal(jsonData, &areas)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
err = werr.Wrap(err)
|
err = re.Wrap(err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func AreaCreate(name string) (err error) { // {{{
|
func AreaCreate(name string) (err error) {// {{{
|
||||||
_, err = service.Db.Conn.Exec(`INSERT INTO area(name) VALUES($1)`, name)
|
_, err = service.Db.Conn.Exec(`INSERT INTO area(name) VALUES($1)`, name)
|
||||||
return
|
return
|
||||||
} // }}}
|
}// }}}
|
||||||
func AreaRename(id int, name string) (err error) { // {{{
|
func AreaRename(id int, name string) (err error) {// {{{
|
||||||
_, err = service.Db.Conn.Exec(`UPDATE area SET name=$2 WHERE id=$1`, id, name)
|
_, err = service.Db.Conn.Exec(`UPDATE area SET name=$2 WHERE id=$1`, id, name)
|
||||||
return
|
return
|
||||||
} // }}}
|
}// }}}
|
||||||
func AreaDelete(id int) (err error) { // {{{
|
|
||||||
var trx *sql.Tx
|
|
||||||
trx, err = service.Db.Conn.Begin()
|
|
||||||
if err != nil {
|
|
||||||
err = werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = trx.Exec(`
|
|
||||||
DELETE
|
|
||||||
FROM trigger t
|
|
||||||
USING section s
|
|
||||||
WHERE
|
|
||||||
t.section_id = s.id AND
|
|
||||||
s.area_id = $1
|
|
||||||
`,
|
|
||||||
id,
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
err2 := trx.Rollback()
|
|
||||||
if err2 != nil {
|
|
||||||
return werr.Wrap(err2).WithData(err)
|
|
||||||
}
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = trx.Exec(`DELETE FROM public.section WHERE area_id = $1`, id)
|
|
||||||
if err != nil {
|
|
||||||
err2 := trx.Rollback()
|
|
||||||
if err2 != nil {
|
|
||||||
return werr.Wrap(err2).WithData(err)
|
|
||||||
}
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = trx.Exec(`DELETE FROM public.area WHERE id = $1`, id)
|
|
||||||
if err != nil {
|
|
||||||
err2 := trx.Rollback()
|
|
||||||
if err2 != nil {
|
|
||||||
return werr.Wrap(err2).WithData(err)
|
|
||||||
}
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
err = trx.Commit()
|
|
||||||
if err != nil {
|
|
||||||
err2 := trx.Rollback()
|
|
||||||
if err2 != nil {
|
|
||||||
return werr.Wrap(err2).WithData(err)
|
|
||||||
}
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
} // }}}
|
|
||||||
|
|
||||||
func (a Area) SortedSections() []Section { // {{{
|
func (a Area) SortedSections() []Section { // {{{
|
||||||
sort.SliceStable(a.Sections, func(i, j int) bool {
|
sort.SliceStable(a.Sections, func(i, j int) bool {
|
||||||
|
13
datapoint.go
13
datapoint.go
@ -25,7 +25,6 @@ type Datapoint struct {
|
|||||||
Group string
|
Group string
|
||||||
Name string
|
Name string
|
||||||
Datatype DatapointType
|
Datatype DatapointType
|
||||||
Comment string
|
|
||||||
LastValue time.Time `db:"last_value"`
|
LastValue time.Time `db:"last_value"`
|
||||||
DatapointValueJSON []byte `db:"datapoint_value_json"`
|
DatapointValueJSON []byte `db:"datapoint_value_json"`
|
||||||
LastDatapointValue DatapointValue
|
LastDatapointValue DatapointValue
|
||||||
@ -74,12 +73,11 @@ func (dp Datapoint) Update() (err error) { // {{{
|
|||||||
|
|
||||||
if dp.ID == 0 {
|
if dp.ID == 0 {
|
||||||
_, err = service.Db.Conn.Exec(
|
_, err = service.Db.Conn.Exec(
|
||||||
`INSERT INTO datapoint("group", name, datatype, nodata_problem_seconds, comment) VALUES($1, $2, $3, $4, $5)`,
|
`INSERT INTO datapoint("group", name, datatype, nodata_problem_seconds) VALUES($1, $2, $3, $4)`,
|
||||||
dp.Group,
|
dp.Group,
|
||||||
name,
|
name,
|
||||||
dp.Datatype,
|
dp.Datatype,
|
||||||
dp.NodataProblemSeconds,
|
dp.NodataProblemSeconds,
|
||||||
dp.Comment,
|
|
||||||
)
|
)
|
||||||
} else {
|
} else {
|
||||||
/* Keep nodata_is_problem as is unless the nodata_problem_seconds is changed.
|
/* Keep nodata_is_problem as is unless the nodata_problem_seconds is changed.
|
||||||
@ -92,11 +90,10 @@ func (dp Datapoint) Update() (err error) { // {{{
|
|||||||
"group"=$2,
|
"group"=$2,
|
||||||
name=$3,
|
name=$3,
|
||||||
datatype=$4,
|
datatype=$4,
|
||||||
comment=$5,
|
nodata_problem_seconds=$5,
|
||||||
nodata_problem_seconds=$6,
|
|
||||||
nodata_is_problem = (
|
nodata_is_problem = (
|
||||||
CASE
|
CASE
|
||||||
WHEN $6 != nodata_problem_seconds THEN false
|
WHEN $5 != nodata_problem_seconds THEN false
|
||||||
ELSE
|
ELSE
|
||||||
nodata_is_problem
|
nodata_is_problem
|
||||||
END
|
END
|
||||||
@ -108,7 +105,6 @@ func (dp Datapoint) Update() (err error) { // {{{
|
|||||||
dp.Group,
|
dp.Group,
|
||||||
name,
|
name,
|
||||||
dp.Datatype,
|
dp.Datatype,
|
||||||
dp.Comment,
|
|
||||||
dp.NodataProblemSeconds,
|
dp.NodataProblemSeconds,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -165,7 +161,6 @@ func DatapointsRetrieve() (dps []Datapoint, err error) { // {{{
|
|||||||
dp.datatype,
|
dp.datatype,
|
||||||
dp.last_value,
|
dp.last_value,
|
||||||
dp.group,
|
dp.group,
|
||||||
dp.comment,
|
|
||||||
dp.nodata_problem_seconds,
|
dp.nodata_problem_seconds,
|
||||||
|
|
||||||
dpv.id AS v_id,
|
dpv.id AS v_id,
|
||||||
@ -195,7 +190,6 @@ func DatapointsRetrieve() (dps []Datapoint, err error) { // {{{
|
|||||||
Group string
|
Group string
|
||||||
Name string
|
Name string
|
||||||
Datatype DatapointType
|
Datatype DatapointType
|
||||||
Comment string
|
|
||||||
LastValue time.Time `db:"last_value"`
|
LastValue time.Time `db:"last_value"`
|
||||||
NodataProblemSeconds int `db:"nodata_problem_seconds"`
|
NodataProblemSeconds int `db:"nodata_problem_seconds"`
|
||||||
|
|
||||||
@ -220,7 +214,6 @@ func DatapointsRetrieve() (dps []Datapoint, err error) { // {{{
|
|||||||
dp.Name = res.Name
|
dp.Name = res.Name
|
||||||
dp.Group = res.Group
|
dp.Group = res.Group
|
||||||
dp.Datatype = res.Datatype
|
dp.Datatype = res.Datatype
|
||||||
dp.Comment = res.Comment
|
|
||||||
dp.LastValue = res.LastValue
|
dp.LastValue = res.LastValue
|
||||||
dp.Found = true
|
dp.Found = true
|
||||||
dp.NodataProblemSeconds = res.NodataProblemSeconds
|
dp.NodataProblemSeconds = res.NodataProblemSeconds
|
||||||
|
91
main.go
91
main.go
@ -120,35 +120,33 @@ func main() { // {{{
|
|||||||
|
|
||||||
service.Register("/", false, false, staticHandler)
|
service.Register("/", false, false, staticHandler)
|
||||||
|
|
||||||
service.Register("/area/new/{name}", false, false, actionAreaNew)
|
service.Register("/area/new/{name}", false, false, areaNew)
|
||||||
service.Register("/area/rename/{id}/{name}", false, false, actionAreaRename)
|
service.Register("/area/rename/{id}/{name}", false, false, areaRename)
|
||||||
service.Register("/area/delete/{id}", false, false, actionAreaDelete)
|
|
||||||
|
|
||||||
service.Register("/section/new/{areaID}/{name}", false, false, actionSectionNew)
|
service.Register("/section/new/{areaID}/{name}", false, false, sectionNew)
|
||||||
service.Register("/section/rename/{id}/{name}", false, false, actionSectionRename)
|
service.Register("/section/rename/{id}/{name}", false, false, sectionRename)
|
||||||
service.Register("/section/delete/{id}", false, false, actionSectionDelete)
|
|
||||||
|
|
||||||
service.Register("/problems", false, false, pageProblems)
|
service.Register("/problems", false, false, pageProblems)
|
||||||
service.Register("/problem/acknowledge/{id}", false, false, actionProblemAcknowledge)
|
service.Register("/problem/acknowledge/{id}", false, false, pageProblemAcknowledge)
|
||||||
service.Register("/problem/unacknowledge/{id}", false, false, actionProblemUnacknowledge)
|
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)
|
||||||
service.Register("/datapoint/update/{id}", false, false, actionDatapointUpdate)
|
service.Register("/datapoint/update/{id}", false, false, pageDatapointUpdate)
|
||||||
service.Register("/datapoint/delete/{id}", false, false, actionDatapointDelete)
|
service.Register("/datapoint/delete/{id}", false, false, pageDatapointDelete)
|
||||||
service.Register("/datapoint/values/{id}", false, false, pageDatapointValues)
|
service.Register("/datapoint/values/{id}", false, false, pageDatapointValues)
|
||||||
|
|
||||||
service.Register("/triggers", false, false, pageTriggers)
|
service.Register("/triggers", false, false, pageTriggers)
|
||||||
service.Register("/trigger/create/{sectionID}/{name}", false, false, actionTriggerCreate)
|
service.Register("/trigger/create/{sectionID}/{name}", false, false, triggerCreate)
|
||||||
service.Register("/trigger/edit/{id}", false, false, pageTriggerEdit)
|
service.Register("/trigger/edit/{id}", false, false, pageTriggerEdit)
|
||||||
service.Register("/trigger/edit/{id}/{sectionID}", false, false, pageTriggerEdit)
|
service.Register("/trigger/edit/{id}/{sectionID}", false, false, pageTriggerEdit)
|
||||||
service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, actionTriggerDatapointAdd)
|
service.Register("/trigger/addDatapoint/{id}/{datapointName}", false, false, pageTriggerDatapointAdd)
|
||||||
service.Register("/trigger/update/{id}", false, false, actionTriggerUpdate)
|
service.Register("/trigger/update/{id}", false, false, pageTriggerUpdate)
|
||||||
service.Register("/trigger/run/{id}", false, false, actionTriggerRun)
|
service.Register("/trigger/run/{id}", false, false, pageTriggerRun)
|
||||||
service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete)
|
service.Register("/trigger/delete/{id}", false, false, actionTriggerDelete)
|
||||||
|
|
||||||
service.Register("/configuration", false, false, pageConfiguration)
|
service.Register("/configuration", false, false, pageConfiguration)
|
||||||
service.Register("/entry/{datapoint}", false, false, actionEntryDatapoint)
|
service.Register("/entry/{datapoint}", false, false, entryDatapoint)
|
||||||
|
|
||||||
go nodataLoop()
|
go nodataLoop()
|
||||||
|
|
||||||
@ -199,7 +197,7 @@ func staticHandler(w http.ResponseWriter, r *http.Request, sess *session.T) { //
|
|||||||
|
|
||||||
service.StaticHandler(w, r, sess)
|
service.StaticHandler(w, r, sess)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionEntryDatapoint(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{
|
func entryDatapoint(w http.ResponseWriter, r *http.Request, sess *session.T) { // {{{
|
||||||
dpoint := r.PathValue("datapoint")
|
dpoint := r.PathValue("datapoint")
|
||||||
value, _ := io.ReadAll(r.Body)
|
value, _ := io.ReadAll(r.Body)
|
||||||
|
|
||||||
@ -370,7 +368,7 @@ func pageIndex(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
|||||||
page.Render(w)
|
page.Render(w)
|
||||||
} // }}}
|
} // }}}
|
||||||
|
|
||||||
func actionAreaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func areaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
name := r.PathValue("name")
|
name := r.PathValue("name")
|
||||||
err := AreaCreate(name)
|
err := AreaCreate(name)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -382,7 +380,7 @@ func actionAreaNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{
|
|||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionAreaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func areaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -401,26 +399,8 @@ func actionAreaRename(w http.ResponseWriter, r *http.Request, _ *session.T) { //
|
|||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionAreaDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
|
||||||
idStr := r.PathValue("id")
|
|
||||||
id, err := strconv.Atoi(idStr)
|
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).WithData(idStr).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = AreaDelete(id)
|
func sectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).WithData(id).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Add("Location", "/configuration")
|
|
||||||
w.WriteHeader(302)
|
|
||||||
return
|
|
||||||
} // }}}
|
|
||||||
|
|
||||||
func actionSectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
|
||||||
idStr := r.PathValue("areaID")
|
idStr := r.PathValue("areaID")
|
||||||
areaID, err := strconv.Atoi(idStr)
|
areaID, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -439,7 +419,7 @@ func actionSectionNew(w http.ResponseWriter, r *http.Request, _ *session.T) { //
|
|||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionSectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func sectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -458,24 +438,6 @@ func actionSectionRename(w http.ResponseWriter, r *http.Request, _ *session.T) {
|
|||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionSectionDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
|
||||||
idStr := r.PathValue("id")
|
|
||||||
id, err := strconv.Atoi(idStr)
|
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).WithData(idStr).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
err = SectionDelete(id)
|
|
||||||
if err != nil {
|
|
||||||
httpError(w, werr.Wrap(err).WithData(id).Log())
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
w.Header().Add("Location", "/configuration")
|
|
||||||
w.WriteHeader(302)
|
|
||||||
return
|
|
||||||
} // }}}
|
|
||||||
|
|
||||||
func pageProblems(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
func pageProblems(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
||||||
page := Page{
|
page := Page{
|
||||||
@ -512,7 +474,7 @@ func pageProblems(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
|||||||
page.Render(w)
|
page.Render(w)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -531,7 +493,7 @@ func actionProblemAcknowledge(w http.ResponseWriter, r *http.Request, _ *session
|
|||||||
|
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionProblemUnacknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageProblemUnacknowledge(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -610,7 +572,7 @@ func pageDatapointEdit(w http.ResponseWriter, r *http.Request, _ *session.T) { /
|
|||||||
page.Render(w)
|
page.Render(w)
|
||||||
return
|
return
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -626,7 +588,6 @@ func actionDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T)
|
|||||||
dp.Group = r.FormValue("group")
|
dp.Group = r.FormValue("group")
|
||||||
dp.Name = r.FormValue("name")
|
dp.Name = r.FormValue("name")
|
||||||
dp.Datatype = DatapointType(r.FormValue("datatype"))
|
dp.Datatype = DatapointType(r.FormValue("datatype"))
|
||||||
dp.Comment = r.FormValue("comment")
|
|
||||||
dp.NodataProblemSeconds = nodataSeconds
|
dp.NodataProblemSeconds = nodataSeconds
|
||||||
err = dp.Update()
|
err = dp.Update()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -637,7 +598,7 @@ func actionDatapointUpdate(w http.ResponseWriter, r *http.Request, _ *session.T)
|
|||||||
w.Header().Add("Location", "/datapoints")
|
w.Header().Add("Location", "/datapoints")
|
||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionDatapointDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageDatapointDelete(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -713,7 +674,7 @@ func pageTriggers(w http.ResponseWriter, _ *http.Request, _ *session.T) { // {{{
|
|||||||
|
|
||||||
page.Render(w)
|
page.Render(w)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionTriggerCreate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func triggerCreate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
name := r.PathValue("name")
|
name := r.PathValue("name")
|
||||||
sectionIDStr := r.PathValue("sectionID")
|
sectionIDStr := r.PathValue("sectionID")
|
||||||
sectionID, err := strconv.Atoi(sectionIDStr)
|
sectionID, err := strconv.Atoi(sectionIDStr)
|
||||||
@ -800,7 +761,7 @@ func pageTriggerEdit(w http.ResponseWriter, r *http.Request, _ *session.T) { //
|
|||||||
|
|
||||||
page.Render(w)
|
page.Render(w)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
triggerID := r.PathValue("id")
|
triggerID := r.PathValue("id")
|
||||||
dpName := r.PathValue("datapointName")
|
dpName := r.PathValue("datapointName")
|
||||||
|
|
||||||
@ -832,7 +793,7 @@ func actionTriggerDatapointAdd(w http.ResponseWriter, r *http.Request, _ *sessio
|
|||||||
w.Header().Add("Content-Type", "application/json")
|
w.Header().Add("Content-Type", "application/json")
|
||||||
w.Write(j)
|
w.Write(j)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -867,7 +828,7 @@ func actionTriggerUpdate(w http.ResponseWriter, r *http.Request, _ *session.T) {
|
|||||||
w.Header().Add("Location", "/triggers")
|
w.Header().Add("Location", "/triggers")
|
||||||
w.WriteHeader(302)
|
w.WriteHeader(302)
|
||||||
} // }}}
|
} // }}}
|
||||||
func actionTriggerRun(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
func pageTriggerRun(w http.ResponseWriter, r *http.Request, _ *session.T) { // {{{
|
||||||
idStr := r.PathValue("id")
|
idStr := r.PathValue("id")
|
||||||
id, err := strconv.Atoi(idStr)
|
id, err := strconv.Atoi(idStr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -16,16 +16,7 @@ func ServiceFactory(t string, config []byte, prio int, ackURL string, logger *sl
|
|||||||
err = werr.Wrap(err).WithData(config)
|
err = werr.Wrap(err).WithData(config)
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
ntfy.SetLogger(logger)
|
|
||||||
return ntfy, nil
|
return ntfy, nil
|
||||||
case "SCRIPT":
|
|
||||||
script, err := NewScript(config, prio, ackURL)
|
|
||||||
if err != nil {
|
|
||||||
err = werr.Wrap(err).WithData(config)
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
script.SetLogger(logger)
|
|
||||||
return script, nil
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000")
|
return nil, werr.New("Unknown notification service, '%s'", t).WithCode("002-0000")
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package notification
|
|
||||||
|
|
||||||
import (
|
|
||||||
// External
|
|
||||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
|
||||||
|
|
||||||
// Standard
|
|
||||||
"encoding/json"
|
|
||||||
"log/slog"
|
|
||||||
"os/exec"
|
|
||||||
"strconv"
|
|
||||||
"strings"
|
|
||||||
)
|
|
||||||
|
|
||||||
type Script struct {
|
|
||||||
Filename string
|
|
||||||
Prio int
|
|
||||||
AcknowledgeURL string
|
|
||||||
logger *slog.Logger
|
|
||||||
}
|
|
||||||
|
|
||||||
func NewScript(config []byte, prio int, ackURL string) (instance *Script, err error) {
|
|
||||||
instance = new(Script)
|
|
||||||
err = json.Unmarshal(config, &instance)
|
|
||||||
if err != nil {
|
|
||||||
err = werr.Wrap(err).WithCode("002-0001").WithData(config)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
instance.Prio = prio
|
|
||||||
instance.AcknowledgeURL = ackURL
|
|
||||||
return instance, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (script *Script) SetLogger(l *slog.Logger) {
|
|
||||||
script.logger = l
|
|
||||||
}
|
|
||||||
|
|
||||||
func (script *Script) GetType() string {
|
|
||||||
return "SCRIPT"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (script *Script) GetPrio() int {
|
|
||||||
return script.Prio
|
|
||||||
}
|
|
||||||
|
|
||||||
func (script Script) Send(problemID int, msg []byte) (err error) {
|
|
||||||
var errbuf strings.Builder
|
|
||||||
cmd := exec.Command(script.Filename, strconv.Itoa(problemID), script.AcknowledgeURL, string(msg))
|
|
||||||
cmd.Stderr = &errbuf
|
|
||||||
|
|
||||||
err = cmd.Run()
|
|
||||||
if err != nil {
|
|
||||||
script.logger.Error("notification", "type", "script", "error", err)
|
|
||||||
err = werr.Wrap(err).WithData(
|
|
||||||
struct {
|
|
||||||
Filename string
|
|
||||||
ProblemID int
|
|
||||||
Msg string
|
|
||||||
StdErr string
|
|
||||||
}{
|
|
||||||
script.Filename,
|
|
||||||
problemID,
|
|
||||||
string(msg),
|
|
||||||
errbuf.String(),
|
|
||||||
},
|
|
||||||
).Log()
|
|
||||||
}
|
|
||||||
|
|
||||||
return
|
|
||||||
}
|
|
23
section.go
23
section.go
@ -1,9 +1,6 @@
|
|||||||
package main
|
package main
|
||||||
|
|
||||||
import (
|
import (
|
||||||
// External
|
|
||||||
werr "git.gibonuddevalla.se/go/wrappederror"
|
|
||||||
|
|
||||||
// Standard
|
// Standard
|
||||||
"sort"
|
"sort"
|
||||||
)
|
)
|
||||||
@ -25,23 +22,11 @@ func (s *Section) SortedTriggers() []Trigger {
|
|||||||
return s.Triggers
|
return s.Triggers
|
||||||
}
|
}
|
||||||
|
|
||||||
func SectionCreate(areaID int, name string) (err error) { // {{{
|
func SectionCreate(areaID int, name string) (err error) {// {{{
|
||||||
_, err = service.Db.Conn.Exec(`INSERT INTO section(area_id, name) VALUES($1, $2)`, areaID, name)
|
_, err = service.Db.Conn.Exec(`INSERT INTO section(area_id, name) VALUES($1, $2)`, areaID, name)
|
||||||
return
|
return
|
||||||
} // }}}
|
}// }}}
|
||||||
func SectionRename(id int, name string) (err error) { // {{{
|
func SectionRename(id int, name string) (err error) {// {{{
|
||||||
_, err = service.Db.Conn.Exec(`UPDATE section SET name=$2 WHERE id=$1`, id, name)
|
_, err = service.Db.Conn.Exec(`UPDATE section SET name=$2 WHERE id=$1`, id, name)
|
||||||
return
|
return
|
||||||
} // }}}
|
}// }}}
|
||||||
func SectionDelete(id int) (err error) { // {{{
|
|
||||||
_, err = service.Db.Conn.Exec(`DELETE FROM public.trigger WHERE section_id = $1`, id)
|
|
||||||
if err != nil {
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
|
|
||||||
_, err = service.Db.Conn.Exec(`DELETE FROM public.section WHERE id = $1`, id)
|
|
||||||
if err != nil {
|
|
||||||
return werr.Wrap(err).WithData(id)
|
|
||||||
}
|
|
||||||
return
|
|
||||||
} // }}}
|
|
||||||
|
@ -1,9 +0,0 @@
|
|||||||
ALTER TYPE notification_type RENAME TO _notification_type;
|
|
||||||
CREATE TYPE notification_type AS ENUM ('NTFY', 'SCRIPT');
|
|
||||||
|
|
||||||
ALTER TABLE notification RENAME COLUMN service TO _service;
|
|
||||||
ALTER TABLE notification ADD service notification_type NOT NULL DEFAULT 'NTFY';
|
|
||||||
UPDATE notification SET service = _service::text::notification_type;
|
|
||||||
|
|
||||||
ALTER TABLE notification DROP COLUMN _service;
|
|
||||||
DROP TYPE _notification_type;
|
|
@ -1 +0,0 @@
|
|||||||
ALTER TABLE public.datapoint ADD COLUMN comment VARCHAR DEFAULT '' NOT NULL;
|
|
@ -1,130 +0,0 @@
|
|||||||
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: sans-serif;
|
|
||||||
font-weight: 300;
|
|
||||||
color: #d5c4a1;
|
|
||||||
font-size: 11pt;
|
|
||||||
}
|
|
||||||
h1,
|
|
||||||
h2 {
|
|
||||||
margin-bottom: 4px;
|
|
||||||
}
|
|
||||||
h1:first-child,
|
|
||||||
h2:first-child {
|
|
||||||
margin-top: 0px;
|
|
||||||
}
|
|
||||||
h1 {
|
|
||||||
font-size: 1.5em;
|
|
||||||
color: #fb4934;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
h2 {
|
|
||||||
font-size: 1.25em;
|
|
||||||
color: #b8bb26;
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
a {
|
|
||||||
color: #3f9da1;
|
|
||||||
text-decoration: none;
|
|
||||||
}
|
|
||||||
a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
b {
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
|
||||||
input[type="text"],
|
|
||||||
textarea,
|
|
||||||
select {
|
|
||||||
font-family: monospace;
|
|
||||||
background: #202020;
|
|
||||||
color: #d5c4a1;
|
|
||||||
padding: 4px 8px;
|
|
||||||
border: none;
|
|
||||||
font-size: 1em;
|
|
||||||
line-height: 1.5em;
|
|
||||||
}
|
|
||||||
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: 800;
|
|
||||||
}
|
|
||||||
span.time {
|
|
||||||
font-size: 0.9em;
|
|
||||||
color: #d5c4a1;
|
|
||||||
}
|
|
||||||
span.seconds {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
label {
|
|
||||||
user-select: none;
|
|
||||||
}
|
|
||||||
.description {
|
|
||||||
border: 1px solid #737373;
|
|
||||||
color: #3f9da1;
|
|
||||||
background: #202020;
|
|
||||||
padding: 4px 8px;
|
|
||||||
margin-top: 8px;
|
|
||||||
white-space: nowrap;
|
|
||||||
width: min-content;
|
|
||||||
border-radius: 8px;
|
|
||||||
}
|
|
||||||
#areas .area > .name {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr min-content;
|
|
||||||
grid-gap: 0px 16px;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 16px;
|
|
||||||
padding-right: 8px;
|
|
||||||
}
|
|
||||||
#areas .area > .name img {
|
|
||||||
margin-top: 3px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
#areas .area .section.configuration {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr min-content;
|
|
||||||
grid-gap: 0 16px;
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
}
|
|
||||||
#areas .area .section.configuration:last-child {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
#areas .area .section.configuration img {
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
@ -125,16 +125,12 @@ label {
|
|||||||
}
|
}
|
||||||
#datapoints div {
|
#datapoints div {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
#datapoints .icons {
|
#datapoints .icons {
|
||||||
display: flex;
|
display: flex;
|
||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
#datapoints img.info {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
#values {
|
#values {
|
||||||
display: grid;
|
display: grid;
|
||||||
grid-template-columns: repeat(2, min-content);
|
grid-template-columns: repeat(2, min-content);
|
||||||
|
@ -182,6 +182,10 @@ label {
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
}
|
}
|
||||||
|
#areas .area .section.configuration {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
#areas .area .section:last-child {
|
#areas .area .section:last-child {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
@ -1,67 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="16.000025"
|
|
||||||
height="18"
|
|
||||||
viewBox="0 0 4.2333398 4.7625001"
|
|
||||||
version="1.1"
|
|
||||||
id="svg8"
|
|
||||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
|
||||||
sodipodi:docname="delete_white.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="32"
|
|
||||||
inkscape:cx="10.203125"
|
|
||||||
inkscape:cy="7.03125"
|
|
||||||
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(-214.57708,-116.15208)">
|
|
||||||
<title
|
|
||||||
id="title1">trash-can-outline</title>
|
|
||||||
<path
|
|
||||||
d="m 215.9,116.15208 v 0.26459 h -1.32292 v 0.52916 h 0.26459 v 3.43959 a 0.52916667,0.52916667 0 0 0 0.52916,0.52916 h 2.64584 a 0.52916667,0.52916667 0 0 0 0.52916,-0.52916 v -3.43959 h 0.26459 v -0.52916 h -1.32292 v -0.26459 H 215.9 m -0.52917,0.79375 h 2.64584 v 3.43959 h -2.64584 v -3.43959 M 215.9,117.475 v 2.38125 h 0.52917 V 117.475 H 215.9 m 1.05833,0 v 2.38125 h 0.52917 V 117.475 Z"
|
|
||||||
id="path1"
|
|
||||||
style="fill:#ffffff;fill-opacity:1;stroke-width:0.264583" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.3 KiB |
@ -1,69 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="17.999989"
|
|
||||||
height="18"
|
|
||||||
viewBox="0 0 4.7624969 4.7625001"
|
|
||||||
version="1.1"
|
|
||||||
id="svg8"
|
|
||||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
|
||||||
sodipodi:docname="info-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="16"
|
|
||||||
inkscape:cx="6.84375"
|
|
||||||
inkscape:cy="0.6875"
|
|
||||||
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(-90.222917,-148.43125)">
|
|
||||||
<title
|
|
||||||
id="title1">information-slab-circle</title>
|
|
||||||
<title
|
|
||||||
id="title1-6">information</title>
|
|
||||||
<path
|
|
||||||
d="m 92.842292,150.09812 h -0.47625 v -0.47625 h 0.47625 m 0,2.38126 h -0.47625 v -1.42875 h 0.47625 m -0.238125,-2.14313 a 2.3812503,2.3812503 0 0 0 -2.38125,2.38125 2.3812503,2.3812503 0 0 0 2.38125,2.38124 2.3812503,2.3812503 0 0 0 2.381246,-2.38124 2.3812503,2.3812503 0 0 0 -2.381246,-2.38125 z"
|
|
||||||
id="path1-2"
|
|
||||||
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#fb4934;fill-opacity:1;stroke-width:0.311724;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.5 KiB |
@ -1,71 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
|
||||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
|
||||||
|
|
||||||
<svg
|
|
||||||
width="17.999989"
|
|
||||||
height="18"
|
|
||||||
viewBox="0 0 4.7624969 4.7625001"
|
|
||||||
version="1.1"
|
|
||||||
id="svg8"
|
|
||||||
inkscape:version="1.3.2 (1:1.3.2+202311252150+091e20ef0f)"
|
|
||||||
sodipodi:docname="info-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="11.313708"
|
|
||||||
inkscape:cx="21.610951"
|
|
||||||
inkscape:cy="4.5961941"
|
|
||||||
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(-90.222917,-148.43125)">
|
|
||||||
<title
|
|
||||||
id="title1">information-slab-circle</title>
|
|
||||||
<title
|
|
||||||
id="title1-6">information-slab-circle-outline</title>
|
|
||||||
<title
|
|
||||||
id="title1-5">information-outline</title>
|
|
||||||
<path
|
|
||||||
d="m 92.366045,150.09812 h 0.47625 v -0.47625 h -0.47625 m 0.238125,3.09564 c -1.050132,0 -1.905003,-0.85488 -1.905003,-1.90501 0,-1.05013 0.854871,-1.90501 1.905003,-1.90501 1.050133,0 1.905006,0.85488 1.905006,1.90501 0,1.05013 -0.854873,1.90501 -1.905006,1.90501 m 0,-4.28626 a 2.381253,2.381253 0 0 0 -2.381253,2.38125 2.381253,2.381253 0 0 0 2.381253,2.38125 2.381253,2.381253 0 0 0 2.381256,-2.38125 2.381253,2.381253 0 0 0 -2.381256,-2.38125 m -0.238125,3.57188 h 0.47625 v -1.42875 h -0.47625 z"
|
|
||||||
id="path1-3"
|
|
||||||
style="font-variation-settings:normal;opacity:1;vector-effect:none;fill:#666666;fill-opacity:1;stroke-width:0.238125;stroke-linecap:butt;stroke-linejoin:miter;stroke-miterlimit:4;stroke-dasharray:none;stroke-dashoffset:0;stroke-opacity:1;-inkscape-stroke:none;stop-color:#000000;stop-opacity:1" />
|
|
||||||
</g>
|
|
||||||
</svg>
|
|
Before Width: | Height: | Size: 2.8 KiB |
@ -1,38 +0,0 @@
|
|||||||
@import 'theme.less';
|
|
||||||
|
|
||||||
#areas {
|
|
||||||
.area {
|
|
||||||
& > .name {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr min-content;
|
|
||||||
grid-gap: 0px 16px;
|
|
||||||
align-items: center;
|
|
||||||
padding-left: 16px;
|
|
||||||
padding-right: 8px;
|
|
||||||
|
|
||||||
img {
|
|
||||||
margin-top: 3px;
|
|
||||||
margin-bottom: 4px;
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
.section.configuration {
|
|
||||||
display: grid;
|
|
||||||
grid-template-columns: 1fr min-content;
|
|
||||||
grid-gap: 0 16px;
|
|
||||||
|
|
||||||
margin-top: 8px;
|
|
||||||
margin-bottom: 8px;
|
|
||||||
|
|
||||||
&:last-child {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
img {
|
|
||||||
height: 16px;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -13,7 +13,6 @@
|
|||||||
margin-top: 1.5em;
|
margin-top: 1.5em;
|
||||||
padding-bottom: 4px;
|
padding-bottom: 4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
border-bottom: unset;
|
border-bottom: unset;
|
||||||
}
|
}
|
||||||
@ -27,7 +26,6 @@
|
|||||||
|
|
||||||
div {
|
div {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
align-self: center;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.icons {
|
.icons {
|
||||||
@ -35,10 +33,6 @@
|
|||||||
gap: 12px;
|
gap: 12px;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
img.info {
|
|
||||||
height: 20px;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#values {
|
#values {
|
||||||
|
@ -94,6 +94,11 @@
|
|||||||
margin-top: 12px;
|
margin-top: 12px;
|
||||||
margin-bottom: 20px;
|
margin-bottom: 20px;
|
||||||
|
|
||||||
|
&.configuration {
|
||||||
|
margin-top: 8px;
|
||||||
|
margin-bottom: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
&:last-child {
|
&:last-child {
|
||||||
margin-bottom: 12px;
|
margin-bottom: 12px;
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,4 @@
|
|||||||
{{ define "page" }}
|
{{ define "page" }}
|
||||||
{{ $version := .VERSION }}
|
|
||||||
<link rel="stylesheet" type="text/css" href="/css/{{ .VERSION }}/configuration.css">
|
|
||||||
<script type="text/javascript">
|
<script type="text/javascript">
|
||||||
function newArea() {
|
function newArea() {
|
||||||
let name = prompt("Area name")
|
let name = prompt("Area name")
|
||||||
@ -49,18 +47,6 @@
|
|||||||
}
|
}
|
||||||
location.href = `/section/rename/${id}/${newName.trim()}`
|
location.href = `/section/rename/${id}/${newName.trim()}`
|
||||||
}
|
}
|
||||||
|
|
||||||
function deleteArea(id, name) {
|
|
||||||
if (!confirm(`Are you sure you want to delete '${name}'?\nEverything in it will be deleted!`))
|
|
||||||
return
|
|
||||||
location.href = `/area/delete/${id}`
|
|
||||||
}
|
|
||||||
|
|
||||||
function deleteSection(id, name) {
|
|
||||||
if (!confirm(`Are you sure you want to delete '${name}'?\nEverything in it will be deleted!`))
|
|
||||||
return
|
|
||||||
location.href = `/section/delete/${id}`
|
|
||||||
}
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
{{ block "page_label" . }}{{end}}
|
{{ block "page_label" . }}{{end}}
|
||||||
@ -72,21 +58,14 @@
|
|||||||
<div id="areas">
|
<div id="areas">
|
||||||
{{ range .Data.Areas }}
|
{{ range .Data.Areas }}
|
||||||
<div class="area">
|
<div class="area">
|
||||||
<div class="name">
|
<div class="name" onclick="renameArea({{ .ID }}, {{ .Name }})">{{ .Name }}</div>
|
||||||
<div onclick="renameArea({{ .ID }}, '{{ .Name }}')">{{ .Name }}</div>
|
|
||||||
<img class="delete" src="/images/{{ $version }}/delete_white.svg" onclick="deleteArea({{ .ID }}, '{{ .Name }}')">
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div style="margin: 8px 16px">
|
<div style="margin: 8px 16px">
|
||||||
<a href="#" onclick="newSection({{ .ID }})">Create</a>
|
<a href="#" onclick="newSection({{ .ID }})">Create</a>
|
||||||
</div>
|
</div>
|
||||||
{{ range .SortedSections }}
|
{{ range .SortedSections }}
|
||||||
{{ if eq .ID 0 }}
|
|
||||||
{{ continue }}
|
|
||||||
{{ end }}
|
|
||||||
<div class="section configuration">
|
<div class="section configuration">
|
||||||
<div class="name" onclick="renameSection({{ .ID }}, {{ .Name }})">{{ .Name }}</div>
|
<div class="name" onclick="renameSection({{ .ID }}, {{ .Name }})">{{ .Name }}</div>
|
||||||
<img src="/images/{{ $version }}/delete.svg" onclick="deleteSection({{ .ID }}, '{{ .Name }}')">
|
|
||||||
</div>
|
</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
</div>
|
</div>
|
||||||
|
@ -32,12 +32,6 @@
|
|||||||
<div class="description">Set to 0 to disable.</div>
|
<div class="description">Set to 0 to disable.</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="label">Comment</div>
|
|
||||||
<div>
|
|
||||||
<textarea name="comment" rows=4>{{ .Data.Datapoint.Comment }}</textarea>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
|
|
||||||
<div></div>
|
<div></div>
|
||||||
<div class="action">
|
<div class="action">
|
||||||
{{ if eq .Data.Datapoint.ID 0 }}
|
{{ if eq .Data.Datapoint.ID 0 }}
|
||||||
|
@ -31,11 +31,6 @@
|
|||||||
<div class="value">{{ .LastDatapointValue.Value }}</div>
|
<div class="value">{{ .LastDatapointValue.Value }}</div>
|
||||||
{{ end }}
|
{{ end }}
|
||||||
<div class="icons">
|
<div class="icons">
|
||||||
{{ if eq .Comment "" }}
|
|
||||||
<div class="values"><img class="info" src="/images/{{ $version }}/info-outline.svg"></div>
|
|
||||||
{{ else }}
|
|
||||||
<div class="values"><img class="info" src="/images/{{ $version }}/info-filled.svg" title="{{ .Comment }}"></div>
|
|
||||||
{{ end }}
|
|
||||||
<div class="values"><a href="/datapoint/values/{{ .ID }}"><img src="/images/{{ $version }}/values.svg"></a></div>
|
<div class="values"><a href="/datapoint/values/{{ .ID }}"><img src="/images/{{ $version }}/values.svg"></a></div>
|
||||||
<div class="delete"><a href="/datapoint/delete/{{ .ID }}" onclick="confirm(`Are you sure you want to delete '{{ .Name }}'?`)"><img src="/images/{{ $version }}/delete.svg"></a></div>
|
<div class="delete"><a href="/datapoint/delete/{{ .ID }}" onclick="confirm(`Are you sure you want to delete '{{ .Name }}'?`)"><img src="/images/{{ $version }}/delete.svg"></a></div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -38,9 +38,6 @@
|
|||||||
<div class="area">
|
<div class="area">
|
||||||
<div class="name">{{ .Name }}</div>
|
<div class="name">{{ .Name }}</div>
|
||||||
{{ range .SortedSections }}
|
{{ range .SortedSections }}
|
||||||
{{ if eq .ID 0 }}
|
|
||||||
{{ continue }}
|
|
||||||
{{ end }}
|
|
||||||
<div class="section">
|
<div class="section">
|
||||||
<div class="create">
|
<div class="create">
|
||||||
<div class="name">{{ .Name }}</div>
|
<div class="name">{{ .Name }}</div>
|
||||||
|
Loading…
Reference in New Issue
Block a user