Skip to content
Open
Show file tree
Hide file tree
Changes from 31 commits
Commits
Show all changes
33 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
40 changes: 26 additions & 14 deletions api/globalconfig/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,25 @@ import (
"github.com/evcc-io/evcc/util/modbus"
)

// Info for publishing config, status and source to UI and external systems
type Info struct {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we find a better name? Info is as arbitrary as it gets.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

\cc @naltatis

Config any `json:"config,omitempty"`
Status any `json:"status,omitempty"`
FromYaml bool `json:"fromYaml,omitempty"`
}

func (i Info) Redacted() any {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Die redacted Methode gehΓΆrt nicht auf das Info

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wie bin ich dann in der Lage darunterliegende Structs wie hier EEBus zu redacten?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Genau wie jetzt auch oder vorher.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Info ist ein Wrapper für die Structs wie EEBus, das gabs vorher so noch nicht, soweit ich weiß.
Ich finde zumindest kein Muster im aktuellen Backend Code, wie ich EEBus ansonsten redacten kann?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Siehe letzter Commit- einfach verschoben. Was mir noch auffΓ€llt: bei Sponsor redacten wir Status, sonst Config. Ist das Objekt bei Sponsor an der richtigen Stelle?

r, ok := i.Config.(api.Redactor)
if !ok {
return i
}
return Info{
Config: r.Redacted(),
Status: i.Status,
FromYaml: i.FromYaml,
}
}

type All struct {
Network Network
Ocpp ocpp.Config
Expand Down Expand Up @@ -79,13 +98,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"`
Expand All @@ -97,12 +109,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,
}
Expand All @@ -124,10 +136,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,
}
}
Expand All @@ -147,7 +159,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
}

Expand Down
12 changes: 9 additions & 3 deletions assets/js/components/Config/DeviceCard.vue
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,10 @@
'round-box--error': error,
'round-box--warning': warning,
'root--unconfigured': unconfigured,
'root--with-tags': !hideTags,
}"
>
<div class="d-flex align-items-center mb-2">
<div class="d-flex align-items-center" :class="{ 'mb-2': !hideTags }">
<div class="icon me-2">
<slot name="icon" />
</div>
Expand All @@ -33,8 +34,10 @@
<shopicon-regular-adjust size="s"></shopicon-regular-adjust>
</button>
</div>
<hr class="my-3 divide" />
<slot name="tags" />
<div v-if="!hideTags">
<hr class="my-3 divide" />
<slot name="tags" />
</div>
</div>
</template>

