169 lines
5.0 KiB
TypeScript
169 lines
5.0 KiB
TypeScript
import { html, LitElement, PropertyValues } from "lit";
|
|
import { customElement, property } from "lit/decorators";
|
|
import memoizeOne from "memoize-one";
|
|
import { assert, literal, object, optional, string } from "superstruct";
|
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
|
import { LocalizeFunc } from "../../../../../common/translations/localize";
|
|
import "../../../../../components/ha-form/ha-form";
|
|
import type { SchemaUnion } from "../../../../../components/ha-form/types";
|
|
import { HaFormSchema } from "../../../../../components/ha-form/types";
|
|
import type { HomeAssistant } from "../../../../../types";
|
|
import { LovelaceStateCondition } from "../../../common/conditions/types";
|
|
|
|
const stateConditionStruct = object({
|
|
condition: literal("state"),
|
|
entity: optional(string()),
|
|
state: optional(string()),
|
|
state_not: optional(string()),
|
|
});
|
|
|
|
type StateConditionData = {
|
|
condition: "state";
|
|
entity?: string;
|
|
invert: "true" | "false";
|
|
state?: string | string[];
|
|
};
|
|
|
|
@customElement("ha-card-condition-state")
|
|
export class HaCardConditionState extends LitElement {
|
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
|
|
|
@property({ attribute: false }) public condition!: LovelaceStateCondition;
|
|
|
|
@property({ type: Boolean }) public disabled = false;
|
|
|
|
public static get defaultConfig(): LovelaceStateCondition {
|
|
return { condition: "state", entity: "", state: "" };
|
|
}
|
|
|
|
protected static validateUIConfig(condition: LovelaceStateCondition) {
|
|
return assert(condition, stateConditionStruct);
|
|
}
|
|
|
|
protected willUpdate(changedProperties: PropertyValues): void {
|
|
if (!changedProperties.has("condition")) {
|
|
return;
|
|
}
|
|
try {
|
|
assert(this.condition, stateConditionStruct);
|
|
} catch (err: any) {
|
|
fireEvent(this, "ui-mode-not-available", err);
|
|
}
|
|
}
|
|
|
|
private _schema = memoizeOne(
|
|
(localize: LocalizeFunc) =>
|
|
[
|
|
{ name: "entity", selector: { entity: {} } },
|
|
{
|
|
name: "",
|
|
type: "grid",
|
|
schema: [
|
|
{
|
|
name: "invert",
|
|
required: true,
|
|
selector: {
|
|
select: {
|
|
mode: "dropdown",
|
|
options: [
|
|
{
|
|
label: localize(
|
|
"ui.panel.lovelace.editor.condition-editor.condition.state.state_equal"
|
|
),
|
|
value: "false",
|
|
},
|
|
{
|
|
label: localize(
|
|
"ui.panel.lovelace.editor.condition-editor.condition.state.state_not_equal"
|
|
),
|
|
value: "true",
|
|
},
|
|
],
|
|
},
|
|
},
|
|
},
|
|
{
|
|
name: "state",
|
|
selector: {
|
|
state: {},
|
|
},
|
|
context: {
|
|
filter_entity: "entity",
|
|
},
|
|
},
|
|
],
|
|
},
|
|
] as const satisfies readonly HaFormSchema[]
|
|
);
|
|
|
|
protected render() {
|
|
const { state, state_not, ...content } = this.condition;
|
|
|
|
const data: StateConditionData = {
|
|
...content,
|
|
entity: this.condition.entity,
|
|
invert: this.condition.state_not ? "true" : "false",
|
|
state: this.condition.state_not ?? this.condition.state,
|
|
};
|
|
|
|
return html`
|
|
<ha-form
|
|
.hass=${this.hass}
|
|
.data=${data}
|
|
.schema=${this._schema(this.hass.localize)}
|
|
.disabled=${this.disabled}
|
|
@value-changed=${this._valueChanged}
|
|
.computeLabel=${this._computeLabelCallback}
|
|
></ha-form>
|
|
`;
|
|
}
|
|
|
|
private _valueChanged(ev: CustomEvent): void {
|
|
ev.stopPropagation();
|
|
const data = ev.detail.value as StateConditionData;
|
|
|
|
const { invert, state, condition: _, ...content } = data;
|
|
|
|
const condition: LovelaceStateCondition = {
|
|
condition: "state",
|
|
...content,
|
|
state: invert === "false" ? state ?? "" : undefined,
|
|
state_not: invert === "true" ? state ?? "" : undefined,
|
|
};
|
|
|
|
fireEvent(this, "value-changed", { value: condition });
|
|
}
|
|
|
|
private _computeLabelCallback = (
|
|
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
|
): string => {
|
|
const entity = this.condition.entity
|
|
? this.hass.states[this.condition.entity]
|
|
: undefined;
|
|
switch (schema.name) {
|
|
case "entity":
|
|
return this.hass.localize("ui.components.entity.entity-picker.entity");
|
|
case "state":
|
|
if (entity) {
|
|
return `${this.hass.localize(
|
|
"ui.components.entity.entity-state-picker.state"
|
|
)} (${this.hass.localize(
|
|
"ui.panel.lovelace.editor.condition-editor.condition.state.current_state"
|
|
)}: ${this.hass.formatEntityState(entity)})`;
|
|
}
|
|
return `${this.hass.localize(
|
|
"ui.components.entity.entity-state-picker.state"
|
|
)}`;
|
|
|
|
default:
|
|
return "";
|
|
}
|
|
};
|
|
}
|
|
|
|
declare global {
|
|
interface HTMLElementTagNameMap {
|
|
"ha-card-condition-state": HaCardConditionState;
|
|
}
|
|
}
|