diff --git a/api/globalconfig/types.go b/api/globalconfig/types.go index 3756f2f8c..4925bae63 100644 --- a/api/globalconfig/types.go +++ b/api/globalconfig/types.go @@ -18,6 +18,13 @@ import ( "github.com/evcc-io/evcc/util/modbus" ) +// ConfigStatus for publishing config, status and source to UI and external systems +type ConfigStatus struct { + Config any `json:"config,omitempty"` + Status any `json:"status,omitempty"` + FromYaml bool `json:"fromYaml,omitempty"` +} + type All struct { Network Network Ocpp ocpp.Config @@ -79,13 +86,6 @@ func (c Hems) Redacted() any { var _ api.Redactor = (*Mqtt)(nil) -func masked(s any) string { - if s != "" { - return "***" - } - return "" -} - type Mqtt struct { mqtt.Config `mapstructure:",squash"` Topic string `json:"topic"` @@ -97,12 +97,12 @@ func (m Mqtt) Redacted() any { Config: mqtt.Config{ Broker: m.Broker, User: m.User, - Password: masked(m.Password), + Password: util.Masked(m.Password), ClientID: m.ClientID, Insecure: m.Insecure, - CaCert: masked(m.CaCert), - ClientCert: masked(m.ClientCert), - ClientKey: masked(m.ClientKey), + CaCert: util.Masked(m.CaCert), + ClientCert: util.Masked(m.ClientCert), + ClientKey: util.Masked(m.ClientKey), }, Topic: m.Topic, } @@ -124,10 +124,10 @@ func (c Influx) Redacted() any { return Influx{ URL: c.URL, Database: c.Database, - Token: masked(c.Token), + Token: util.Masked(c.Token), Org: c.Org, User: c.User, - Password: masked(c.Password), + Password: util.Masked(c.Password), Insecure: c.Insecure, } } @@ -147,7 +147,7 @@ type MessagingEventTemplate struct { Title, Msg string } -func (c Messaging) Configured() bool { +func (c Messaging) IsConfigured() bool { return len(c.Services) > 0 || len(c.Events) > 0 } diff --git a/assets/js/components/Config/DeviceCard.vue b/assets/js/components/Config/DeviceCard.vue index 5c8eddbf4..aa8c030a8 100644 --- a/assets/js/components/Config/DeviceCard.vue +++ b/assets/js/components/Config/DeviceCard.vue @@ -6,9 +6,10 @@ 'round-box--error': error, 'round-box--warning': warning, 'root--unconfigured': unconfigured, + 'root--with-tags': $slots.tags, }" > -
+
@@ -33,8 +34,10 @@
-
- +
+
+ +
@@ -67,7 +70,7 @@ export default { } let title = `${this.$t("config.main.name")}: ${this.name}`; if (!this.editable) { - title += `
${this.$t("config.main.yaml")}
`; + title += `
${this.$t("config.general.fromYamlHint")}
`; } return `
${title}
`; }, @@ -105,6 +108,8 @@ export default { list-style-type: none; border-radius: 1rem; padding: 1rem 1.5rem; +} +.root--with-tags { min-height: 8rem; } .root--unconfigured { diff --git a/assets/js/components/Config/EebusModal.vue b/assets/js/components/Config/EebusModal.vue index d4e499669..ff7c48df5 100644 --- a/assets/js/components/Config/EebusModal.vue +++ b/assets/js/components/Config/EebusModal.vue @@ -1,26 +1,153 @@ - diff --git a/assets/js/components/Config/HemsModal.vue b/assets/js/components/Config/HemsModal.vue index cd293ef25..cab449f58 100644 --- a/assets/js/components/Config/HemsModal.vue +++ b/assets/js/components/Config/HemsModal.vue @@ -31,7 +31,7 @@

- {{ $t("config.hems.yamlConfigured") }} + {{ $t("config.general.fromYamlHint") }}

diff --git a/assets/js/components/Config/JsonModal.vue b/assets/js/components/Config/JsonModal.vue index e3338bf55..010028e01 100644 --- a/assets/js/components/Config/JsonModal.vue +++ b/assets/js/components/Config/JsonModal.vue @@ -88,6 +88,7 @@ export default { saveMethod: { type: String, default: "post" }, storeValuesInArray: Boolean, size: { type: String }, + confirmRemove: String, }, emits: ["changed", "open"], data() { @@ -121,7 +122,13 @@ export default { await this.load(); }, async load() { - this.serverValues = this.stateKey ? store.state[this.stateKey] : store.state; + if (this.stateKey) { + // Support nested keys like "eebus.config" + const keys = this.stateKey.split("."); + this.serverValues = keys.reduce((obj, key) => obj?.[key], store.state); + } else { + this.serverValues = store.state; + } if (this.transformReadValues) { this.serverValues = this.transformReadValues(this.serverValues); } @@ -155,6 +162,9 @@ export default { this.saving = false; }, async remove() { + if (this.confirmRemove && !window.confirm(this.confirmRemove)) { + return; + } this.removing = true; this.error = ""; try { diff --git a/assets/js/components/Config/PropertyCertField.vue b/assets/js/components/Config/PropertyCertField.vue index c71722301..df64a242d 100644 --- a/assets/js/components/Config/PropertyCertField.vue +++ b/assets/js/components/Config/PropertyCertField.vue @@ -1,6 +1,6 @@