mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 10:46:35 +00:00
Support to|from null in UI for ha-automation-trigger-state (#15071)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
aea668e754
commit
5217d427e9
@ -19,6 +19,8 @@ class HaEntityStatePicker extends LitElement {
|
|||||||
|
|
||||||
@property() public attribute?: string;
|
@property() public attribute?: string;
|
||||||
|
|
||||||
|
@property() public extraOptions?: any[];
|
||||||
|
|
||||||
@property({ type: Boolean }) public autofocus = false;
|
@property({ type: Boolean }) public autofocus = false;
|
||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
@ -43,10 +45,16 @@ class HaEntityStatePicker extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected updated(changedProps: PropertyValues) {
|
protected updated(changedProps: PropertyValues) {
|
||||||
if (changedProps.has("_opened") && this._opened) {
|
if (
|
||||||
|
(changedProps.has("_opened") && this._opened) ||
|
||||||
|
changedProps.has("entityId") ||
|
||||||
|
changedProps.has("attribute") ||
|
||||||
|
changedProps.has("extraOptions")
|
||||||
|
) {
|
||||||
const state = this.entityId ? this.hass.states[this.entityId] : undefined;
|
const state = this.entityId ? this.hass.states[this.entityId] : undefined;
|
||||||
(this._comboBox as any).items =
|
(this._comboBox as any).items = [
|
||||||
this.entityId && state
|
...(this.extraOptions ?? []),
|
||||||
|
...(this.entityId && state
|
||||||
? getStates(state, this.attribute).map((key) => ({
|
? getStates(state, this.attribute).map((key) => ({
|
||||||
value: key,
|
value: key,
|
||||||
label: !this.attribute
|
label: !this.attribute
|
||||||
@ -66,7 +74,8 @@ class HaEntityStatePicker extends LitElement {
|
|||||||
key
|
key
|
||||||
),
|
),
|
||||||
}))
|
}))
|
||||||
: [];
|
: []),
|
||||||
|
];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,6 +34,7 @@ export class HaSelectorState extends SubscribeMixin(LitElement) {
|
|||||||
this.context?.filter_entity}
|
this.context?.filter_entity}
|
||||||
.attribute=${this.selector.state?.attribute ||
|
.attribute=${this.selector.state?.attribute ||
|
||||||
this.context?.filter_attribute}
|
this.context?.filter_attribute}
|
||||||
|
.extraOptions=${this.selector.state?.extra_options}
|
||||||
.value=${this.value}
|
.value=${this.value}
|
||||||
.label=${this.label}
|
.label=${this.label}
|
||||||
.helper=${this.helper}
|
.helper=${this.helper}
|
||||||
|
@ -301,6 +301,14 @@ export const describeTrigger = (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!trigger.attribute &&
|
||||||
|
trigger.from === undefined &&
|
||||||
|
trigger.to === undefined
|
||||||
|
) {
|
||||||
|
base += " state or any attributes";
|
||||||
|
}
|
||||||
|
|
||||||
if (trigger.for) {
|
if (trigger.for) {
|
||||||
const duration = describeDuration(trigger.for);
|
const duration = describeDuration(trigger.for);
|
||||||
if (duration) {
|
if (duration) {
|
||||||
|
@ -295,6 +295,7 @@ export interface SelectSelector {
|
|||||||
|
|
||||||
export interface StateSelector {
|
export interface StateSelector {
|
||||||
state: {
|
state: {
|
||||||
|
extra_options?: { label: string; value: any }[];
|
||||||
entity_id?: string;
|
entity_id?: string;
|
||||||
attribute?: string;
|
attribute?: string;
|
||||||
} | null;
|
} | null;
|
||||||
|
@ -5,6 +5,7 @@ import {
|
|||||||
assert,
|
assert,
|
||||||
assign,
|
assign,
|
||||||
literal,
|
literal,
|
||||||
|
nullable,
|
||||||
number,
|
number,
|
||||||
object,
|
object,
|
||||||
optional,
|
optional,
|
||||||
@ -12,6 +13,7 @@ import {
|
|||||||
union,
|
union,
|
||||||
} from "superstruct";
|
} from "superstruct";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import type { LocalizeFunc } from "../../../../../common/translations/localize";
|
||||||
import { ensureArray } from "../../../../../common/array/ensure-array";
|
import { ensureArray } from "../../../../../common/array/ensure-array";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import { hasTemplate } from "../../../../../common/string/has-template";
|
import { hasTemplate } from "../../../../../common/string/has-template";
|
||||||
@ -30,12 +32,14 @@ const stateTriggerStruct = assign(
|
|||||||
platform: literal("state"),
|
platform: literal("state"),
|
||||||
entity_id: optional(union([string(), array(string())])),
|
entity_id: optional(union([string(), array(string())])),
|
||||||
attribute: optional(string()),
|
attribute: optional(string()),
|
||||||
from: optional(string()),
|
from: optional(nullable(string())),
|
||||||
to: optional(string()),
|
to: optional(nullable(string())),
|
||||||
for: optional(union([number(), string(), forDictStruct])),
|
for: optional(union([number(), string(), forDictStruct])),
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const ANY_STATE_VALUE = "__ANY_STATE_IGNORE_ATTRIBUTES__";
|
||||||
|
|
||||||
@customElement("ha-automation-trigger-state")
|
@customElement("ha-automation-trigger-state")
|
||||||
export class HaStateTrigger extends LitElement implements TriggerElement {
|
export class HaStateTrigger extends LitElement implements TriggerElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -49,7 +53,7 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _schema = memoizeOne(
|
private _schema = memoizeOne(
|
||||||
(entityId, attribute) =>
|
(localize: LocalizeFunc, entityId, attribute) =>
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
name: "entity_id",
|
name: "entity_id",
|
||||||
@ -117,6 +121,16 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
name: "from",
|
name: "from",
|
||||||
selector: {
|
selector: {
|
||||||
state: {
|
state: {
|
||||||
|
extra_options: (attribute
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
label: localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.any_state_ignore_attributes"
|
||||||
|
),
|
||||||
|
value: ANY_STATE_VALUE,
|
||||||
|
},
|
||||||
|
]) as any,
|
||||||
entity_id: entityId ? entityId[0] : undefined,
|
entity_id: entityId ? entityId[0] : undefined,
|
||||||
attribute: attribute,
|
attribute: attribute,
|
||||||
},
|
},
|
||||||
@ -126,6 +140,16 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
name: "to",
|
name: "to",
|
||||||
selector: {
|
selector: {
|
||||||
state: {
|
state: {
|
||||||
|
extra_options: (attribute
|
||||||
|
? []
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
label: localize(
|
||||||
|
"ui.panel.config.automation.editor.triggers.type.state.any_state_ignore_attributes"
|
||||||
|
),
|
||||||
|
value: ANY_STATE_VALUE,
|
||||||
|
},
|
||||||
|
]) as any,
|
||||||
entity_id: entityId ? entityId[0] : undefined,
|
entity_id: entityId ? entityId[0] : undefined,
|
||||||
attribute: attribute,
|
attribute: attribute,
|
||||||
},
|
},
|
||||||
@ -172,7 +196,17 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
entity_id: ensureArray(this.trigger.entity_id),
|
entity_id: ensureArray(this.trigger.entity_id),
|
||||||
for: trgFor,
|
for: trgFor,
|
||||||
};
|
};
|
||||||
const schema = this._schema(this.trigger.entity_id, this.trigger.attribute);
|
if (!data.attribute && data.to === null) {
|
||||||
|
data.to = ANY_STATE_VALUE;
|
||||||
|
}
|
||||||
|
if (!data.attribute && data.from === null) {
|
||||||
|
data.from = ANY_STATE_VALUE;
|
||||||
|
}
|
||||||
|
const schema = this._schema(
|
||||||
|
this.hass.localize,
|
||||||
|
this.trigger.entity_id,
|
||||||
|
this.trigger.attribute
|
||||||
|
);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-form
|
<ha-form
|
||||||
@ -190,6 +224,13 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
ev.stopPropagation();
|
ev.stopPropagation();
|
||||||
const newTrigger = ev.detail.value;
|
const newTrigger = ev.detail.value;
|
||||||
|
|
||||||
|
if (newTrigger.to === ANY_STATE_VALUE) {
|
||||||
|
newTrigger.to = newTrigger.attribute ? undefined : null;
|
||||||
|
}
|
||||||
|
if (newTrigger.from === ANY_STATE_VALUE) {
|
||||||
|
newTrigger.from = newTrigger.attribute ? undefined : null;
|
||||||
|
}
|
||||||
|
|
||||||
Object.keys(newTrigger).forEach((key) =>
|
Object.keys(newTrigger).forEach((key) =>
|
||||||
newTrigger[key] === undefined || newTrigger[key] === ""
|
newTrigger[key] === undefined || newTrigger[key] === ""
|
||||||
? delete newTrigger[key]
|
? delete newTrigger[key]
|
||||||
|
@ -2301,7 +2301,8 @@
|
|||||||
"attribute": "Attribute (optional)",
|
"attribute": "Attribute (optional)",
|
||||||
"from": "From (optional)",
|
"from": "From (optional)",
|
||||||
"for": "For",
|
"for": "For",
|
||||||
"to": "To (optional)"
|
"to": "To (optional)",
|
||||||
|
"any_state_ignore_attributes": "Any state (ignoring attribute changes)"
|
||||||
},
|
},
|
||||||
"homeassistant": {
|
"homeassistant": {
|
||||||
"label": "Home Assistant",
|
"label": "Home Assistant",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user