From 6febe8552e8e89170e4345c02b3c940a1af5db01 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 1 May 2024 11:55:06 +0200 Subject: [PATCH] Allow to reorder alarm modes in card feature (#20684) --- src/data/alarm_control_panel.ts | 7 ++ .../hui-alarm-modes-card-feature.ts | 11 ++- .../hui-alarm-modes-card-feature-editor.ts | 99 +++++++++++++------ src/translations/en.json | 3 +- 4 files changed, 85 insertions(+), 35 deletions(-) diff --git a/src/data/alarm_control_panel.ts b/src/data/alarm_control_panel.ts index 2c1a8ea489..64a8d53fee 100644 --- a/src/data/alarm_control_panel.ts +++ b/src/data/alarm_control_panel.ts @@ -11,6 +11,7 @@ import { HassEntityBase, } from "home-assistant-js-websocket"; import { HomeAssistant } from "../types"; +import { supportsFeature } from "../common/entity/supports-feature"; export const FORMAT_TEXT = "text"; export const FORMAT_NUMBER = "number"; @@ -96,3 +97,9 @@ export const ALARM_MODES: Record = { path: mdiShieldOff, }, }; + +export const supportedAlarmModes = (stateObj: AlarmControlPanelEntity) => + (Object.keys(ALARM_MODES) as AlarmMode[]).filter((mode) => { + const feature = ALARM_MODES[mode].feature; + return !feature || supportsFeature(stateObj, feature); + }); diff --git a/src/panels/lovelace/card-features/hui-alarm-modes-card-feature.ts b/src/panels/lovelace/card-features/hui-alarm-modes-card-feature.ts index 818b1e66a4..7a4362ee9a 100644 --- a/src/panels/lovelace/card-features/hui-alarm-modes-card-feature.ts +++ b/src/panels/lovelace/card-features/hui-alarm-modes-card-feature.ts @@ -16,12 +16,14 @@ import { AlarmControlPanelEntity, AlarmMode, ALARM_MODES, + supportedAlarmModes, } from "../../../data/alarm_control_panel"; import { UNAVAILABLE } from "../../../data/entity"; import { HomeAssistant } from "../../../types"; import { LovelaceCardFeature, LovelaceCardFeatureEditor } from "../types"; import { AlarmModesCardFeatureConfig } from "./types"; import { showEnterCodeDialog } from "../../../dialogs/enter-code/show-enter-code-dialog"; +import { filterModes } from "./common/filter-modes"; export const supportsAlarmModesCardFeature = (stateObj: HassEntity) => { const domain = computeDomain(stateObj.entity_id); @@ -164,9 +166,12 @@ class HuiAlarmModeCardFeature const color = stateColorCss(this.stateObj); - const modes = this._modes(this.stateObj, this._config.modes); + const supportedModes = supportedAlarmModes(this.stateObj); - const options = modes.map((mode) => ({ + const options = filterModes( + supportedModes, + this._config.modes + ).map((mode) => ({ value: mode, label: this.hass!.localize(`ui.card.alarm_control_panel.modes.${mode}`), path: ALARM_MODES[mode].path, @@ -196,7 +201,7 @@ class HuiAlarmModeCardFeature )} style=${styleMap({ "--control-select-color": color, - "--modes-count": modes.length.toString(), + "--modes-count": options.length.toString(), })} .disabled=${this.stateObj!.state === UNAVAILABLE} > diff --git a/src/panels/lovelace/editor/config-elements/hui-alarm-modes-card-feature-editor.ts b/src/panels/lovelace/editor/config-elements/hui-alarm-modes-card-feature-editor.ts index 0ae1b20979..b96be97bb0 100644 --- a/src/panels/lovelace/editor/config-elements/hui-alarm-modes-card-feature-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-alarm-modes-card-feature-editor.ts @@ -3,17 +3,23 @@ import { html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; import { fireEvent } from "../../../../common/dom/fire_event"; -import { supportsFeature } from "../../../../common/entity/supports-feature"; import type { LocalizeFunc } from "../../../../common/translations/localize"; -import type { SchemaUnion } from "../../../../components/ha-form/types"; -import { AlarmMode, ALARM_MODES } from "../../../../data/alarm_control_panel"; +import "../../../../components/ha-form/ha-form"; +import type { + HaFormSchema, + SchemaUnion, +} from "../../../../components/ha-form/types"; +import { supportedAlarmModes } from "../../../../data/alarm_control_panel"; import type { HomeAssistant } from "../../../../types"; import { - LovelaceCardFeatureContext, AlarmModesCardFeatureConfig, + LovelaceCardFeatureContext, } from "../../card-features/types"; import type { LovelaceCardFeatureEditor } from "../../types"; -import "../../../../components/ha-form/ha-form"; + +type AlarmModesCardFeatureData = AlarmModesCardFeatureConfig & { + customize_modes: boolean; +}; @customElement("hui-alarm-modes-card-feature-editor") export class HuiAlarmModesCardFeatureEditor @@ -31,31 +37,40 @@ export class HuiAlarmModesCardFeatureEditor } private _schema = memoizeOne( - (localize: LocalizeFunc, stateObj?: HassEntity) => + ( + localize: LocalizeFunc, + stateObj: HassEntity | undefined, + customizeModes: boolean + ) => [ { - name: "modes", + name: "customize_modes", selector: { - select: { - multiple: true, - mode: "list", - options: Object.keys(ALARM_MODES) - .filter((mode) => { - const feature = ALARM_MODES[mode as AlarmMode].feature; - return ( - stateObj && (!feature || supportsFeature(stateObj, feature)) - ); - }) - .map((mode) => ({ - value: mode, - label: `${localize( - `ui.panel.lovelace.editor.features.types.alarm-modes.modes_list.${mode}` - )}`, - })), - }, + boolean: {}, }, }, - ] as const + ...(customizeModes + ? ([ + { + name: "modes", + selector: { + select: { + multiple: true, + reorder: true, + options: stateObj + ? supportedAlarmModes(stateObj).map((mode) => ({ + value: mode, + label: `${localize( + `ui.panel.lovelace.editor.features.types.alarm-modes.modes_list.${mode}` + )}`, + })) + : [], + }, + }, + }, + ] as const satisfies readonly HaFormSchema[]) + : []), + ] as const satisfies readonly HaFormSchema[] ); protected render() { @@ -63,16 +78,25 @@ export class HuiAlarmModesCardFeatureEditor return nothing; } + const data: AlarmModesCardFeatureData = { + ...this._config, + customize_modes: this._config.modes !== undefined, + }; + const stateObj = this.context?.entity_id ? this.hass.states[this.context?.entity_id] : undefined; - const schema = this._schema(this.hass.localize, stateObj); + const schema = this._schema( + this.hass.localize, + stateObj, + data.customize_modes + ); return html` { switch (schema.name) { case "modes": + case "customize_modes": return this.hass!.localize( `ui.panel.lovelace.editor.features.types.alarm-modes.${schema.name}` ); default: - return this.hass!.localize( - `ui.panel.lovelace.editor.card.generic.${schema.name}` - ); + return ""; } }; } diff --git a/src/translations/en.json b/src/translations/en.json index 3bde569c1b..f28231447e 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5970,7 +5970,8 @@ "armed_vacation": "[%key:ui::card::alarm_control_panel::modes::armed_vacation%]", "armed_custom_bypass": "[%key:ui::card::alarm_control_panel::modes::armed_custom_bypass%]", "disarmed": "[%key:ui::card::alarm_control_panel::modes::disarmed%]" - } + }, + "customize_modes": "Customize alarm modes" }, "light-brightness": { "label": "Light brightness"