diff --git a/api/api.go b/api/api.go index cb3680ac1..d92a7e65b 100644 --- a/api/api.go +++ b/api/api.go @@ -291,3 +291,8 @@ type Circuit interface { type Redactor interface { Redacted() any } + +// Messenger implements message sending +type Messenger interface { + Send(title, msg string) +} diff --git a/api/globalconfig/types.go b/api/globalconfig/types.go index 036670214..ab7fda8a8 100644 --- a/api/globalconfig/types.go +++ b/api/globalconfig/types.go @@ -34,34 +34,35 @@ const ( ) type All struct { - Network Network - Ocpp ocpp.Config - Log string - SponsorToken string - Plant string // telemetry plant id - Telemetry bool - Mcp bool - Metrics bool - Profile bool - Levels map[string]string - Interval time.Duration - Database DB - Mqtt Mqtt - ModbusProxy []ModbusProxy - Javascript []Javascript - Go []Go - Influx Influx - EEBus eebus.Config - HEMS Hems - SHM shm.Config - Messaging Messaging - Meters []config.Named - Chargers []config.Named - Vehicles []config.Named - Tariffs Tariffs - Site map[string]any - Loadpoints []config.Named - Circuits []config.Named + Network Network + Ocpp ocpp.Config + Log string + SponsorToken string + Plant string // telemetry plant id + Telemetry bool + Mcp bool + Metrics bool + Profile bool + Levels map[string]string + Interval time.Duration + Database DB + Mqtt Mqtt + ModbusProxy []ModbusProxy + Javascript []Javascript + Go []Go + Influx Influx + EEBus eebus.Config + HEMS Hems + SHM shm.Config + Messaging Messaging + MessagingEvents MessagingEvents + Meters []config.Named + Chargers []config.Named + Vehicles []config.Named + Tariffs Tariffs + Site map[string]any + Loadpoints []config.Named + Circuits []config.Named } type Javascript struct { @@ -146,13 +147,17 @@ type DB struct { } type Messaging struct { - Events map[string]MessagingEventTemplate + Events MessagingEvents Services []config.Typed } +type MessagingEvents = map[string]MessagingEventTemplate + // MessagingEventTemplate is the push message configuration for an event type MessagingEventTemplate struct { - Title, Msg string + Title string `json:"title"` + Msg string `json:"msg"` + Disabled bool `json:"disabled"` } func (c Messaging) IsConfigured() bool { diff --git a/assets/css/app.css b/assets/css/app.css index 67befbf26..9a586c4e0 100644 --- a/assets/css/app.css +++ b/assets/css/app.css @@ -773,3 +773,26 @@ input::-webkit-date-and-time-value { .tabular { font-variant-numeric: tabular-nums; } + +/* Collapsible wrapper pattern with choreographed animation */ +.collapsible-wrapper { + display: grid; + grid-template-rows: 0fr; + transition: grid-template-rows var(--evcc-transition-fast) ease 0.2s; +} + +.collapsible-wrapper.open { + grid-template-rows: 1fr; + transition: grid-template-rows var(--evcc-transition-fast) ease; +} + +.collapsible-content { + overflow: hidden; + opacity: 0; + transition: opacity 0.2s ease; +} + +.collapsible-wrapper.open .collapsible-content { + opacity: 1; + transition: opacity var(--evcc-transition-fast) ease 0.2s; +} diff --git a/assets/js/components/ChargingPlans/PlanStrategy.vue b/assets/js/components/ChargingPlans/PlanStrategy.vue index 0c1f5918a..a8014a76b 100644 --- a/assets/js/components/ChargingPlans/PlanStrategy.vue +++ b/assets/js/components/ChargingPlans/PlanStrategy.vue @@ -1,6 +1,6 @@ @@ -129,15 +80,8 @@ export default { .icon:empty { display: none; } -.edit-button { - /* transparent button, right align icon */ - margin-right: -0.5rem; -} .divide { margin-left: -1.5rem; margin-right: -1.5rem; } -button:disabled { - pointer-events: auto; -} diff --git a/assets/js/components/Config/DeviceCardEditIcon.vue b/assets/js/components/Config/DeviceCardEditIcon.vue new file mode 100644 index 000000000..bcca7ab14 --- /dev/null +++ b/assets/js/components/Config/DeviceCardEditIcon.vue @@ -0,0 +1,84 @@ + + + + + diff --git a/assets/js/components/Config/DeviceModal/Actions.vue b/assets/js/components/Config/DeviceModal/Actions.vue index 3ee0ca369..57e877a89 100644 --- a/assets/js/components/Config/DeviceModal/Actions.vue +++ b/assets/js/components/Config/DeviceModal/Actions.vue @@ -7,7 +7,7 @@ @test="$emit('test')" /> -
+
+ +
+ + + + + diff --git a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue index 9d617f5db..4651ae2dc 100644 --- a/assets/js/components/Config/DeviceModal/DeviceModalBase.vue +++ b/assets/js/components/Config/DeviceModal/DeviceModalBase.vue @@ -10,6 +10,9 @@ @close="handleClose" @visibilitychange="handleVisibilityChange" > +
@@ -167,6 +170,7 @@ + + diff --git a/assets/js/components/Config/Messaging/MessagingLegacyModal.vue b/assets/js/components/Config/Messaging/MessagingLegacyModal.vue new file mode 100644 index 000000000..4fccb7818 --- /dev/null +++ b/assets/js/components/Config/Messaging/MessagingLegacyModal.vue @@ -0,0 +1,34 @@ + + + diff --git a/assets/js/components/Config/Messaging/MessagingModal.vue b/assets/js/components/Config/Messaging/MessagingModal.vue new file mode 100644 index 000000000..815c0d8b6 --- /dev/null +++ b/assets/js/components/Config/Messaging/MessagingModal.vue @@ -0,0 +1,172 @@ + + + diff --git a/assets/js/components/Config/Messaging/MessengerModal.vue b/assets/js/components/Config/Messaging/MessengerModal.vue new file mode 100644 index 000000000..641060c4a --- /dev/null +++ b/assets/js/components/Config/Messaging/MessengerModal.vue @@ -0,0 +1,74 @@ + + + diff --git a/assets/js/components/Config/Messaging/utils.ts b/assets/js/components/Config/Messaging/utils.ts new file mode 100644 index 000000000..9996d36f8 --- /dev/null +++ b/assets/js/components/Config/Messaging/utils.ts @@ -0,0 +1,3 @@ +export function capitalize(str: string): string { + return str.charAt(0).toUpperCase() + str.slice(1); +} diff --git a/assets/js/components/Config/MessagingModal.vue b/assets/js/components/Config/MessagingModal.vue deleted file mode 100644 index 69dcaa7f6..000000000 --- a/assets/js/components/Config/MessagingModal.vue +++ /dev/null @@ -1,26 +0,0 @@ - - - diff --git a/assets/js/components/Config/PropertyField.vue b/assets/js/components/Config/PropertyField.vue index abaa81940..7398c52ae 100644 --- a/assets/js/components/Config/PropertyField.vue +++ b/assets/js/components/Config/PropertyField.vue @@ -13,6 +13,7 @@ :class="selectMode ? 'btn-check' : 'd-none'" :name="property" :value="key" + :disabled="disabled" @click="toggleSelectMode" />