From d9628fd9a203ab882b520e1191cb02282721eb0c Mon Sep 17 00:00:00 2001 From: Charles Garwood Date: Thu, 1 Aug 2019 11:32:20 -0400 Subject: [PATCH 1/7] Convert zwave-node-config to lit/ts (#3434) * Convert zwave-node-config to lit/ts * Add translations * lint round 1 * lint round 2 * . all the properties and fix missing types * Clean up bad prettier auto-style * set header property instead of attribute --- src/data/zwave.ts | 31 ++ src/panels/config/zwave/zwave-node-config.js | 377 ------------------ src/panels/config/zwave/zwave-node-config.ts | 388 +++++++++++++++++++ src/translations/en.json | 14 +- 4 files changed, 432 insertions(+), 378 deletions(-) delete mode 100644 src/panels/config/zwave/zwave-node-config.js create mode 100644 src/panels/config/zwave/zwave-node-config.ts diff --git a/src/data/zwave.ts b/src/data/zwave.ts index 8ca10a78ca..f41567edbc 100644 --- a/src/data/zwave.ts +++ b/src/data/zwave.ts @@ -11,6 +11,34 @@ export interface ZWaveValue { poll_intensity: number; } +export interface ZWaveConfigItem { + key: number; + value: { + data: any; + data_items: any[]; + help: string; + label: string; + max: number; + min: number; + type: string; + }; +} + +export interface ZWaveConfigServiceData { + node_id: number; + parameter: number; + value: number | string; +} + +export interface ZWaveNode { + attributes: ZWaveAttributes; +} + +export interface ZWaveAttributes { + node_id: number; + wake_up_interval?: number; +} + export const ZWAVE_NETWORK_STATE_STOPPED = 0; export const ZWAVE_NETWORK_STATE_FAILED = 1; export const ZWAVE_NETWORK_STATE_STARTED = 5; @@ -26,3 +54,6 @@ export const fetchNetworkStatus = ( export const fetchValues = (hass: HomeAssistant, nodeId: number) => hass.callApi("GET", `zwave/values/${nodeId}`); + +export const fetchNodeConfig = (hass: HomeAssistant, nodeId: number) => + hass.callApi("GET", `zwave/config/${nodeId}`); diff --git a/src/panels/config/zwave/zwave-node-config.js b/src/panels/config/zwave/zwave-node-config.js deleted file mode 100644 index 054cbf0b91..0000000000 --- a/src/panels/config/zwave/zwave-node-config.js +++ /dev/null @@ -1,377 +0,0 @@ -import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; -import "@polymer/paper-input/paper-input"; -import "@polymer/paper-item/paper-item"; -import "@polymer/paper-listbox/paper-listbox"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../../../components/buttons/ha-call-service-button"; -import "../../../components/ha-card"; - -class ZwaveNodeConfig extends PolymerElement { - static get template() { - return html` - -
- - -
- - - - - -
- - - - -
[[_configValueHelpText]]
- -
-
- `; - } - - static get properties() { - return { - hass: Object, - - nodes: Array, - - selectedNode: { - type: Number, - observer: "_nodesChanged", - }, - - config: { - type: Array, - value: () => [], - }, - - _selectedConfigParameter: { - type: Number, - value: -1, - observer: "_selectedConfigParameterChanged", - }, - - _configParameterMax: { - type: Number, - value: -1, - }, - - _configParameterMin: { - type: Number, - value: -1, - }, - - _configValueHelpText: { - type: String, - value: "", - computed: "_computeConfigValueHelp(_selectedConfigParameter)", - }, - - _selectedConfigParameterType: { - type: String, - value: "", - }, - - _selectedConfigValue: { - type: Number, - value: -1, - observer: "_computeSetConfigParameterServiceData", - }, - - _selectedConfigParameterValues: { - type: Array, - value: () => [], - }, - - _selectedConfigParameterNumValues: { - type: String, - value: "", - }, - - _loadedConfigValue: { - type: Number, - value: -1, - }, - - _wakeupInput: Number, - - _wakeupNode: { - type: Boolean, - value: false, - }, - }; - } - - ready() { - super.ready(); - this.addEventListener("hass-service-called", (ev) => - this.serviceCalled(ev) - ); - } - - serviceCalled(ev) { - if (ev.detail.success) { - setTimeout(() => { - this._refreshConfig(this.selectedNode); - }, 5000); - } - } - - _nodesChanged() { - if (!this.nodes) return; - this.setProperties({ _selectedConfigParameter: -1 }); - this._wakeupNode = - this.nodes[this.selectedNode].attributes.wake_up_interval === 0 || - this.nodes[this.selectedNode].attributes.wake_up_interval; - if (this._wakeupNode) { - if (this.nodes[this.selectedNode].attributes.wake_up_interval === 0) - this.setProperties({ _wakeupInput: "" }); - else { - this.setProperties({ - _wakeupInput: this.nodes[this.selectedNode].attributes - .wake_up_interval, - }); - } - } - } - - _computeGetWakeupValue(selectedNode) { - if ( - this.selectedNode === -1 || - !this.nodes[selectedNode].attributes.wake_up_interval - ) - return "unknown"; - return this.nodes[selectedNode].attributes.wake_up_interval; - } - - _computeWakeupServiceData(wakeupInput) { - return { - node_id: this.nodes[this.selectedNode].attributes.node_id, - value: wakeupInput, - }; - } - - _computeConfigValueHelp(selectedConfigParameter) { - if (selectedConfigParameter === -1) return ""; - const helpText = this.config[selectedConfigParameter].value.help; - if (!helpText) return ["No helptext available"]; - return helpText; - } - - _computeSetConfigParameterServiceData(selectedConfigValue) { - if (this.selectedNode === -1 || this._selectedConfigParameter === -1) - return -1; - var valueData = null; - if ("Short Byte Int".includes(this._selectedConfigParameterType)) { - valueData = parseInt(selectedConfigValue, 10); - } - if ("Bool Button List".includes(this._selectedConfigParameterType)) { - valueData = this._selectedConfigParameterValues[selectedConfigValue]; - } - return { - node_id: this.nodes[this.selectedNode].attributes.node_id, - parameter: this.config[this._selectedConfigParameter].key, - value: valueData, - }; - } - - _selectedConfigParameterChanged(selectedConfigParameter) { - if (selectedConfigParameter === -1) return; - this.setProperties({ - _selectedConfigValue: -1, - _loadedConfigValue: -1, - _selectedConfigParameterValues: [], - }); - this.setProperties({ - _selectedConfigParameterType: this.config[selectedConfigParameter].value - .type, - _configParameterMax: this.config[selectedConfigParameter].value.max, - _configParameterMin: this.config[selectedConfigParameter].value.min, - _loadedConfigValue: this.config[selectedConfigParameter].value.data, - _configValueHelpText: this.config[selectedConfigParameter].value.help, - }); - if ("Short Byte Int".includes(this._selectedConfigParameterType)) { - this.setProperties({ - _selectedConfigParameterNumValues: this.config[selectedConfigParameter] - .value.data_items, - _selectedConfigValue: this._loadedConfigValue, - }); - } - if ("Bool Button".includes(this._selectedConfigParameterType)) { - this.setProperties({ _selectedConfigParameterValues: ["True", "False"] }); - if (this.config[selectedConfigParameter].value.data) { - this.setProperties({ _loadedConfigValue: "True" }); - } else this.setProperties({ _loadedConfigValue: "False" }); - } - if ("List".includes(this._selectedConfigParameterType)) { - this.setProperties({ - _selectedConfigParameterValues: this.config[selectedConfigParameter] - .value.data_items, - }); - } - } - - _isConfigParameterSelected(selectedConfigParameter, type) { - if (selectedConfigParameter === -1) return false; - if (this.config[selectedConfigParameter].value.type === type) return true; - if (type.includes(this.config[selectedConfigParameter].value.type)) - return true; - return false; - } - - _computeSelectCaptionConfigParameter(stateObj) { - return `${stateObj.key}: ${stateObj.value.label}`; - } - - async _refreshConfig(selectedNode) { - const configData = []; - const config = await this.hass.callApi( - "GET", - `zwave/config/${this.nodes[selectedNode].attributes.node_id}` - ); - Object.keys(config).forEach((key) => { - configData.push({ - key: key, - value: config[key], - }); - }); - this.setProperties({ config: configData }); - this._selectedConfigParameterChanged(this._selectedConfigParameter); - } -} - -customElements.define("zwave-node-config", ZwaveNodeConfig); diff --git a/src/panels/config/zwave/zwave-node-config.ts b/src/panels/config/zwave/zwave-node-config.ts new file mode 100644 index 0000000000..ed0dab5edd --- /dev/null +++ b/src/panels/config/zwave/zwave-node-config.ts @@ -0,0 +1,388 @@ +import "@polymer/paper-dropdown-menu/paper-dropdown-menu"; +import "@polymer/paper-input/paper-input"; +import "@polymer/paper-item/paper-item"; +import "@polymer/paper-listbox/paper-listbox"; + +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, + PropertyValues, +} from "lit-element"; + +import { haStyle } from "../../../resources/styles"; +import { HomeAssistant } from "../../../types"; + +import "../../../components/buttons/ha-call-service-button"; +import "../../../components/ha-card"; +import { + ZWaveConfigItem, + ZWaveNode, + ZWaveConfigServiceData, + fetchNodeConfig, +} from "../../../data/zwave"; + +@customElement("zwave-node-config") +export class ZwaveNodeConfig extends LitElement { + @property() public hass!: HomeAssistant; + @property() public nodes: ZWaveNode[] = []; + @property() public config: ZWaveConfigItem[] = []; + @property() public selectedNode: number = -1; + @property() private _configItem?: ZWaveConfigItem; + @property() private _wakeupInput: number = -1; + @property() private _selectedConfigParameter: number = -1; + @property() private _selectedConfigValue: number | string = -1; + + protected render(): TemplateResult | void { + return html` +
+ + ${"wake_up_interval" in this.nodes[this.selectedNode].attributes + ? html` +
+ +
+ ${this.hass!.localize( + "ui.panel.config.zwave.node_config.seconds" + )} +
+
+ + ${this.hass!.localize( + "ui.panel.config.zwave.node_config.set_wakeup" + )} + +
+ ` + : ""} +
+ + + ${this.config.map( + (state) => html` + + ${state.key}: ${state.value.label} + + ` + )} + + +
+ ${this._configItem + ? html` + ${this._configItem.value.type === "List" + ? html` +
+ + + ${this._configItem.value.data_items.map( + (state) => html` + ${state} + ` + )} + + +
+ ` + : ""} + ${["Byte", "Short", "Int"].includes(this._configItem.value.type) + ? html` +
+ + +
+ ` + : ""} + ${["Bool", "Button"].includes(this._configItem.value.type) + ? html` +
+ + + + ${this.hass!.localize( + "ui.panel.config.zwave.node_config.true" + )} + + + ${this.hass!.localize( + "ui.panel.config.zwave.node_config.false" + )} + + + +
+ ` + : ""} +
+ ${this._configItem.value.help} +
+ ${["Bool", "Button", "Byte", "Short", "Int", "List"].includes( + this._configItem.value.type + ) + ? html` +
+ + ${this.hass!.localize( + "ui.panel.config.zwave.node_config.set_config_parameter" + )} + +
+ ` + : ""} + ` + : ""} +
+
+ `; + } + + static get styles(): CSSResult[] { + return [ + haStyle, + css` + .content { + margin-top: 24px; + } + + ha-card { + margin: 0 auto; + max-width: 600px; + } + + .device-picker { + @apply --layout-horizontal; + @apply --layout-center-center; + display: -ms-flexbox; + display: -webkit-flex; + display: flex; + -ms-flex-direction: row; + -webkit-flex-direction: row; + flex-direction: row; + -ms-flex-align: center; + -webkit-align-items: center; + align-items: center; + padding-left: 24px; + padding-right: 24px; + padding-bottom: 24px; + } + + .help-text { + padding-left: 24px; + padding-right: 24px; + } + + .flex { + -ms-flex: 1 1 0.000000001px; + -webkit-flex: 1; + flex: 1; + -webkit-flex-basis: 0.000000001px; + flex-basis: 0.000000001px; + } + `, + ]; + } + + protected firstUpdated(changedProps: PropertyValues): void { + super.firstUpdated(changedProps); + this.addEventListener("hass-service-called", (ev) => + this.serviceCalled(ev) + ); + } + + protected updated(changedProps: PropertyValues): void { + super.updated(changedProps); + if (changedProps.has("selectedNode")) { + this._nodesChanged(); + } + } + + private serviceCalled(ev): void { + if (ev.detail.success) { + setTimeout(() => { + this._refreshConfig(this.selectedNode); + }, 5000); + } + } + + private _nodesChanged(): void { + if (!this.nodes) { + return; + } + this._configItem = undefined; + this._wakeupInput = this.nodes[this.selectedNode].attributes.hasOwnProperty( + "wake_up_interval" + ) + ? this.nodes[this.selectedNode].attributes.wake_up_interval! + : -1; + } + + private _onWakeupIntervalChanged(value: ChangeEvent): void { + this._wakeupInput = value.detail!.value; + } + + private _computeWakeupServiceData(wakeupInput: number) { + return { + node_id: this.nodes[this.selectedNode].attributes.node_id, + value: wakeupInput, + }; + } + + private _computeSetConfigParameterServiceData(): + | ZWaveConfigServiceData + | boolean { + if (this.selectedNode === -1 || typeof this._configItem === "undefined") { + return false; + } + let valueData: number | string = ""; + if (["Short", "Byte", "Int"].includes(this._configItem!.value.type)) { + valueData = + typeof this._selectedConfigValue === "string" + ? parseInt(this._selectedConfigValue, 10) + : this._selectedConfigValue; + } + if (["Bool", "Button", "List"].includes(this._configItem!.value.type)) { + valueData = this._selectedConfigValue; + } + return { + node_id: this.nodes[this.selectedNode].attributes.node_id, + parameter: this._configItem.key, + value: valueData, + }; + } + + private _selectedConfigParameterChanged(event: ItemSelectedEvent): void { + if (event.target!.selected === -1) { + return; + } + this._selectedConfigParameter = event.target!.selected; + this._configItem = this.config[event.target!.selected]; + } + + private _configValueSelectChanged(event: ItemSelectedEvent): void { + if (event.target!.selected === -1) { + return; + } + this._selectedConfigValue = event.target!.selectedItem.textContent; + } + + private _configValueInputChanged(value: ChangeEvent): void { + this._selectedConfigValue = value.detail!.value; + } + + private async _refreshConfig(selectedNode): Promise { + const configData: ZWaveConfigItem[] = []; + const config = await fetchNodeConfig( + this.hass, + this.nodes[selectedNode].attributes.node_id + ); + + Object.keys(config).forEach((key) => { + configData.push({ + key: parseInt(key, 10), + value: config[key], + }); + }); + + this.config = configData; + this._configItem = this.config[this._selectedConfigParameter]; + } +} + +export interface ChangeEvent { + detail?: { + value?: any; + }; + target?: EventTarget; +} + +export interface PickerTarget extends EventTarget { + selected: number; + selectedItem?: any; +} + +export interface ItemSelectedEvent { + target?: PickerTarget; +} + +declare global { + interface HTMLElementTagNameMap { + "zwave-node-config": ZwaveNodeConfig; + } +} diff --git a/src/translations/en.json b/src/translations/en.json index de90e209c3..611cbedfc2 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -932,7 +932,9 @@ "common": { "value": "Value", "instance": "Instance", - "index": "Index" + "index": "Index", + "unknown": "unknown", + "wakeup_interval": "Wakeup Interval" }, "network_management": { "header": "Z-Wave Network Management", @@ -946,6 +948,16 @@ "network_started_note_some_queried": "Awake nodes have been queried. Sleeping nodes will be queried when they wake.", "network_started_note_all_queried": "All nodes have been queried." }, + "node_config": { + "header": "Node Config Options", + "seconds": "seconds", + "set_wakeup": "Set Wakeup Interval", + "config_parameter": "Config Parameter", + "config_value": "Config Value", + "true": "True", + "false": "False", + "set_config_parameter": "Set Config Parameter" + }, "values": { "header": "Node Values" }, From b9afa69ee5cfcf14b5422fbe30e4e0603a106aac Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 09:02:20 -0700 Subject: [PATCH 2/7] Handle unavailable climate (#3446) --- src/panels/lovelace/cards/hui-thermostat-card.ts | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/src/panels/lovelace/cards/hui-thermostat-card.ts b/src/panels/lovelace/cards/hui-thermostat-card.ts index 73b1d853f0..0070de8d0d 100644 --- a/src/panels/lovelace/cards/hui-thermostat-card.ts +++ b/src/panels/lovelace/cards/hui-thermostat-card.ts @@ -169,7 +169,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { : ""}
- ${stateObj.attributes.hvac_modes + ${(stateObj.attributes.hvac_modes || []) .concat() .sort(compareClimateHvacModes) .map((modeItem) => this._renderIcon(modeItem, mode))} @@ -288,7 +288,11 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard { let sliderValue: string | number | null; let uiValue: string; - if ( + if (stateObj.state === "unavailable") { + sliderType = "min-range"; + sliderValue = null; + uiValue = this.hass!.localize("state.default.unavailable"); + } else if ( stateObj.attributes.target_temp_low && stateObj.attributes.target_temp_high ) { From abf70c3a3e2a0bd1d2aab291c7a8505093753a99 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 11:52:43 -0700 Subject: [PATCH 3/7] Better deal with YAML updated message (#3447) --- src/panels/lovelace/ha-panel-lovelace.ts | 28 ++++++++++++------------ 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/panels/lovelace/ha-panel-lovelace.ts b/src/panels/lovelace/ha-panel-lovelace.ts index 0a22d634fd..1a1f0e543d 100644 --- a/src/panels/lovelace/ha-panel-lovelace.ts +++ b/src/panels/lovelace/ha-panel-lovelace.ts @@ -49,8 +49,7 @@ class LovelacePanel extends LitElement { private mqls?: MediaQueryList[]; - private _ignoreNextUpdateEventBecauseOfSave = false; - private _ignoreUpdateUntilTime: number | undefined; + private _ignoreNextUpdateEvent = false; constructor() { super(); @@ -185,14 +184,8 @@ class LovelacePanel extends LitElement { } private _lovelaceChanged() { - if ( - this._ignoreUpdateUntilTime && - new Date().getTime() < this._ignoreUpdateUntilTime - ) { - return; - } - if (this._ignoreNextUpdateEventBecauseOfSave) { - this._ignoreNextUpdateEventBecauseOfSave = false; + if (this._ignoreNextUpdateEvent) { + this._ignoreNextUpdateEvent = false; return; } showToast(this, { @@ -222,10 +215,10 @@ class LovelacePanel extends LitElement { llWindow.llConfProm = undefined; } else { // Refreshing a YAML config can trigger an update event. We will ignore - // all update events for a second after we refresh, as we already have - // the latest config in that case. + // all update events while fetching the config and for 2 seconds after the cnofig is back. + // We ignore because we already have the latest config. if (this.lovelace && this.lovelace.mode === "yaml") { - this._ignoreUpdateUntilTime = new Date().getTime() + 1000; + this._ignoreNextUpdateEvent = true; } confProm = fetchConfig(this.hass!.connection, forceDiskRefresh); @@ -243,6 +236,13 @@ class LovelacePanel extends LitElement { } conf = await generateLovelaceConfigFromHass(this.hass!); confMode = "generated"; + } finally { + // Ignore updates for another 2 seconds. + if (this.lovelace && this.lovelace.mode === "yaml") { + setTimeout(() => { + this._ignoreNextUpdateEvent = false; + }, 2000); + } } this._state = "loaded"; @@ -279,7 +279,7 @@ class LovelacePanel extends LitElement { config: newConfig, mode: "storage", }); - this._ignoreNextUpdateEventBecauseOfSave = true; + this._ignoreNextUpdateEvent = true; await saveConfig(this.hass!, newConfig); } catch (err) { // tslint:disable-next-line From 87e24d658b51b9dafdca7fdc5e1eddb6d24dd936 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 13:31:41 -0700 Subject: [PATCH 4/7] Update translations --- translations/ca.json | 27 ++++++++++++ translations/da.json | 29 ++++++++++++- translations/de.json | 27 ++++++++++++ translations/es.json | 27 ++++++++++++ translations/fi.json | 4 +- translations/fr.json | 89 ++++++++++++++++++++++++++++++--------- translations/nb.json | 35 +++++++++++++-- translations/nl.json | 29 ++++++++++++- translations/pl.json | 35 +++++++++++++-- translations/ru.json | 31 +++++++++++++- translations/sl.json | 27 ++++++++++++ translations/zh-Hant.json | 31 +++++++++++++- 12 files changed, 354 insertions(+), 37 deletions(-) diff --git a/translations/ca.json b/translations/ca.json index 79ca355b30..012f98acc7 100644 --- a/translations/ca.json +++ b/translations/ca.json @@ -747,6 +747,33 @@ "device_tracker_picked": "Seguint dispositiu", "device_tracker_pick": "Tria un dispositiu per fer-li el seguiment" } + }, + "server_control": { + "caption": "Control del servidor", + "description": "Reinicia o atura el servidor de Home Assistant", + "section": { + "validation": { + "heading": "Validació de la configuració", + "introduction": "Valida la configuració si recentment has fet algun canvi a la configuració i vols assegurar-te de que sigui vàlida.", + "check_config": "Comprova la configuració", + "valid": "Configuració vàlida!", + "invalid": "Configuració invàlida" + }, + "reloading": { + "heading": "Tornant a carregar configuració", + "introduction": "Algunes parts de la configuració de Home Assistant es poden recarregar sense necessitat de reiniciar. Els botons de sota esborraran la configuració antiga i en carregaran la nova.", + "core": "Actualitza el nucli", + "group": "Actualitza grups", + "automation": "Actualitza automatismes", + "script": "Actualitza programes" + }, + "server_management": { + "heading": "Gestió del servidor", + "introduction": "Controla el servidor de Home Assistant... des de Home Assistant.", + "restart": "Reinicia", + "stop": "Atura" + } + } } }, "profile": { diff --git a/translations/da.json b/translations/da.json index 85c3da1734..db818b8611 100644 --- a/translations/da.json +++ b/translations/da.json @@ -349,7 +349,7 @@ "introduction": "Her er det muligt at konfigurere dine komponenter og Home Assistant. Ikke alt er muligt at konfigurere fra brugergrænsefladen endnu, men vi arbejder på det.", "core": { "caption": "Generelt", - "description": "Valider din konfigurationsfil og kontroller serveren", + "description": "Valider din konfigurationsfil og administrer serveren", "section": { "core": { "header": "Konfiguration og server kontrol", @@ -747,6 +747,33 @@ "device_tracker_picked": "Spor enhed", "device_tracker_pick": "Vælg en enhed, der skal spores" } + }, + "server_control": { + "caption": "Serveradministration", + "description": "Genstart og stop Home Assistant serveren", + "section": { + "validation": { + "heading": "Validering af konfiguration", + "introduction": "Valider din konfiguration, hvis du for nylig har foretaget nogle ændringer i din konfiguration og vil sikre dig, at den er gyldig", + "check_config": "Tjek konfiguration", + "valid": "Konfiguration gyldig!", + "invalid": "Konfiguration ugyldig" + }, + "reloading": { + "heading": "Genindlæser konfiguration", + "introduction": "Nogle dele af Home Assistant kan genindlæses uden en genstart. Tryk på genindlæs for at aflæse den nuværende konfiguration og indlæse den nye.", + "core": "Genindlæs system", + "group": "Genindlæs grupper", + "automation": "Genindlæs automatiseringer", + "script": "Genindlæs scripts" + }, + "server_management": { + "heading": "Serveradministration", + "introduction": "Administrer din Home Assistant server... fra Home Assistant.", + "restart": "Genstart", + "stop": "Stop" + } + } } }, "profile": { diff --git a/translations/de.json b/translations/de.json index 691032517d..980d38c6c0 100644 --- a/translations/de.json +++ b/translations/de.json @@ -747,6 +747,33 @@ "device_tracker_picked": "Verfolge Gerät", "device_tracker_pick": "Wähle zu verfolgendes Gerät" } + }, + "server_control": { + "caption": "Serversteuerung", + "description": "Neustarten und Stoppen des Home Assistant-Servers", + "section": { + "validation": { + "heading": "Konfiguration überprüfen", + "introduction": "Überprüfe deine Konfiguration wenn du kürzlich Änderungen vorgenommen hast und sicherstellen möchtest, dass alle Änderungen gültig sind", + "check_config": "Konfiguration prüfen", + "valid": "Konfiguration in Ordnung", + "invalid": "Konfiguration ungültig" + }, + "reloading": { + "heading": "Konfiguration neu laden", + "introduction": "Einige Komponenten von Home Assistant können ohne einen Neustart neu geladen werden. \"Neu laden\" entlädt dabei die aktuelle Konfiguration und lädt die Neue.", + "core": "Hauptsystem neu laden", + "group": "Gruppen neu laden", + "automation": "Automatisierungen neu laden", + "script": "Skripte neu laden" + }, + "server_management": { + "heading": "Serververwaltung", + "introduction": "Verwalte Home Assistant… von Home Assistant aus.", + "restart": "Neu starten", + "stop": "Stoppen" + } + } } }, "profile": { diff --git a/translations/es.json b/translations/es.json index 898ef911cb..8633b2f60d 100644 --- a/translations/es.json +++ b/translations/es.json @@ -747,6 +747,33 @@ "device_tracker_picked": "Rastrear dispositivo", "device_tracker_pick": "Seleccionar dispositivo para rastrear" } + }, + "server_control": { + "caption": "Control del servidor", + "description": "Reinicia y detiene el servidor de Home Assistant", + "section": { + "validation": { + "heading": "Validación de la configuración", + "introduction": "Valida tu configuración si has realizado cambios recientemente y quieres asegurarte de que son correctos", + "check_config": "Verificar la configuración", + "valid": "¡Configuración valida!", + "invalid": "Configuración no válida" + }, + "reloading": { + "heading": "Recargando la configuración", + "introduction": "Algunas partes de Home Assistant pueden recargarse sin necesidad de reiniciar. Al pulsar en recargar se descartará la configuración actual y se cargará la nueva.", + "core": "Recargar núcleo", + "group": "Recargar grupos", + "automation": "Recargar automatizaciones", + "script": "Recargar los scripts" + }, + "server_management": { + "heading": "Gestión del servidor", + "introduction": "Controla tu servidor de Home Assistant ... desde Home Assistant.", + "restart": "Reiniciar", + "stop": "Detener" + } + } } }, "profile": { diff --git a/translations/fi.json b/translations/fi.json index 2c8eb88ca9..87377a685b 100644 --- a/translations/fi.json +++ b/translations/fi.json @@ -360,8 +360,8 @@ "elevation_meters": "metriä", "time_zone": "Aikavyöhyke", "unit_system": "Yksikköjärjestelmä", - "unit_system_imperial": "Imperial", - "unit_system_metric": "Metrinen", + "unit_system_imperial": "Brittiläinen yksikköjärjestelmä", + "unit_system_metric": "Kansainvälinen yksikköjärjestelmä", "imperial_example": "Fahrenheit, paunaa", "metric_example": "Celsius, kilogrammat", "save_button": "Tallenna" diff --git a/translations/fr.json b/translations/fr.json index 3f38518776..bfd060bf1f 100644 --- a/translations/fr.json +++ b/translations/fr.json @@ -128,7 +128,7 @@ }, "climate": { "off": "Off", - "on": "On", + "on": "Marche", "heat": "Chauffe", "cool": "Frais", "idle": "Inactif", @@ -160,8 +160,8 @@ "not_home": "Absent" }, "fan": { - "off": "Off", - "on": "On" + "off": "Arrêt", + "on": "Marche" }, "group": { "off": "Off", @@ -179,20 +179,20 @@ "problem": "Problème" }, "input_boolean": { - "off": "Off", - "on": "On" + "off": "Arrêt", + "on": "Marche" }, "light": { - "off": "Off", - "on": "On" + "off": "Éteinte", + "on": "Allumée" }, "lock": { "locked": "Verrouillé", "unlocked": "Déverrouillé" }, "media_player": { - "off": "Off", - "on": "On", + "off": "Arrêt", + "on": "Marche", "playing": "Lecture en cours", "paused": "En pause", "idle": "En veille", @@ -203,7 +203,7 @@ "problem": "Problème" }, "remote": { - "off": "Off", + "off": "Arrêt", "on": "On" }, "scene": { @@ -265,7 +265,7 @@ }, "timer": { "active": "actif", - "idle": "En veille", + "idle": "en veille", "paused": "en pause" }, "person": { @@ -290,7 +290,7 @@ "arming": "Activer", "disarming": "Désarmement", "triggered": "Déclenchée", - "armed_custom_bypass": "Activée" + "armed_custom_bypass": "Armée" }, "device_tracker": { "home": "Maison", @@ -320,7 +320,7 @@ "title": "Événements" }, "templates": { - "title": "Templates" + "title": "Gabarit" }, "mqtt": { "title": "MQTT" @@ -352,7 +352,7 @@ "description": "Validez votre fichier de configuration et contrôlez le serveur", "section": { "core": { - "header": "Configuration et contrôle du serveur", + "header": "Configuration générale", "introduction": "Changer votre configuration peut être un processus fastidieux. Nous le savons. Cette section va essayer de vous rendre la vie un peu plus facile.", "core_config": { "edit_requires_storage": "L'éditeur est désactivé car la configuration est stockée dans configuration.yaml.", @@ -532,8 +532,8 @@ "sunset": "Coucher du soleil" }, "template": { - "label": "Template", - "value_template": "Contenu du template" + "label": "Gabarit", + "value_template": "Valeur du gabarit" }, "time": { "label": "Heure", @@ -555,7 +555,7 @@ "duplicate": "Dupliquer", "delete": "Supprimer", "delete_confirm": "Voulez-vous vraiment effacer ?", - "unsupported_action": "Action non supportée : {action}", + "unsupported_action": "Action non supportée : {action}", "type_select": "Type d'action", "type": { "service": { @@ -593,20 +593,34 @@ "zwave": { "caption": "Z-Wave", "description": "Gérez votre réseau Z-Wave", + "network_management": { + "header": "Gestion de réseau Z-Wave" + }, "network_status": { "network_stopped": "Réseau Z-Wave arrêté", "network_starting": "Démarrage du réseau Z-Wave...", "network_starting_note": "Ceci peut prendre un certain temps en fonction du débit de votre réseau.", - "network_started": "Le réseau Z-Wave a été démarré" + "network_started": "Le réseau Z-Wave a été démarré", + "network_started_note_all_queried": "Tous les nœuds ont été interrogés." }, "services": { "start_network": "Démarrer le réseau", "stop_network": "Arrêter le réseau", + "heal_network": "Soigner le réseau", "test_network": "Tester le réseau", "save_config": "Enregistrer la configuration", "add_node_secure": "Ajouter un nœud sécurisé", "add_node": "Ajouter un nœud", - "remove_node": "Supprimer un nœud" + "remove_node": "Supprimer un nœud", + "cancel_command": "Annuler la commande" + }, + "common": { + "value": "Valeur", + "instance": "Instance", + "index": "Indice" + }, + "values": { + "header": "Valeurs des nœuds" } }, "users": { @@ -730,6 +744,28 @@ "device_tracker_picked": "Appareil suivi", "device_tracker_pick": "Choisissez le périphérique à suivre" } + }, + "server_control": { + "section": { + "validation": { + "heading": "Validation de la configuration", + "check_config": "Vérifiez la configuration", + "valid": "Configuration valide !", + "invalid": "Configuration invalide" + }, + "reloading": { + "heading": "Rechargement de la configuration", + "core": "Recharger le noyau", + "group": "Recharger les groupes", + "automation": "Recharger les automatisations", + "script": "Recharger les scripts" + }, + "server_management": { + "heading": "Gestion du serveur", + "restart": "Redémarrer", + "stop": "Arrêter" + } + } } }, "profile": { @@ -801,7 +837,10 @@ "close": "Fermer", "submit": "Envoyer" }, - "logout": "Déconnexion" + "logout": "Déconnexion", + "force_narrow": { + "header": "Toujours cacher la barre latérale" + } }, "page-authorize": { "initializing": "Initialisation", @@ -1218,7 +1257,7 @@ "dialogs": { "more_info_settings": { "save": "Sauvegarder", - "name": "Nom", + "name": "Surcharge du nom", "entity_id": "ID de l'entité" }, "more_info_control": { @@ -1313,6 +1352,14 @@ "home": "Accueil", "sleep": "Veille", "activity": "Activité" + }, + "hvac_action": { + "off": "Éteint", + "heating": "Chauffage", + "cooling": "Refroidissement", + "drying": "Séchage", + "idle": "Inactif", + "fan": "Ventilateur" } } }, diff --git a/translations/nb.json b/translations/nb.json index 390d5bad5e..3d980a3429 100644 --- a/translations/nb.json +++ b/translations/nb.json @@ -320,7 +320,7 @@ "title": "Hendelser" }, "templates": { - "title": "Maler" + "title": "Mal" }, "mqtt": { "title": "MQTT" @@ -349,10 +349,10 @@ "introduction": "Her er det mulig å konfigurere dine komponenter og Home Assistant. Ikke alt er mulig å konfigurere fra brukergrensesnittet enda, men vi jobber med det.", "core": { "caption": "Generelt", - "description": "Valider konfigurasjonsfilen din og kontroller serveren", + "description": "Endre den generelle konfigurasjonen for Home Assistant", "section": { "core": { - "header": "Konfigurasjon og serverkontroll", + "header": "Generell konfigurasjon", "introduction": "Endring av konfigurasjonen kan være en slitsom prosess, det vet vi. Denne delen vil forsøke å gjøre livet ditt litt lettere.", "core_config": { "edit_requires_storage": "Redigering deaktivert da konfigurasjonen er lagret i configuration.yaml.", @@ -747,6 +747,33 @@ "device_tracker_picked": "Spor enhet", "device_tracker_pick": "Velg en enhet å spore" } + }, + "server_control": { + "caption": "Server-kontroll", + "description": "Start på nytt og stopp Home Assistant-serveren", + "section": { + "validation": { + "heading": "Validering av konfigurasjon", + "introduction": "Valider konfigurasjonen hvis du nylig har gjort endringer i konfigurasjonen og vil forsikre deg om at det hele er gyldig", + "check_config": "Sjekk konfigurasjonen", + "valid": "Gyldig konfigurasjon", + "invalid": "Ugyldig konfigurasjon" + }, + "reloading": { + "heading": "Konfigurasjon lastes på nytt", + "introduction": "Noen deler av Home Assistant kan laste inn uten å kreve omstart. Hvis du trykker last på nytt, vil du bytte den nåværende konfigurasjonen med den nye.", + "core": "Last inn kjernen på nytt", + "group": "Last inn grupper på nytt", + "automation": "Last inn automatiseringer på nytt", + "script": "Last inn skript på nytt" + }, + "server_management": { + "heading": "Serveradministrasjon", + "introduction": "Kontroller din Home Assistant server... fra Home Assistant.", + "restart": "Omstart", + "stop": "Stopp" + } + } } }, "profile": { @@ -1329,7 +1356,7 @@ "none": "Ingen", "eco": "Øko", "away": "Borte", - "boost": "Turbo", + "boost": "Øke", "comfort": "Komfort", "home": "Hjem", "sleep": "Sove", diff --git a/translations/nl.json b/translations/nl.json index 92cb0cc502..35234a9cb5 100644 --- a/translations/nl.json +++ b/translations/nl.json @@ -349,7 +349,7 @@ "introduction": "Hier kun je je componenten en Home Assistant configureren. Het is nog niet mogelijk om alles te configureren vanuit de interface, maar we werken er aan.", "core": { "caption": "Algemeen", - "description": "Valideer je configuratiebestand en beheer de server", + "description": "Wijzig je algemene Home Assistant configuratie", "section": { "core": { "header": "Configuratie en serverbeheer", @@ -747,6 +747,33 @@ "device_tracker_picked": "Volg apparaat", "device_tracker_pick": "Kies apparaat om te volgen" } + }, + "server_control": { + "caption": "Serverbeheer", + "description": "De Home Assistant-server opnieuw opstarten en stoppen", + "section": { + "validation": { + "heading": "Valideer configuratie", + "introduction": "Controleer je configuratie als je onlangs wijzigingen hebt aangebracht en zeker wilt weten dat ze geldig zijn", + "check_config": "Controleer configuratie", + "valid": "Geldige configuratie!", + "invalid": "Ongeldige configuratie" + }, + "reloading": { + "heading": "Configuratie herladen", + "introduction": "Sommige delen van Home Assistant kunnen opnieuw worden geladen zonder dat een herstart vereist is. Als je herladen gebruikt, wordt de huidige configuratie leeggemaakt en wordt de nieuwe geladen.", + "core": "Herlaad kern", + "group": "Herlaad groepen", + "automation": "Herlaad automatiseringen", + "script": "Herlaad scripts" + }, + "server_management": { + "heading": "Serverbeheer", + "introduction": "Beheer je Home Assistant-server ... vanuit Home Assistant.", + "restart": "Herstarten", + "stop": "Stop" + } + } } }, "profile": { diff --git a/translations/pl.json b/translations/pl.json index 7957ada8be..27584037d9 100644 --- a/translations/pl.json +++ b/translations/pl.json @@ -747,6 +747,33 @@ "device_tracker_picked": "Śledź urządzenie", "device_tracker_pick": "Wybierz urządzenie do śledzenia" } + }, + "server_control": { + "caption": "Kontrola serwera", + "description": "Uruchom ponownie i zatrzymaj serwer Home Assistant", + "section": { + "validation": { + "heading": "Sprawdzanie konfiguracji", + "introduction": "Jeśli ostatnio wprowadzano zmiany w konfiguracji sprawdź jej poprawność", + "check_config": "Sprawdź konfigurację", + "valid": "Konfiguracja prawidłowa!", + "invalid": "Konfiguracja nieprawidłowa" + }, + "reloading": { + "heading": "Przeładowanie konfiguracji", + "introduction": "Niektóre części Home Assistant'a można przeładować bez konieczności ponownego uruchomienia. Kliknięcie przeładuj spowoduje ponowne wczytanie konfiguracji.", + "core": "Przeładuj rdzeń", + "group": "Przeładuj grupy", + "automation": "Przeładuj automatyzacje", + "script": "Przeładuj skrypty" + }, + "server_management": { + "heading": "Zarządzanie serwerem", + "introduction": "Kontroluj swój serwer Home Assistant… z Home Assistant.", + "restart": "Uruchom ponownie", + "stop": "Zatrzymaj" + } + } } }, "profile": { @@ -1138,10 +1165,10 @@ "alarm_control_panel": { "code": "Kod", "clear_code": "Wyczyść", - "disarm": "Rozbrojenie", - "arm_home": "Uzbrojenie (w domu)", - "arm_away": "Uzbrojenie (nieobecny)", - "arm_night": "Uzbrojenie (noc)", + "disarm": "rozbrojenie", + "arm_home": "uzbrojenie (w domu)", + "arm_away": "uzbrojenie (nieobecny)", + "arm_night": "uzbrojenie (noc)", "armed_custom_bypass": "Uzbrój (częściowo)", "arm_custom_bypass": "Niestandardowy bypass" }, diff --git a/translations/ru.json b/translations/ru.json index d681a3a3ef..74afefcbd1 100644 --- a/translations/ru.json +++ b/translations/ru.json @@ -349,10 +349,10 @@ "introduction": "Здесь можно настроить Home Assistant. Пока что не все настройки доступны из интерфейса, но мы работаем над этим.", "core": { "caption": "Общие", - "description": "Проверяйте Ваш файл конфигурации и управляйте сервером", + "description": "Управляйте основными настройками Home Assistant", "section": { "core": { - "header": "Конфигурация и управление сервером", + "header": "Общие настройки", "introduction": "Изменение конфигурации может быть утомительным процессом. Мы знаем. Этот раздел может немного упростить эту задачу.", "core_config": { "edit_requires_storage": "Редактор отключен, поскольку конфигурация уже хранится в файле configuration.yaml.", @@ -747,6 +747,33 @@ "device_tracker_picked": "Устройство для отслеживания", "device_tracker_pick": "Выберите устройство для отслеживания" } + }, + "server_control": { + "caption": "Управление сервером", + "description": "Перезапуск или остановка Home Assistant", + "section": { + "validation": { + "heading": "Проверка конфигурации", + "introduction": "Проверьте файлы конфигурации, если Вы внесли в них изменения", + "check_config": "Начать проверку", + "valid": "Конфигурация выполнена верно", + "invalid": "Ошибка в конфигурации" + }, + "reloading": { + "heading": "Перезагрузка конфигурации", + "introduction": "Некоторые компоненты Home Assistant можно перезагрузить без необходимости перезапуска всей системы. Перезагрузка выгружает текущую конфигурацию и загружает новую.", + "core": "Перезагрузить ядро", + "group": "Перезагрузить группы", + "automation": "Перезагрузить автоматизации", + "script": "Перезагрузить скрипты" + }, + "server_management": { + "heading": "Управление сервером", + "introduction": "Управляйте Вашим сервером Home Assistant... из Home Assistant", + "restart": "Перезапустить", + "stop": "Остановить" + } + } } }, "profile": { diff --git a/translations/sl.json b/translations/sl.json index 53b849e2b9..9e526c9b90 100644 --- a/translations/sl.json +++ b/translations/sl.json @@ -747,6 +747,33 @@ "device_tracker_picked": "Sledi Napravi", "device_tracker_pick": "Izberite napravo za sledenje" } + }, + "server_control": { + "caption": "Nadzor strežnika", + "description": "Znova zaženite in ustavite strežnik Home Assistant", + "section": { + "validation": { + "heading": "Preverjanje konfiguracije", + "introduction": "Potrdite svojo konfiguracijo, če ste nedavno spremenili svojo konfiguracijo in se prepričajte, da je vse veljavno", + "check_config": "Preverite nastavitve", + "valid": "Konfiguracija veljavna!", + "invalid": "Konfiguracija ni veljavna" + }, + "reloading": { + "heading": "Ponovno nalaganje konfiguracije", + "introduction": "Nekateri deli Home Assistanta se lahko znova naložijo brez potrebe po ponovnem zagonu. S pritiskom na \"ponovno naloži\" se bo naložila nova konfiguracija", + "core": "Ponovno naloži jedro", + "group": "Ponovno naloži skupine", + "automation": "Ponovno naloži avtomatizacije", + "script": "Ponovno naloži skripte" + }, + "server_management": { + "heading": "Upravljanje strežnika", + "introduction": "Nadzirajte strežnik Home Assistant ... iz Home Assistant-a", + "restart": "Ponovni zagon", + "stop": "Ustavi" + } + } } }, "profile": { diff --git a/translations/zh-Hant.json b/translations/zh-Hant.json index 9e0341aa1b..a31df9528d 100644 --- a/translations/zh-Hant.json +++ b/translations/zh-Hant.json @@ -349,10 +349,10 @@ "introduction": "此處為 Home Assistant 和元件相關配置區,目前尚未支援透過 UI 進行所有設定,我們正在努力改進中。", "core": { "caption": "一般設定", - "description": "驗證設定內容及服務器控制", + "description": "變更 Home Assistant 一般設定", "section": { "core": { - "header": "設定和服務器控制", + "header": "一般設定", "introduction": "更改設定常是個惱人過程。此區域將盡可能協助您,讓事情變得更輕鬆一些。", "core_config": { "edit_requires_storage": "由於 configuration.yaml 內已儲存設定,編輯功能已關閉。", @@ -747,6 +747,33 @@ "device_tracker_picked": "追蹤設備", "device_tracker_pick": "選擇追蹤設備" } + }, + "server_control": { + "caption": "伺服器控制", + "description": "重啟與停止 Home Assistant 伺服器", + "section": { + "validation": { + "heading": "設定驗證", + "introduction": "如果您對設定進行了一些更改、並且想確保設定有無錯誤,可以選擇驗證設定內容。", + "check_config": "檢查設定內容", + "valid": "設定檔內容檢查正確", + "invalid": "設定無效" + }, + "reloading": { + "heading": "正在重新載入設定", + "introduction": "Home Assistant 中部分設定無須重啟即可重新載入生效。點選重新載入按鈕,即可重新載入最新設定。", + "core": "重新載入核心設定", + "group": "重新載入群組", + "automation": "重新載入自動化", + "script": "重新載入腳本" + }, + "server_management": { + "heading": "服務器管理", + "introduction": "由 Home Assistant,控制 Home Assistant 伺服器。", + "restart": "重啟", + "stop": "停止" + } + } } }, "profile": { From f6be398fb9b7ede5da68eca5a317749a92585c1a Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 13:31:46 -0700 Subject: [PATCH 5/7] Bumped version to 20190801.0 --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 5173765e0a..82544a867c 100644 --- a/setup.py +++ b/setup.py @@ -2,7 +2,7 @@ from setuptools import setup, find_packages setup( name="home-assistant-frontend", - version="20190731.0", + version="20190801.0", description="The Home Assistant frontend", url="https://github.com/home-assistant/home-assistant-polymer", author="The Home Assistant Authors", From 17a3affb6f91c8cb5487323dfc7e5e89f5984387 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 13:32:13 -0700 Subject: [PATCH 6/7] Remove conversation because it's not part of default config (#3444) --- src/fake_data/demo_config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/fake_data/demo_config.ts b/src/fake_data/demo_config.ts index b6b96e6794..1361937db4 100644 --- a/src/fake_data/demo_config.ts +++ b/src/fake_data/demo_config.ts @@ -11,7 +11,7 @@ export const demoConfig: HassConfig = { temperature: "°C", volume: "L", }, - components: ["conversation", "notify.html5", "history"], + components: ["notify.html5", "history"], time_zone: "America/Los_Angeles", config_dir: "/config", version: "DEMO", From 2fda2ee7420c05bf7e7a964520b007cb35c222e1 Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Thu, 1 Aug 2019 13:33:28 -0700 Subject: [PATCH 7/7] Suggest a view path when user enters a title when creating a view (#3448) * Suggest a view path when user enters a title when creating a view * Lint --- src/common/string/slugify.ts | 19 ++++++ .../editor/view-editor/hui-edit-view.ts | 1 + .../editor/view-editor/hui-view-editor.ts | 59 +++++++++++-------- 3 files changed, 56 insertions(+), 23 deletions(-) create mode 100644 src/common/string/slugify.ts diff --git a/src/common/string/slugify.ts b/src/common/string/slugify.ts new file mode 100644 index 0000000000..74a21b5c8f --- /dev/null +++ b/src/common/string/slugify.ts @@ -0,0 +1,19 @@ +// https://gist.github.com/hagemann/382adfc57adbd5af078dc93feef01fe1 +export const slugify = (value: string) => { + const a = + "àáäâãåăæąçćčđďèéěėëêęğǵḧìíïîįłḿǹńňñòóöôœøṕŕřßşśšșťțùúüûǘůűūųẃẍÿýźžż·/_,:;"; + const b = + "aaaaaaaaacccddeeeeeeegghiiiiilmnnnnooooooprrsssssttuuuuuuuuuwxyyzzz------"; + const p = new RegExp(a.split("").join("|"), "g"); + + return value + .toString() + .toLowerCase() + .replace(/\s+/g, "-") // Replace spaces with - + .replace(p, (c) => b.charAt(a.indexOf(c))) // Replace special characters + .replace(/&/g, "-and-") // Replace & with 'and' + .replace(/[^\w\-]+/g, "") // Remove all non-word characters + .replace(/\-\-+/g, "-") // Replace multiple - with single - + .replace(/^-+/, "") // Trim - from start of text + .replace(/-+$/, ""); // Trim - from end of text +}; diff --git a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts index 4af79771f3..55d68a1702 100644 --- a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts @@ -93,6 +93,7 @@ export class HuiEditView extends LitElement { case "tab-settings": content = html` Panel Mode?
@@ -112,10 +115,6 @@ export class HuiViewEditor extends LitElement { } private _valueChanged(ev: Event): void { - if (!this._config || !this.hass) { - return; - } - const target = ev.currentTarget! as EditorTarget; if (this[`_${target.configValue}`] === target.value) { @@ -134,6 +133,20 @@ export class HuiViewEditor extends LitElement { fireEvent(this, "view-config-changed", { config: newConfig }); } + + private _handleTitleBlur(ev) { + if ( + !this.isNew || + this._suggestedPath || + this._config.path || + !ev.currentTarget.value + ) { + return; + } + + const config = { ...this._config, path: slugify(ev.currentTarget.value) }; + fireEvent(this, "view-config-changed", { config }); + } } declare global {