diff --git a/src/components/ha-combo-box.ts b/src/components/ha-combo-box.ts index 44e55c55d9..4d07dcba6c 100644 --- a/src/components/ha-combo-box.ts +++ b/src/components/ha-combo-box.ts @@ -205,7 +205,7 @@ export class HaComboBox extends LitElement { role="button" tabindex="-1" aria-label=${ifDefined(this.hass?.localize("ui.common.clear"))} - class="clear-button" + class=${`clear-button ${this.label ? "" : "no-label"}`} .path=${mdiClose} @click=${this._clearValue} >` @@ -215,7 +215,7 @@ export class HaComboBox extends LitElement { tabindex="-1" aria-label=${ifDefined(this.label)} aria-expanded=${this.opened ? "true" : "false"} - class="toggle-button" + class=${`toggle-button ${this.label ? "" : "no-label"}`} .path=${this.opened ? mdiMenuUp : mdiMenuDown} ?disabled=${this.disabled} @click=${this._toggleOpen} @@ -397,6 +397,9 @@ export class HaComboBox extends LitElement { color: var(--disabled-text-color); pointer-events: none; } + .toggle-button.no-label { + top: -3px; + } .clear-button { --mdc-icon-size: 20px; top: -7px; @@ -405,6 +408,9 @@ export class HaComboBox extends LitElement { inset-inline-end: 36px; direction: var(--direction); } + .clear-button.no-label { + top: 0; + } ha-input-helper-text { margin-top: 4px; } diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts index cff9d6fb20..df838464d2 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-node-config.ts @@ -23,6 +23,7 @@ import "../../../../../components/ha-selector/ha-selector-boolean"; import "../../../../../components/ha-settings-row"; import "../../../../../components/ha-svg-icon"; import "../../../../../components/ha-textfield"; +import "../../../../../components/ha-combo-box"; import type { ZWaveJSNodeCapabilities, ZWaveJSNodeConfigParam, @@ -55,7 +56,7 @@ const icons = { @customElement("zwave_js-node-config") class ZWaveJSNodeConfig extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; + public hass!: HomeAssistant; @property({ attribute: false }) public route!: Route; @@ -230,26 +231,8 @@ class ZWaveJSNodeConfig extends LitElement { item: ZWaveJSNodeConfigParam ): TemplateResult { const result = this._results[id]; - let type = item.configuration_value_type; - if ( - type === "manual_entry" && - item.metadata.states && - item.metadata.min != null && - item.metadata.max != null && - item.metadata.max - item.metadata.min <= 100 - ) { - // https://github.com/zwave-js/backlog/issues/59 - type = "enumerated"; - for (let i = item.metadata.min; i <= item.metadata.max; i++) { - if (i in item.metadata.states) { - continue; - } - item.metadata.states[i] = i.toString(); - } - } - - const isTypeBoolean = type === "boolean" || this._isEnumeratedBool(item); + const isTypeBoolean = item.configuration_value_type === "boolean" || this._isEnumeratedBool(item); const labelAndDescription = html` @@ -310,7 +293,7 @@ class ZWaveJSNodeConfig extends LitElement { ? this.hass.localize( item.metadata.default === 1 ? "ui.common.yes" : "ui.common.no" ) - : type === "enumerated" + : item.configuration_value_type === "enumerated" ? item.metadata.states[item.metadata.default] || item.metadata.default : item.metadata.default @@ -335,7 +318,31 @@ class ZWaveJSNodeConfig extends LitElement { `; } - if (type === "manual_entry") { + if (item.configuration_value_type === "manual_entry") { + if ( + item.metadata.states && + item.metadata.min != null && + item.metadata.max != null && + item.metadata.max - item.metadata.min <= 100 + ) { + return html` + ${labelAndDescription} + ({ value, label }) + )} + .disabled=${!item.metadata.writeable} + .placeholder=${item.metadata.unit} + .helper=${`${this.hass.localize("ui.panel.config.zwave_js.node_config.between_min_max", { min: item.metadata.min, max: item.metadata.max })}${defaultLabel ? `, ${defaultLabel}` : ""}`} + @value-changed=${this._getComboBoxValueChangedCallback(id, item)} + > + + `; + } return html`${labelAndDescription} `; } - if (type === "enumerated") { + if (item.configuration_value_type === "enumerated") { return html` ${labelAndDescription} ev.target.max) @@ -456,6 +472,26 @@ class ZWaveJSNodeConfig extends LitElement { this._updateConfigParameter(ev.target, value); } + private _getComboBoxValueChangedCallback( + id: string, + item: ZWaveJSNodeConfigParam + ) { + return (ev: CustomEvent<{ value: number }>) => + this._numericInputChanged({ + ...ev, + target: { + ...ev.target, + key: id, + min: item.metadata.min, + max: item.metadata.max, + value: ev.detail.value, + property: item.property, + endpoint: item.endpoint, + propertyKey: item.property_key, + }, + }); + } + private async _updateConfigParameter(target, value) { try { const result = await setZwaveNodeConfigParameter( diff --git a/src/translations/en.json b/src/translations/en.json index c861c420b0..ecc0a18090 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -6061,6 +6061,7 @@ "parameter_is_read_only": "This parameter is read-only.", "between_min_max": "Between {min} and {max}", "error_not_in_range": "Value must be between {min} and {max}", + "error_not_numeric": "Value must be a number", "error_required": "{entity} is required", "error_device_not_found": "Device not found", "set_param_accepted": "The parameter has been updated.",