mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
State Trigger -> HA Form (#11631)
Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
0eeed85193
commit
cefa2ee183
@ -26,6 +26,11 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
*/
|
*/
|
||||||
@property({ type: Boolean }) autoValidate = false;
|
@property({ type: Boolean }) autoValidate = false;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* determines if inputs are required
|
||||||
|
*/
|
||||||
|
@property({ type: Boolean }) public required?: boolean;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 12 or 24 hr format
|
* 12 or 24 hr format
|
||||||
*/
|
*/
|
||||||
@ -115,7 +120,7 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
@input=${this._valueChanged}
|
@input=${this._valueChanged}
|
||||||
@focus=${this._onFocus}
|
@focus=${this._onFocus}
|
||||||
no-spinner
|
no-spinner
|
||||||
required
|
.required=${this.required}
|
||||||
.autoValidate=${this.autoValidate}
|
.autoValidate=${this.autoValidate}
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
.max=${this._hourMax}
|
.max=${this._hourMax}
|
||||||
@ -135,7 +140,7 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
@focus=${this._onFocus}
|
@focus=${this._onFocus}
|
||||||
name="minutes"
|
name="minutes"
|
||||||
no-spinner
|
no-spinner
|
||||||
required
|
.required=${this.required}
|
||||||
.autoValidate=${this.autoValidate}
|
.autoValidate=${this.autoValidate}
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
max="59"
|
max="59"
|
||||||
@ -156,7 +161,7 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
@focus=${this._onFocus}
|
@focus=${this._onFocus}
|
||||||
name="seconds"
|
name="seconds"
|
||||||
no-spinner
|
no-spinner
|
||||||
required
|
.required=${this.required}
|
||||||
.autoValidate=${this.autoValidate}
|
.autoValidate=${this.autoValidate}
|
||||||
maxlength="2"
|
maxlength="2"
|
||||||
max="59"
|
max="59"
|
||||||
@ -177,7 +182,7 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
@focus=${this._onFocus}
|
@focus=${this._onFocus}
|
||||||
name="milliseconds"
|
name="milliseconds"
|
||||||
no-spinner
|
no-spinner
|
||||||
required
|
.required=${this.required}
|
||||||
.autoValidate=${this.autoValidate}
|
.autoValidate=${this.autoValidate}
|
||||||
maxlength="3"
|
maxlength="3"
|
||||||
max="999"
|
max="999"
|
||||||
@ -189,7 +194,7 @@ export class HaBaseTimeInput extends LitElement {
|
|||||||
${this.format === 24
|
${this.format === 24
|
||||||
? ""
|
? ""
|
||||||
: html`<mwc-select
|
: html`<mwc-select
|
||||||
required
|
.required=${this.required}
|
||||||
.value=${this.amPm}
|
.value=${this.amPm}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
name="amPm"
|
name="amPm"
|
||||||
|
@ -81,12 +81,12 @@ export class HaForm extends LitElement implements HaFormElement {
|
|||||||
: ""}
|
: ""}
|
||||||
${"selector" in item
|
${"selector" in item
|
||||||
? html`<ha-selector
|
? html`<ha-selector
|
||||||
.schema=${item}
|
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.selector=${item.selector}
|
.selector=${item.selector}
|
||||||
.value=${getValue(this.data, item)}
|
.value=${getValue(this.data, item)}
|
||||||
.label=${this._computeLabel(item)}
|
.label=${this._computeLabel(item)}
|
||||||
.disabled=${this.disabled}
|
.disabled=${this.disabled}
|
||||||
|
.required=${item.required}
|
||||||
></ha-selector>`
|
></ha-selector>`
|
||||||
: dynamicElement(`ha-form-${item.type}`, {
|
: dynamicElement(`ha-form-${item.type}`, {
|
||||||
schema: item,
|
schema: item,
|
||||||
|
37
src/components/ha-selector/ha-selector-duration.ts
Normal file
37
src/components/ha-selector/ha-selector-duration.ts
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import "../ha-duration-input";
|
||||||
|
import { html, LitElement } from "lit";
|
||||||
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { DurationSelector } from "../../data/selector";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
|
||||||
|
@customElement("ha-selector-duration")
|
||||||
|
export class HaTimeDuration extends LitElement {
|
||||||
|
@property() public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public selector!: DurationSelector;
|
||||||
|
|
||||||
|
@property() public value?: string;
|
||||||
|
|
||||||
|
@property() public label?: string;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = true;
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
return html`
|
||||||
|
<ha-duration-input
|
||||||
|
.label=${this.label}
|
||||||
|
.data=${this.value}
|
||||||
|
.disabled=${this.disabled}
|
||||||
|
.required=${this.required}
|
||||||
|
></ha-duration-input>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-selector-duration": HaTimeDuration;
|
||||||
|
}
|
||||||
|
}
|
@ -22,6 +22,8 @@ export class HaTextSelector extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = true;
|
||||||
|
|
||||||
@state() private _unmaskedPassword = false;
|
@state() private _unmaskedPassword = false;
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
@ -35,7 +37,7 @@ export class HaTextSelector extends LitElement {
|
|||||||
autocapitalize="none"
|
autocapitalize="none"
|
||||||
autocomplete="off"
|
autocomplete="off"
|
||||||
spellcheck="false"
|
spellcheck="false"
|
||||||
required
|
.required=${this.required}
|
||||||
autogrow
|
autogrow
|
||||||
></ha-textarea>`;
|
></ha-textarea>`;
|
||||||
}
|
}
|
||||||
@ -50,7 +52,7 @@ export class HaTextSelector extends LitElement {
|
|||||||
? // reserve some space for the icon.
|
? // reserve some space for the icon.
|
||||||
html`<div style="width: 24px"></div>`
|
html`<div style="width: 24px"></div>`
|
||||||
: this.selector.text?.suffix}
|
: this.selector.text?.suffix}
|
||||||
required
|
.required=${this.required}
|
||||||
></ha-textfield>
|
></ha-textfield>
|
||||||
${this.selector.text?.type === "password"
|
${this.selector.text?.type === "password"
|
||||||
? html`<ha-icon-button
|
? html`<ha-icon-button
|
||||||
|
@ -15,6 +15,7 @@ import "./ha-selector-select";
|
|||||||
import "./ha-selector-target";
|
import "./ha-selector-target";
|
||||||
import "./ha-selector-text";
|
import "./ha-selector-text";
|
||||||
import "./ha-selector-time";
|
import "./ha-selector-time";
|
||||||
|
import "./ha-selector-duration";
|
||||||
|
|
||||||
@customElement("ha-selector")
|
@customElement("ha-selector")
|
||||||
export class HaSelector extends LitElement {
|
export class HaSelector extends LitElement {
|
||||||
@ -30,6 +31,8 @@ export class HaSelector extends LitElement {
|
|||||||
|
|
||||||
@property({ type: Boolean }) public disabled = false;
|
@property({ type: Boolean }) public disabled = false;
|
||||||
|
|
||||||
|
@property({ type: Boolean }) public required = true;
|
||||||
|
|
||||||
public focus() {
|
public focus() {
|
||||||
this.shadowRoot?.getElementById("selector")?.focus();
|
this.shadowRoot?.getElementById("selector")?.focus();
|
||||||
}
|
}
|
||||||
@ -47,6 +50,7 @@ export class HaSelector extends LitElement {
|
|||||||
label: this.label,
|
label: this.label,
|
||||||
placeholder: this.placeholder,
|
placeholder: this.placeholder,
|
||||||
disabled: this.disabled,
|
disabled: this.disabled,
|
||||||
|
required: this.required,
|
||||||
id: "selector",
|
id: "selector",
|
||||||
})}
|
})}
|
||||||
`;
|
`;
|
||||||
|
@ -31,6 +31,11 @@ export interface DeviceSelector {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface DurationSelector {
|
||||||
|
// eslint-disable-next-line @typescript-eslint/ban-types
|
||||||
|
duration: {};
|
||||||
|
}
|
||||||
|
|
||||||
export interface AddonSelector {
|
export interface AddonSelector {
|
||||||
addon: {
|
addon: {
|
||||||
name?: string;
|
name?: string;
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import "@polymer/paper-input/paper-input";
|
|
||||||
import { html, LitElement, PropertyValues } from "lit";
|
import { html, LitElement, PropertyValues } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
import {
|
import {
|
||||||
@ -10,19 +9,15 @@ import {
|
|||||||
string,
|
string,
|
||||||
union,
|
union,
|
||||||
} from "superstruct";
|
} from "superstruct";
|
||||||
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
|
||||||
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";
|
||||||
import "../../../../../components/entity/ha-entity-attribute-picker";
|
|
||||||
import "../../../../../components/entity/ha-entity-picker";
|
|
||||||
import "../../../../../components/ha-duration-input";
|
|
||||||
import { StateTrigger } from "../../../../../data/automation";
|
import { StateTrigger } from "../../../../../data/automation";
|
||||||
import { HomeAssistant } from "../../../../../types";
|
import { HomeAssistant } from "../../../../../types";
|
||||||
import { baseTriggerStruct, forDictStruct } from "../../structs";
|
import { baseTriggerStruct, forDictStruct } from "../../structs";
|
||||||
import {
|
import { TriggerElement } from "../ha-automation-trigger-row";
|
||||||
handleChangeEvent,
|
import "../../../../../components/ha-form/ha-form";
|
||||||
TriggerElement,
|
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
|
||||||
} from "../ha-automation-trigger-row";
|
import { HaFormSchema } from "../../../../../components/ha-form/types";
|
||||||
|
|
||||||
const stateTriggerStruct = assign(
|
const stateTriggerStruct = assign(
|
||||||
baseTriggerStruct,
|
baseTriggerStruct,
|
||||||
@ -36,6 +31,13 @@ const stateTriggerStruct = assign(
|
|||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const SCHEMA = [
|
||||||
|
{ name: "entity_id", selector: { entity: {} } },
|
||||||
|
{ name: "from", required: false, selector: { text: {} } },
|
||||||
|
{ name: "to", required: false, selector: { text: {} } },
|
||||||
|
{ name: "for", required: false, selector: { duration: {} } },
|
||||||
|
];
|
||||||
|
|
||||||
@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;
|
||||||
@ -76,57 +78,40 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const { entity_id, attribute, to, from } = this.trigger;
|
|
||||||
const trgFor = createDurationData(this.trigger.for);
|
const trgFor = createDurationData(this.trigger.for);
|
||||||
|
|
||||||
|
const data = { ...this.trigger, ...{ for: trgFor } };
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-entity-picker
|
<ha-form
|
||||||
.value=${entity_id}
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
.name=${"entity_id"}
|
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
allow-custom-entity
|
.data=${data}
|
||||||
></ha-entity-picker>
|
.schema=${SCHEMA}
|
||||||
<ha-entity-attribute-picker
|
|
||||||
.hass=${this.hass}
|
|
||||||
.entityId=${entity_id}
|
|
||||||
.value=${attribute}
|
|
||||||
.name=${"attribute"}
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.state.attribute"
|
|
||||||
)}
|
|
||||||
@value-changed=${this._valueChanged}
|
@value-changed=${this._valueChanged}
|
||||||
allow-custom-value
|
.computeLabel=${this._computeLabelCallback}
|
||||||
></ha-entity-attribute-picker>
|
></ha-form>
|
||||||
<paper-input
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.state.from"
|
|
||||||
)}
|
|
||||||
.name=${"from"}
|
|
||||||
.value=${from}
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></paper-input>
|
|
||||||
<paper-input
|
|
||||||
label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.state.to"
|
|
||||||
)}
|
|
||||||
.name=${"to"}
|
|
||||||
.value=${to}
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></paper-input>
|
|
||||||
<ha-duration-input
|
|
||||||
.label=${this.hass.localize(
|
|
||||||
"ui.panel.config.automation.editor.triggers.type.state.for"
|
|
||||||
)}
|
|
||||||
.name=${"for"}
|
|
||||||
.data=${trgFor}
|
|
||||||
@value-changed=${this._valueChanged}
|
|
||||||
></ha-duration-input>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: CustomEvent): void {
|
private _valueChanged(ev: CustomEvent): void {
|
||||||
handleChangeEvent(this, ev);
|
ev.stopPropagation();
|
||||||
|
const newTrigger = ev.detail.value;
|
||||||
|
|
||||||
|
Object.keys(newTrigger).forEach((key) =>
|
||||||
|
newTrigger[key] === undefined || newTrigger[key] === ""
|
||||||
|
? delete newTrigger[key]
|
||||||
|
: {}
|
||||||
|
);
|
||||||
|
|
||||||
|
fireEvent(this, "value-changed", { value: newTrigger });
|
||||||
|
}
|
||||||
|
|
||||||
|
private _computeLabelCallback(schema: HaFormSchema): string {
|
||||||
|
return this.hass.localize(
|
||||||
|
schema.name === "entity_id"
|
||||||
|
? "ui.components.entity.entity-picker.entity"
|
||||||
|
: `ui.panel.config.automation.editor.triggers.type.state.${schema.name}`
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user