#10 - Early config reload support, added benefit of cleaning up ActionButton.js early state code

This commit is contained in:
jamesread 2021-07-12 01:08:55 +01:00
parent 6c75d83280
commit 7dcc62ad1d
4 changed files with 46 additions and 26 deletions

View File

@ -10,6 +10,7 @@ import (
config "github.com/jamesread/OliveTin/internal/config" config "github.com/jamesread/OliveTin/internal/config"
"github.com/spf13/viper" "github.com/spf13/viper"
"github.com/fsnotify/fsnotify"
"os" "os"
) )
@ -43,16 +44,28 @@ func init() {
cfg = config.DefaultConfig() cfg = config.DefaultConfig()
if err := viper.UnmarshalExact(cfg); err != nil { reloadConfig();
log.Errorf("Config unmarshal error %+v", err)
os.Exit(1)
}
if logLevel, err := log.ParseLevel(cfg.LogLevel); err == nil { if logLevel, err := log.ParseLevel(cfg.LogLevel); err == nil {
log.SetLevel(logLevel) log.SetLevel(logLevel)
} }
viper.WatchConfig() viper.WatchConfig()
viper.OnConfigChange(func(e fsnotify.Event) {
if e.Op == fsnotify.Write {
log.Info("Config file changed:", e.String())
reloadConfig();
}
})
}
func reloadConfig() {
if err := viper.UnmarshalExact(&cfg); err != nil {
log.Errorf("Config unmarshal error %+v", err)
os.Exit(1)
}
} }
func main() { func main() {

1
go.mod
View File

@ -4,6 +4,7 @@ go 1.15
require ( require (
github.com/denisbrodbeck/machineid v1.0.1 // indirect github.com/denisbrodbeck/machineid v1.0.1 // indirect
github.com/fsnotify/fsnotify v1.4.9 // indirect
github.com/go-co-op/gocron v1.6.2 // indirect github.com/go-co-op/gocron v1.6.2 // indirect
github.com/grpc-ecosystem/grpc-gateway/v2 v2.4.0 github.com/grpc-ecosystem/grpc-gateway/v2 v2.4.0
github.com/sirupsen/logrus v1.8.1 github.com/sirupsen/logrus v1.8.1

View File

@ -1,29 +1,35 @@
class ActionButton extends window.HTMLButtonElement { class ActionButton extends window.HTMLButtonElement {
constructFromJson (json) { constructFromJson (json) {
this.updateIterationTimestamp = 0;
this.title = json.title this.title = json.title
this.states = []
this.stateLabels = []
this.temporaryStatusMessage = null this.temporaryStatusMessage = null
this.currentState = 0
this.isWaiting = false this.isWaiting = false
this.actionCallUrl = window.restBaseUrl + 'StartAction?actionName=' + this.title this.actionCallUrl = window.restBaseUrl + 'StartAction?actionName=' + this.title
if (json.icon === '') { this.updateFromJson(json)
this.unicodeIcon = '&#x1f4a9'
} else {
this.unicodeIcon = unescape(json.icon)
}
this.onclick = () => { this.startAction() } this.onclick = () => { this.startAction() }
this.constructTemplate() this.constructTemplate()
this.updateHtml() this.updateHtml()
this.setAttribute("id", "actionButton_" + json.id) this.setAttribute("id", "actionButton_" + json.id)
} }
updateFromJson (json) { updateFromJson (json) {
console.log("updating button") // Fields that should not be updated
//
// title - as the callback URL relies on it
// actionCallbackUrl - as it's based on the title
// temporaryStatusMessage - as the button might be "waiting" on execution to finish while it's being updated.
if (json.icon === '') {
this.unicodeIcon = '&#x1f4a9'
} else {
this.unicodeIcon = unescape(json.icon)
}
} }
startAction () { startAction () {
@ -73,7 +79,6 @@ class ActionButton extends window.HTMLButtonElement {
this.domTitle = this.querySelector('.title') this.domTitle = this.querySelector('.title')
this.domIcon = this.querySelector('.icon') this.domIcon = this.querySelector('.icon')
} }
updateHtml () { updateHtml () {
@ -96,18 +101,6 @@ class ActionButton extends window.HTMLButtonElement {
this.domIcon.innerHTML = this.unicodeIcon this.domIcon.innerHTML = this.unicodeIcon
} }
getCurrentStateLabel (useLabels = true) {
if (useLabels) {
return this.stateLabels[this.currentState]
} else {
return this.states[this.currentState]
}
}
getNextStateLabel () {
return this.stateLabels[this.currentState + 1]
}
} }
window.customElements.define('action-button', ActionButton, { extends: 'button' }) window.customElements.define('action-button', ActionButton, { extends: 'button' })

View File

@ -1,15 +1,28 @@
import './ActionButton.js' // To define action-button import './ActionButton.js' // To define action-button
export function marshalActionButtonsJsonToHtml (json) { export function marshalActionButtonsJsonToHtml (json) {
const currentIterationTimestamp = Date.now()
for (const jsonButton of json.actions) { for (const jsonButton of json.actions) {
var htmlButton = document.querySelector('#actionButton_' + jsonButton.id) var htmlButton = document.querySelector('#actionButton_' + jsonButton.id)
if (htmlButton == null) { if (htmlButton == null) {
htmlButton = document.createElement('button', { is: 'action-button' }) htmlButton = document.createElement('button', { is: 'action-button' })
htmlButton.constructFromJson(jsonButton) htmlButton.constructFromJson(jsonButton)
document.getElementById('rootGroup').appendChild(htmlButton) document.getElementById('rootGroup').appendChild(htmlButton)
} else { } else {
htmlButton.updateFromJson(jsonButton) htmlButton.updateFromJson(jsonButton)
htmlButton.updateHtml()
}
console.log("action", jsonButton.title)
htmlButton.updateIterationTimestamp = currentIterationTimestamp;
}
for (const existingButton of document.querySelectorAll('button')) {
if (existingButton.updateIterationTimestamp != currentIterationTimestamp) {
existingButton.remove();
} }
} }
} }