State Trigger -> HA Form (#11631)

Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
Zack Barett 2022-02-10 09:26:28 -06:00 committed by GitHub
parent 0eeed85193
commit cefa2ee183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
7 changed files with 97 additions and 59 deletions

View File

@ -26,6 +26,11 @@ export class HaBaseTimeInput extends LitElement {
*/
@property({ type: Boolean }) autoValidate = false;
/**
* determines if inputs are required
*/
@property({ type: Boolean }) public required?: boolean;
/**
* 12 or 24 hr format
*/
@ -115,7 +120,7 @@ export class HaBaseTimeInput extends LitElement {
@input=${this._valueChanged}
@focus=${this._onFocus}
no-spinner
required
.required=${this.required}
.autoValidate=${this.autoValidate}
maxlength="2"
.max=${this._hourMax}
@ -135,7 +140,7 @@ export class HaBaseTimeInput extends LitElement {
@focus=${this._onFocus}
name="minutes"
no-spinner
required
.required=${this.required}
.autoValidate=${this.autoValidate}
maxlength="2"
max="59"
@ -156,7 +161,7 @@ export class HaBaseTimeInput extends LitElement {
@focus=${this._onFocus}
name="seconds"
no-spinner
required
.required=${this.required}
.autoValidate=${this.autoValidate}
maxlength="2"
max="59"
@ -177,7 +182,7 @@ export class HaBaseTimeInput extends LitElement {
@focus=${this._onFocus}
name="milliseconds"
no-spinner
required
.required=${this.required}
.autoValidate=${this.autoValidate}
maxlength="3"
max="999"
@ -189,7 +194,7 @@ export class HaBaseTimeInput extends LitElement {
${this.format === 24
? ""
: html`<mwc-select
required
.required=${this.required}
.value=${this.amPm}
.disabled=${this.disabled}
name="amPm"

View File

@ -81,12 +81,12 @@ export class HaForm extends LitElement implements HaFormElement {
: ""}
${"selector" in item
? html`<ha-selector
.schema=${item}
.hass=${this.hass}
.selector=${item.selector}
.value=${getValue(this.data, item)}
.label=${this._computeLabel(item)}
.disabled=${this.disabled}
.required=${item.required}
></ha-selector>`
: dynamicElement(`ha-form-${item.type}`, {
schema: item,

View 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;
}
}

View File

@ -22,6 +22,8 @@ export class HaTextSelector extends LitElement {
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = true;
@state() private _unmaskedPassword = false;
protected render() {
@ -35,7 +37,7 @@ export class HaTextSelector extends LitElement {
autocapitalize="none"
autocomplete="off"
spellcheck="false"
required
.required=${this.required}
autogrow
></ha-textarea>`;
}
@ -50,7 +52,7 @@ export class HaTextSelector extends LitElement {
? // reserve some space for the icon.
html`<div style="width: 24px"></div>`
: this.selector.text?.suffix}
required
.required=${this.required}
></ha-textfield>
${this.selector.text?.type === "password"
? html`<ha-icon-button

View File

@ -15,6 +15,7 @@ import "./ha-selector-select";
import "./ha-selector-target";
import "./ha-selector-text";
import "./ha-selector-time";
import "./ha-selector-duration";
@customElement("ha-selector")
export class HaSelector extends LitElement {
@ -30,6 +31,8 @@ export class HaSelector extends LitElement {
@property({ type: Boolean }) public disabled = false;
@property({ type: Boolean }) public required = true;
public focus() {
this.shadowRoot?.getElementById("selector")?.focus();
}
@ -47,6 +50,7 @@ export class HaSelector extends LitElement {
label: this.label,
placeholder: this.placeholder,
disabled: this.disabled,
required: this.required,
id: "selector",
})}
`;

View File

@ -31,6 +31,11 @@ export interface DeviceSelector {
};
}
export interface DurationSelector {
// eslint-disable-next-line @typescript-eslint/ban-types
duration: {};
}
export interface AddonSelector {
addon: {
name?: string;

View File

@ -1,4 +1,3 @@
import "@polymer/paper-input/paper-input";
import { html, LitElement, PropertyValues } from "lit";
import { customElement, property } from "lit/decorators";
import {
@ -10,19 +9,15 @@ import {
string,
union,
} from "superstruct";
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { fireEvent } from "../../../../../common/dom/fire_event";
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 { HomeAssistant } from "../../../../../types";
import { baseTriggerStruct, forDictStruct } from "../../structs";
import {
handleChangeEvent,
TriggerElement,
} from "../ha-automation-trigger-row";
import { TriggerElement } from "../ha-automation-trigger-row";
import "../../../../../components/ha-form/ha-form";
import { createDurationData } from "../../../../../common/datetime/create_duration_data";
import { HaFormSchema } from "../../../../../components/ha-form/types";
const stateTriggerStruct = assign(
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")
export class HaStateTrigger extends LitElement implements TriggerElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -76,57 +78,40 @@ export class HaStateTrigger extends LitElement implements TriggerElement {
}
protected render() {
const { entity_id, attribute, to, from } = this.trigger;
const trgFor = createDurationData(this.trigger.for);
const data = { ...this.trigger, ...{ for: trgFor } };
return html`
<ha-entity-picker
.value=${entity_id}
@value-changed=${this._valueChanged}
.name=${"entity_id"}
<ha-form
.hass=${this.hass}
allow-custom-entity
></ha-entity-picker>
<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"
)}
.data=${data}
.schema=${SCHEMA}
@value-changed=${this._valueChanged}
allow-custom-value
></ha-entity-attribute-picker>
<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>
.computeLabel=${this._computeLabelCallback}
></ha-form>
`;
}
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}`
);
}
}