Expand All @@ -53,6 +56,7 @@ export default {
unconfigured: Boolean,
warning: Boolean,
noEditButton: Boolean,
hideTags: Boolean,
},
emits: ["edit"],
data() {
Expand Down Expand Up @@ -105,6 +109,8 @@ export default {
list-style-type: none;
border-radius: 1rem;
padding: 1rem 1.5rem;
}
.root--with-tags {
min-height: 8rem;
}
.root--unconfigured {
Expand Down
146 changes: 136 additions & 10 deletions assets/js/components/Config/EebusModal.vue
Original file line number Diff line number Diff line change
@@ -1,26 +1,152 @@
<template>
<YamlModal
<JsonModal
id="eebusModal"
:title="$t('config.eebus.title')"
:description="$t('config.eebus.description')"
docs="/docs/reference/configuration/eebus"
:defaultYaml="defaultYaml"
removeKey="eebus"
endpoint="/config/eebus"
state-key="eebus.config"
data-testid="eebus-modal"
:disable-remove="fromYaml"
:disable-save="fromYaml"
:confirm-remove="$t('config.eebus.removeConfirm')"
@changed="$emit('changed')"
/>
>
<template #default="{ values }: { values: EebusConfig }">
<p v-if="fromYaml" class="text-muted">
{{ $t("config.main.yaml") }}
</p>
<FormRow
v-if="values.shipid"
:id="formId('shipid-display')"
:label="$t('config.eebus.shipid')"
:help="$t('config.eebus.shipidExplain')"
>
<input
:id="formId('shipid-display')"
:value="values.shipid"
readonly
class="form-control text-muted"
/>
</FormRow>
<FormRow
v-if="status.ski"
:id="formId('ski-display')"
:label="$t('config.eebus.ski')"
:help="$t('config.eebus.skiExplain')"
>
<input
:id="formId('ski-display')"
:value="status.ski"
readonly
class="form-control text-muted"
/>
</FormRow>
<PropertyCollapsible v-if="!fromYaml">
<template #advanced>
<div class="alert alert-danger">
{{ $t("config.eebus.descriptionAdvanced") }}
</div>
<FormRow
:id="formId('shipid')"
:label="$t('config.eebus.shipid')"
:help="$t('config.eebus.shipidHelp')"
optional
>
<PropertyField
:id="formId('shipid')"
v-model="values.shipid"
type="String"
/>
</FormRow>
<FormRow
:id="formId('port')"
:label="$t('config.eebus.port')"
:help="$t('config.eebus.portHelp')"
optional
>
<PropertyField
:id="formId('port')"
v-model="values.port"
property="port"
type="Int"
/>
</FormRow>
<FormRow
:id="formId('interfaces')"
:label="$t('config.eebus.interfaces')"
:help="$t('config.eebus.interfacesHelp')"
optional
example="eth0"
>
<PropertyField
:id="formId('interfaces')"
v-model="values.interfaces"
type="List"
/>
</FormRow>
<h6>{{ $t("config.eebus.certificate.title") }}</h6>
<FormRow
:id="formId('certificate-public')"
:label="$t('config.eebus.certificate.public')"
>
<PropertyCertField
:id="formId('certificate-public')"
:model-value="values.certificate?.public"
@update:model-value="
values.certificate ? (values.certificate.public = $event) : ''
"
/>
</FormRow>
<FormRow
:id="formId('certificate-private')"
:label="$t('config.eebus.certificate.private')"
>
<PropertyCertField
:id="formId('certificate-private')"
:model-value="values.certificate?.private"
@update:model-value="
values.certificate ? (values.certificate.private = $event) : ''
"
/>
</FormRow>
</template>
</PropertyCollapsible>
</template>
</JsonModal>
</template>

<script>
import YamlModal from "./YamlModal.vue";
import defaultYaml from "./defaultYaml/eebus.yaml?raw";
<script lang="ts">
import type { PropType } from "vue";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
import type { EebusConfig, EebusStatus } from "@/types/evcc";
import JsonModal from "./JsonModal.vue";
import FormRow from "./FormRow.vue";
import PropertyField from "./PropertyField.vue";
import PropertyCertField from "./PropertyCertField.vue";
import PropertyCollapsible from "./PropertyCollapsible.vue";

export default {
name: "EebusModal",
components: { YamlModal },
components: {
JsonModal,
FormRow,
PropertyField,
PropertyCertField,
PropertyCollapsible,
},
props: {
status: {
type: Object as PropType<EebusStatus>,
default: () => ({}),
},
fromYaml: Boolean,
},
emits: ["changed"],
data() {
return { defaultYaml: defaultYaml.trim() };
methods: {
formId(s: string) {
return `eebus-${s}`;
},
},
};
</script>
2 changes: 1 addition & 1 deletion assets/js/components/Config/HemsModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
</a>
</div>
<p v-if="fromYaml" class="text-muted">
{{ $t("config.hems.yamlConfigured") }}
{{ $t("config.main.yaml") }}
</p>
</template>
</YamlModal>
Expand Down
14 changes: 13 additions & 1 deletion assets/js/components/Config/JsonModal.vue
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
</div>

<button
v-if="!disableSave"
type="submit"
class="btn btn-primary order-1 order-sm-2 flex-grow-1 flex-sm-grow-0 px-4"
:disabled="saving || nothingChanged"
Expand Down Expand Up @@ -81,13 +82,15 @@ export default {
endpoint: String,
disableCancel: Boolean,
disableRemove: Boolean,
disableSave: Boolean,
noButtons: Boolean,
transformReadValues: Function,
transformWriteValues: Function,
stateKey: String,
saveMethod: { type: String, default: "post" },
storeValuesInArray: Boolean,
size: { type: String },
confirmRemove: String,
},
emits: ["changed", "open"],
data() {
Expand Down Expand Up @@ -121,7 +124,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);
}
Expand Down Expand Up @@ -155,6 +164,9 @@ export default {
this.saving = false;
},
async remove() {
if (this.confirmRemove && !window.confirm(this.confirmRemove)) {
return;
}
this.removing = true;
this.error = "";
try {
Expand Down
4 changes: 3 additions & 1 deletion assets/js/components/Config/PropertyField.vue
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,9 @@ export default {
return this.property === "icon";
},
textarea() {
return ["accessToken", "refreshToken", "identifiers"].includes(this.property);
return (
this.array || ["accessToken", "refreshToken", "identifiers"].includes(this.property)
);
},
boolean() {
return this.type === "Bool";
Expand Down
12 changes: 0 additions & 12 deletions assets/js/components/Config/defaultYaml/eebus.yaml

This file was deleted.

Loading
Loading