mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 16:26:43 +00:00
Updates to alarm panel card configuration (#17598)
* Updates to alarm panel card configuration * changes from feedback
This commit is contained in:
parent
ae9fcebfd5
commit
034ce56da5
@ -9,6 +9,7 @@ import {
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { styleMap } from "lit/directives/style-map";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { alarmPanelIcon } from "../../../common/entity/alarm_panel_icon";
|
||||
@ -20,16 +21,48 @@ import type { HaTextField } from "../../../components/ha-textfield";
|
||||
import {
|
||||
callAlarmAction,
|
||||
FORMAT_NUMBER,
|
||||
ALARM_MODES,
|
||||
AlarmMode,
|
||||
} from "../../../data/alarm_control_panel";
|
||||
import { UNAVAILABLE } from "../../../data/entity";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type { LovelaceCard } from "../types";
|
||||
import { AlarmPanelCardConfig } from "./types";
|
||||
import { AlarmPanelCardConfig, AlarmPanelCardConfigState } from "./types";
|
||||
import { supportsFeature } from "../../../common/entity/supports-feature";
|
||||
|
||||
const BUTTONS = ["1", "2", "3", "4", "5", "6", "7", "8", "9", "", "0", "clear"];
|
||||
|
||||
export const DEFAULT_STATES = [
|
||||
"arm_home",
|
||||
"arm_away",
|
||||
] as AlarmPanelCardConfigState[];
|
||||
|
||||
export const ALARM_MODE_STATE_MAP: Record<
|
||||
AlarmPanelCardConfigState,
|
||||
AlarmMode
|
||||
> = {
|
||||
arm_home: "armed_home",
|
||||
arm_away: "armed_away",
|
||||
arm_night: "armed_night",
|
||||
arm_vacation: "armed_vacation",
|
||||
arm_custom_bypass: "armed_custom_bypass",
|
||||
};
|
||||
|
||||
export const filterSupportedAlarmStates = (
|
||||
stateObj: HassEntity | undefined,
|
||||
states: AlarmPanelCardConfigState[]
|
||||
): AlarmPanelCardConfigState[] =>
|
||||
states.filter(
|
||||
(s) =>
|
||||
stateObj &&
|
||||
supportsFeature(
|
||||
stateObj,
|
||||
ALARM_MODES[ALARM_MODE_STATE_MAP[s]].feature || 0
|
||||
)
|
||||
);
|
||||
|
||||
@customElement("hui-alarm-panel-card")
|
||||
class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
public static async getConfigElement() {
|
||||
@ -52,10 +85,13 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
includeDomains
|
||||
);
|
||||
|
||||
const entity = foundEntities[0] || "";
|
||||
const stateObj = hass.states[entity];
|
||||
|
||||
return {
|
||||
type: "alarm-panel",
|
||||
states: ["arm_home", "arm_away"],
|
||||
entity: foundEntities[0] || "",
|
||||
states: filterSupportedAlarmStates(stateObj, DEFAULT_STATES),
|
||||
entity,
|
||||
};
|
||||
}
|
||||
|
||||
@ -86,11 +122,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
throw new Error("Invalid configuration");
|
||||
}
|
||||
|
||||
const defaults = {
|
||||
states: ["arm_away", "arm_home"] as const,
|
||||
};
|
||||
|
||||
this._config = { ...defaults, ...config };
|
||||
this._config = { ...config };
|
||||
}
|
||||
|
||||
protected updated(changedProps: PropertyValues): void {
|
||||
@ -138,6 +170,9 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
return nothing;
|
||||
}
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
const states =
|
||||
this._config.states ||
|
||||
filterSupportedAlarmStates(stateObj, DEFAULT_STATES);
|
||||
|
||||
if (!stateObj) {
|
||||
return html`
|
||||
@ -170,7 +205,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
</h1>
|
||||
<div id="armActions" class="actions">
|
||||
${(stateObj.state === "disarmed"
|
||||
? this._config.states!
|
||||
? states
|
||||
: (["disarm"] as const)
|
||||
).map(
|
||||
(stateAction) => html`
|
||||
|
@ -14,10 +14,17 @@ import { HaDurationData } from "../../../components/ha-duration-input";
|
||||
import { LovelaceTileFeatureConfig } from "../tile-features/types";
|
||||
import { ForecastType } from "../../../data/weather";
|
||||
|
||||
export type AlarmPanelCardConfigState =
|
||||
| "arm_away"
|
||||
| "arm_home"
|
||||
| "arm_night"
|
||||
| "arm_vacation"
|
||||
| "arm_custom_bypass";
|
||||
|
||||
export interface AlarmPanelCardConfig extends LovelaceCardConfig {
|
||||
entity: string;
|
||||
name?: string;
|
||||
states?: readonly (keyof TranslationDict["ui"]["card"]["alarm_control_panel"])[];
|
||||
states?: AlarmPanelCardConfigState[];
|
||||
theme?: string;
|
||||
}
|
||||
|
||||
|
@ -2,14 +2,25 @@ import { html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { array, assert, assign, object, optional, string } from "superstruct";
|
||||
import { HassEntity } from "home-assistant-js-websocket";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import "../../../../components/ha-form/ha-form";
|
||||
import type { SchemaUnion } from "../../../../components/ha-form/types";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { AlarmPanelCardConfig } from "../../cards/types";
|
||||
import type {
|
||||
AlarmPanelCardConfig,
|
||||
AlarmPanelCardConfigState,
|
||||
} from "../../cards/types";
|
||||
import type { LovelaceCardEditor } from "../../types";
|
||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||
import {
|
||||
DEFAULT_STATES,
|
||||
ALARM_MODE_STATE_MAP,
|
||||
filterSupportedAlarmStates,
|
||||
} from "../../cards/hui-alarm-panel-card";
|
||||
import { supportsFeature } from "../../../../common/entity/supports-feature";
|
||||
import { ALARM_MODES } from "../../../../data/alarm_control_panel";
|
||||
|
||||
const cardConfigStruct = assign(
|
||||
baseLovelaceCardConfig,
|
||||
@ -21,13 +32,7 @@ const cardConfigStruct = assign(
|
||||
})
|
||||
);
|
||||
|
||||
const states = [
|
||||
"arm_home",
|
||||
"arm_away",
|
||||
"arm_night",
|
||||
"arm_vacation",
|
||||
"arm_custom_bypass",
|
||||
] as const;
|
||||
const states = Object.keys(ALARM_MODE_STATE_MAP) as AlarmPanelCardConfigState[];
|
||||
|
||||
@customElement("hui-alarm-panel-card-editor")
|
||||
export class HuiAlarmPanelCardEditor
|
||||
@ -44,7 +49,11 @@ export class HuiAlarmPanelCardEditor
|
||||
}
|
||||
|
||||
private _schema = memoizeOne(
|
||||
(localize: LocalizeFunc) =>
|
||||
(
|
||||
localize: LocalizeFunc,
|
||||
stateObj: HassEntity | undefined,
|
||||
config_states: AlarmPanelCardConfigState[]
|
||||
) =>
|
||||
[
|
||||
{
|
||||
name: "entity",
|
||||
@ -60,12 +69,24 @@ export class HuiAlarmPanelCardEditor
|
||||
],
|
||||
},
|
||||
{
|
||||
type: "multi_select",
|
||||
name: "states",
|
||||
options: states.map((s) => [
|
||||
s,
|
||||
localize(`ui.card.alarm_control_panel.${s}`),
|
||||
]) as [string, string][],
|
||||
selector: {
|
||||
select: {
|
||||
multiple: true,
|
||||
mode: "list",
|
||||
options: states.map((s) => ({
|
||||
value: s,
|
||||
label: localize(`ui.card.alarm_control_panel.${s}`),
|
||||
disabled:
|
||||
!config_states.includes(s) &&
|
||||
(!stateObj ||
|
||||
!supportsFeature(
|
||||
stateObj,
|
||||
ALARM_MODES[ALARM_MODE_STATE_MAP[s]].feature || 0
|
||||
)),
|
||||
})),
|
||||
},
|
||||
},
|
||||
},
|
||||
] as const
|
||||
);
|
||||
@ -75,11 +96,18 @@ export class HuiAlarmPanelCardEditor
|
||||
return nothing;
|
||||
}
|
||||
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
const defaultFilteredStates = filterSupportedAlarmStates(
|
||||
stateObj,
|
||||
DEFAULT_STATES
|
||||
);
|
||||
const config = { states: defaultFilteredStates, ...this._config };
|
||||
|
||||
return html`
|
||||
<ha-form
|
||||
.hass=${this.hass}
|
||||
.data=${this._config}
|
||||
.schema=${this._schema(this.hass.localize)}
|
||||
.data=${config}
|
||||
.schema=${this._schema(this.hass.localize, stateObj, config.states)}
|
||||
.computeLabel=${this._computeLabelCallback}
|
||||
@value-changed=${this._valueChanged}
|
||||
></ha-form>
|
||||
@ -87,7 +115,26 @@ export class HuiAlarmPanelCardEditor
|
||||
}
|
||||
|
||||
private _valueChanged(ev: CustomEvent): void {
|
||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||
const newConfig = ev.detail.value;
|
||||
|
||||
// Sort states in a consistent order
|
||||
if (newConfig.states) {
|
||||
const sortStates = states.filter((s) => newConfig.states.includes(s));
|
||||
newConfig.states = sortStates;
|
||||
}
|
||||
|
||||
// When changing entities, clear any states that the new entity does not support
|
||||
if (newConfig.states && newConfig.entity !== this._config?.entity) {
|
||||
const newStateObj = this.hass?.states[newConfig.entity];
|
||||
if (newStateObj) {
|
||||
newConfig.states = filterSupportedAlarmStates(
|
||||
newStateObj,
|
||||
newConfig.states
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
fireEvent(this, "config-changed", { config: newConfig });
|
||||
}
|
||||
|
||||
private _computeLabelCallback = (
|
||||
|
Loading…
x
Reference in New Issue
Block a user