mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-21 10:03:02 +00:00
Compare commits
2 Commits
fix-legacy
...
automation
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2ad4b32fd7 | ||
|
|
0f92d55122 |
132
src/components/ha-selector/ha-selector-automation-behavior.ts
Normal file
132
src/components/ha-selector/ha-selector-automation-behavior.ts
Normal file
@@ -0,0 +1,132 @@
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import type { LocalizeKeys } from "../../common/translations/localize";
|
||||
import type {
|
||||
AutomationBehavior,
|
||||
AutomationBehaviorConditionMode,
|
||||
AutomationBehaviorSelector,
|
||||
AutomationBehaviorTriggerMode,
|
||||
} from "../../data/selector";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import "../ha-formfield";
|
||||
import "../ha-input-helper-text";
|
||||
import "../ha-radio";
|
||||
|
||||
const TRIGGER_BEHAVIORS: AutomationBehaviorTriggerMode[] = [
|
||||
"any",
|
||||
"first",
|
||||
"last",
|
||||
];
|
||||
|
||||
const CONDITION_BEHAVIORS: AutomationBehaviorConditionMode[] = ["any", "all"];
|
||||
|
||||
@customElement("ha-selector-automation_behavior")
|
||||
export class HaSelectorAutomationBehavior extends LitElement {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
|
||||
@property({ attribute: false })
|
||||
public selector!: AutomationBehaviorSelector;
|
||||
|
||||
@property() public value?: AutomationBehavior;
|
||||
|
||||
@property() public label?: string;
|
||||
|
||||
@property() public helper?: string;
|
||||
|
||||
@property({ attribute: false })
|
||||
public localizeValue?: (key: string) => string;
|
||||
|
||||
@property({ type: Boolean }) public disabled = false;
|
||||
|
||||
@property({ type: Boolean }) public required = true;
|
||||
|
||||
protected render() {
|
||||
const behaviors = this._behaviors();
|
||||
|
||||
return html`
|
||||
${this.label ? html`<span class="label">${this.label}</span>` : nothing}
|
||||
<div class="container">
|
||||
${behaviors.map(
|
||||
(behavior) => html`
|
||||
<ha-formfield
|
||||
.label=${this._localizeOption(behavior)}
|
||||
.disabled=${this.disabled}
|
||||
>
|
||||
<ha-radio
|
||||
.checked=${behavior === this.value}
|
||||
.value=${behavior}
|
||||
.disabled=${this.disabled}
|
||||
@change=${this._radioChanged}
|
||||
></ha-radio>
|
||||
</ha-formfield>
|
||||
`
|
||||
)}
|
||||
</div>
|
||||
${this.helper
|
||||
? html`<ha-input-helper-text .disabled=${this.disabled}
|
||||
>${this.helper}</ha-input-helper-text
|
||||
>`
|
||||
: nothing}
|
||||
`;
|
||||
}
|
||||
|
||||
private _behaviors(): AutomationBehavior[] {
|
||||
const mode = this.selector.automation_behavior?.mode;
|
||||
return mode === "condition" ? CONDITION_BEHAVIORS : TRIGGER_BEHAVIORS;
|
||||
}
|
||||
|
||||
private _localizeOption(behavior: AutomationBehavior): string {
|
||||
const { translation_key: translationKey, mode } =
|
||||
this.selector.automation_behavior ?? {};
|
||||
|
||||
if (this.localizeValue && translationKey) {
|
||||
const translated = this.localizeValue(
|
||||
`${translationKey}.options.${behavior}`
|
||||
);
|
||||
if (translated) {
|
||||
return translated;
|
||||
}
|
||||
}
|
||||
return (
|
||||
this.hass.localize(
|
||||
`ui.components.selectors.automation_behavior.${mode ?? "trigger"}.options.${behavior}` as LocalizeKeys
|
||||
) || behavior
|
||||
);
|
||||
}
|
||||
|
||||
private _radioChanged(ev: Event) {
|
||||
ev.stopPropagation();
|
||||
const value = (ev.target as HTMLInputElement).value as AutomationBehavior;
|
||||
if (this.disabled || value === this.value) {
|
||||
return;
|
||||
}
|
||||
fireEvent(this, "value-changed", { value });
|
||||
}
|
||||
|
||||
static styles = css`
|
||||
.label {
|
||||
display: block;
|
||||
margin-bottom: var(--ha-space-2);
|
||||
color: var(--secondary-text-color);
|
||||
font-size: var(--ha-font-size-s);
|
||||
}
|
||||
|
||||
.container {
|
||||
border: 1px solid var(--divider-color);
|
||||
border-radius: var(--ha-border-radius-lg);
|
||||
padding: var(--ha-space-2) var(--ha-space-4);
|
||||
padding-left: 0;
|
||||
}
|
||||
|
||||
ha-formfield {
|
||||
display: block;
|
||||
}
|
||||
`;
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"ha-selector-automation_behavior": HaSelectorAutomationBehavior;
|
||||
}
|
||||
}
|
||||
@@ -13,6 +13,7 @@ import type { HomeAssistant } from "../../types";
|
||||
const LOAD_ELEMENTS = {
|
||||
action: () => import("./ha-selector-action"),
|
||||
addon: () => import("./ha-selector-addon"),
|
||||
automation_behavior: () => import("./ha-selector-automation-behavior"),
|
||||
app: () => import("./ha-selector-app"),
|
||||
area: () => import("./ha-selector-area"),
|
||||
areas_display: () => import("./ha-selector-areas-display"),
|
||||
|
||||
@@ -31,6 +31,7 @@ export type Selector =
|
||||
| AreaSelector
|
||||
| AreasDisplaySelector
|
||||
| AttributeSelector
|
||||
| AutomationBehaviorSelector
|
||||
| BooleanSelector
|
||||
| ButtonToggleSelector
|
||||
| ChooseSelector
|
||||
@@ -122,6 +123,21 @@ export interface BooleanSelector {
|
||||
boolean: {} | null;
|
||||
}
|
||||
|
||||
export type AutomationBehaviorTriggerMode = "first" | "last" | "any";
|
||||
|
||||
export type AutomationBehaviorConditionMode = "all" | "any";
|
||||
|
||||
export type AutomationBehavior =
|
||||
| AutomationBehaviorTriggerMode
|
||||
| AutomationBehaviorConditionMode;
|
||||
|
||||
export interface AutomationBehaviorSelector {
|
||||
automation_behavior: {
|
||||
mode: "trigger" | "condition";
|
||||
translation_key?: string;
|
||||
} | null;
|
||||
}
|
||||
|
||||
export interface ButtonToggleSelector {
|
||||
button_toggle: {
|
||||
options: readonly string[] | readonly SelectOption[];
|
||||
|
||||
@@ -97,7 +97,8 @@ export class HaPlatformCondition extends LitElement {
|
||||
field.default !== undefined &&
|
||||
updatedOptions[key] === undefined &&
|
||||
!(
|
||||
key === "behavior" &&
|
||||
field.selector &&
|
||||
"automation_behavior" in field.selector &&
|
||||
this.description?.target &&
|
||||
!this.condition?.target
|
||||
)
|
||||
@@ -231,7 +232,7 @@ export class HaPlatformCondition extends LitElement {
|
||||
}
|
||||
|
||||
if (
|
||||
fieldName === "behavior" &&
|
||||
"automation_behavior" in selector &&
|
||||
this.description?.target &&
|
||||
(!this.condition?.target ||
|
||||
(this._resolvedTargetEntityCount !== undefined &&
|
||||
@@ -430,14 +431,26 @@ export class HaPlatformCondition extends LitElement {
|
||||
this._resolvedTargetEntityCount =
|
||||
await this._resolveTargetEntityCount(target);
|
||||
|
||||
const behaviorFieldEntry = Object.entries(
|
||||
this.description?.fields ?? {}
|
||||
).find(
|
||||
([, field]) => field.selector && "automation_behavior" in field.selector
|
||||
);
|
||||
|
||||
if (!behaviorFieldEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [behaviorFieldName, behaviorField] = behaviorFieldEntry;
|
||||
|
||||
if (
|
||||
(!target ||
|
||||
(this._resolvedTargetEntityCount !== undefined &&
|
||||
this._resolvedTargetEntityCount <= 1)) &&
|
||||
this.condition.options?.behavior !== undefined
|
||||
this.condition.options?.[behaviorFieldName] !== undefined
|
||||
) {
|
||||
const options = { ...this.condition.options };
|
||||
delete options.behavior;
|
||||
delete options[behaviorFieldName];
|
||||
|
||||
fireEvent(this, "value-changed", {
|
||||
value: {
|
||||
@@ -449,14 +462,17 @@ export class HaPlatformCondition extends LitElement {
|
||||
target &&
|
||||
this._resolvedTargetEntityCount !== undefined &&
|
||||
this._resolvedTargetEntityCount > 1 &&
|
||||
this.condition.options?.behavior === undefined
|
||||
this.condition.options?.[behaviorFieldName] === undefined
|
||||
) {
|
||||
const behaviorDefault = this.description?.fields?.behavior?.default;
|
||||
const behaviorDefault = behaviorField.default;
|
||||
if (behaviorDefault !== undefined) {
|
||||
fireEvent(this, "value-changed", {
|
||||
value: {
|
||||
...this.condition,
|
||||
options: { ...this.condition.options, behavior: behaviorDefault },
|
||||
options: {
|
||||
...this.condition.options,
|
||||
[behaviorFieldName]: behaviorDefault,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -132,7 +132,8 @@ export class HaPlatformTrigger extends LitElement {
|
||||
field.default !== undefined &&
|
||||
updatedOptions[key] === undefined &&
|
||||
!(
|
||||
key === "behavior" &&
|
||||
field.selector &&
|
||||
"automation_behavior" in field.selector &&
|
||||
this.description?.target &&
|
||||
!this.trigger?.target
|
||||
)
|
||||
@@ -267,7 +268,7 @@ export class HaPlatformTrigger extends LitElement {
|
||||
}
|
||||
|
||||
if (
|
||||
fieldName === "behavior" &&
|
||||
"automation_behavior" in selector &&
|
||||
this.description?.target &&
|
||||
(!this.trigger?.target ||
|
||||
(this._resolvedTargetEntityCount !== undefined &&
|
||||
@@ -466,14 +467,26 @@ export class HaPlatformTrigger extends LitElement {
|
||||
this._resolvedTargetEntityCount =
|
||||
await this._resolveTargetEntityCount(target);
|
||||
|
||||
const behaviorFieldEntry = Object.entries(
|
||||
this.description?.fields ?? {}
|
||||
).find(
|
||||
([, field]) => field.selector && "automation_behavior" in field.selector
|
||||
);
|
||||
|
||||
if (!behaviorFieldEntry) {
|
||||
return;
|
||||
}
|
||||
|
||||
const [behaviorFieldName, behaviorField] = behaviorFieldEntry;
|
||||
|
||||
if (
|
||||
(!target ||
|
||||
(this._resolvedTargetEntityCount !== undefined &&
|
||||
this._resolvedTargetEntityCount <= 1)) &&
|
||||
this.trigger.options?.behavior !== undefined
|
||||
this.trigger.options?.[behaviorFieldName] !== undefined
|
||||
) {
|
||||
const options = { ...this.trigger.options };
|
||||
delete options.behavior;
|
||||
delete options[behaviorFieldName];
|
||||
|
||||
fireEvent(this, "value-changed", {
|
||||
value: {
|
||||
@@ -485,14 +498,17 @@ export class HaPlatformTrigger extends LitElement {
|
||||
target &&
|
||||
this._resolvedTargetEntityCount !== undefined &&
|
||||
this._resolvedTargetEntityCount > 1 &&
|
||||
this.trigger.options?.behavior === undefined
|
||||
this.trigger.options?.[behaviorFieldName] === undefined
|
||||
) {
|
||||
const behaviorDefault = this.description?.fields?.behavior?.default;
|
||||
const behaviorDefault = behaviorField.default;
|
||||
if (behaviorDefault !== undefined) {
|
||||
fireEvent(this, "value-changed", {
|
||||
value: {
|
||||
...this.trigger,
|
||||
options: { ...this.trigger.options, behavior: behaviorDefault },
|
||||
options: {
|
||||
...this.trigger.options,
|
||||
[behaviorFieldName]: behaviorDefault,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
|
||||
@@ -583,6 +583,21 @@
|
||||
"between": "In range",
|
||||
"outside": "Outside range"
|
||||
}
|
||||
},
|
||||
"automation_behavior": {
|
||||
"trigger": {
|
||||
"options": {
|
||||
"any": "When any entity gets in the required state",
|
||||
"first": "When the first entity gets in the required state",
|
||||
"last": "When the last entity gets in the required state"
|
||||
}
|
||||
},
|
||||
"condition": {
|
||||
"options": {
|
||||
"any": "When any entity is in the required state",
|
||||
"all": "When all entities are in the required state"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"logbook": {
|
||||
|
||||
Reference in New Issue
Block a user