Compare commits

...

2 Commits

Author SHA1 Message Date
Magnus Åhall
317c233255 Bumped to v6 2024-05-04 22:08:04 +02:00
Magnus Åhall
7990f1f419 Remove datapoint from trigger 2024-05-04 22:07:41 +02:00
6 changed files with 53 additions and 12 deletions

View File

@ -27,6 +27,7 @@ type Datapoint struct {
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
Found bool
} }
type DatapointValue struct { type DatapointValue struct {
@ -177,6 +178,7 @@ func DatapointsRetrieve() (dps []Datapoint, err error) { // {{{
dp.Name = res.Name dp.Name = res.Name
dp.Datatype = res.Datatype dp.Datatype = res.Datatype
dp.LastValue = res.LastValue dp.LastValue = res.LastValue
dp.Found = true
if res.VID.Valid { if res.VID.Valid {
dpv.ID = int(res.VID.Int64) dpv.ID = int(res.VID.Int64)
@ -196,16 +198,25 @@ func DatapointRetrieve(id int, name string) (dp Datapoint, err error) { // {{{
var query string var query string
var param any var param any
if id > 0 { if id > 0 {
query = `SELECT * FROM datapoint WHERE id = $1` query = `SELECT *, true AS found FROM datapoint WHERE id = $1`
param = id param = id
dp.ID = id dp.ID = id
} else { } else {
query = `SELECT * FROM datapoint WHERE name = $1` query = `SELECT *, true AS found FROM datapoint WHERE name = $1`
param = name param = name
} }
row := service.Db.Conn.QueryRowx(query, param) row := service.Db.Conn.QueryRowx(query, param)
err = row.StructScan(&dp) err = row.StructScan(&dp)
if err == sql.ErrNoRows {
dp = Datapoint{
Name: name,
}
err = nil
return
}
if err != nil { if err != nil {
err = we.Wrap(err).WithData(name) err = we.Wrap(err).WithData(name)
return return

View File

@ -23,7 +23,7 @@ import (
"time" "time"
) )
const VERSION = "v5" const VERSION = "v6"
var ( var (
logger *slog.Logger logger *slog.Logger

View File

@ -112,9 +112,16 @@ label {
.widgets .datapoints { .widgets .datapoints {
font: "Roboto Mono", monospace; font: "Roboto Mono", monospace;
display: grid; display: grid;
grid-template-columns: min-content 1fr; grid-template-columns: min-content min-content 1fr;
gap: 6px 8px; gap: 6px 8px;
margin-bottom: 8px; margin-bottom: 8px;
white-space: nowrap;
}
.widgets .datapoints .invalid {
color: #c83737;
}
.widgets .datapoints .delete img {
height: 16px;
} }
.widgets .action { .widgets .action {
display: grid; display: grid;

View File

@ -1,5 +1,5 @@
export class UI { export class UI {
constructor() {//{{{ constructor(version) {//{{{
document.getElementById('button-run'). document.getElementById('button-run').
addEventListener('click', evt => evt.preventDefault()) addEventListener('click', evt => evt.preventDefault())
@ -7,6 +7,7 @@ export class UI {
document.querySelector('input[name="name"]').focus() document.querySelector('input[name="name"]').focus()
this.version = version
this.datapoints = [] this.datapoints = []
}//}}} }//}}}
render() {//{{{ render() {//{{{
@ -17,8 +18,9 @@ export class UI {
let html = Object.keys(this.trigger.datapoints).sort().map(dpName => { let html = Object.keys(this.trigger.datapoints).sort().map(dpName => {
const dp = this.trigger.datapoints[dpName] const dp = this.trigger.datapoints[dpName]
return ` return `
<div class="datapoint name"><b>${dp.Name}</b></div> <div class="datapoint delete"><a href="#" onclick="_ui.deleteDatapoint('${dp.Name}')"><img src="/images/${this.version}/delete.svg"></a></div>
<div class="datapoint value">${dp.LastDatapointValue.TemplateValue}</div> <div class="datapoint name ${dp.Found ? 'valid' : 'invalid'}"><b>${dp.Name}</b></div>
<div class="datapoint value">${dp.Found ? dp.LastDatapointValue.TemplateValue : ''}</div>
` `
}).join('') }).join('')
datapoints.innerHTML += html datapoints.innerHTML += html
@ -78,7 +80,15 @@ export class UI {
dlg.close() dlg.close()
this.render() this.render()
}//}}} }//}}}
update() {//{{{ deleteDatapoint(name) {//{{{
if (!confirm(`Delete ${name}?`)) {
return
}
delete this.trigger.datapoints[name]
_ui.update(true)
}//}}}
update(stayOnSamePage) {//{{{
const form = document.getElementById('form-trigger') const form = document.getElementById('form-trigger')
var formData = new FormData(form) var formData = new FormData(form)
Object.keys(this.trigger.datapoints).forEach(name => formData.append("datapoints[]", name)) Object.keys(this.trigger.datapoints).forEach(name => formData.append("datapoints[]", name))
@ -87,6 +97,11 @@ export class UI {
body: formData, body: formData,
}) })
.then(resp => { .then(resp => {
if (stayOnSamePage) {
location.reload()
return
}
if (resp.redirected) { if (resp.redirected) {
location.href = resp.url location.href = resp.url
return return

View File

@ -19,9 +19,18 @@
.datapoints { .datapoints {
font: "Roboto Mono", monospace; font: "Roboto Mono", monospace;
display: grid; display: grid;
grid-template-columns: min-content 1fr; grid-template-columns: min-content min-content 1fr;
gap: 6px 8px; gap: 6px 8px;
margin-bottom: 8px; margin-bottom: 8px;
white-space: nowrap;
.invalid {
color: #c83737;
}
.delete img {
height: 16px;
}
} }
.action { .action {

View File

@ -2,7 +2,7 @@
<script type="module" defer> <script type="module" defer>
import {UI, Trigger} from "/js/{{ .VERSION }}/trigger_edit.mjs" import {UI, Trigger} from "/js/{{ .VERSION }}/trigger_edit.mjs"
window._ui = new UI() window._ui = new UI({{ .VERSION }})
let trigger = new Trigger( let trigger = new Trigger(
{{ .Data.Trigger.ID }}, {{ .Data.Trigger.ID }},
'{{ .Data.Trigger.Name }}', '{{ .Data.Trigger.Name }}',
@ -29,8 +29,7 @@
<div class="label">Datapoints</div> <div class="label">Datapoints</div>
<div class="datapoints" style="margin-top: 4px"> <div class="datapoints" style="margin-top: 4px">
<div><a onclick="_ui.addDatapoint()">Add</a></div> <div style="grid-column: 1 / -1"><a onclick="_ui.addDatapoint()">Add</a></div>
<div></div>
</div> </div>
<div class="label">Expression</div> <div class="label">Expression</div>