From 94c120cdb11fce19c546849397701e31a708729e Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 2 Dec 2019 12:02:35 +0100 Subject: [PATCH] Add yaml editor to automation conditions (#4305) --- .../config/js/condition/condition_edit.tsx | 27 ++++++++++++------ .../config/js/condition/condition_row.tsx | 28 +++++++++++++++++-- src/panels/config/js/condition/device.tsx | 17 +++++++++-- src/panels/config/js/condition/logical.tsx | 25 ++++++----------- .../config/js/condition/numeric_state.tsx | 8 ++++-- src/panels/config/js/condition/state.tsx | 8 ++++-- src/panels/config/js/condition/sun.tsx | 8 ++++-- src/panels/config/js/condition/template.tsx | 5 ++-- src/panels/config/js/condition/time.tsx | 5 ++-- src/panels/config/js/condition/zone.tsx | 12 ++++++-- 10 files changed, 102 insertions(+), 41 deletions(-) diff --git a/src/panels/config/js/condition/condition_edit.tsx b/src/panels/config/js/condition/condition_edit.tsx index 2ffd01ef9d..2eb2107713 100644 --- a/src/panels/config/js/condition/condition_edit.tsx +++ b/src/panels/config/js/condition/condition_edit.tsx @@ -3,6 +3,8 @@ import "@polymer/paper-dropdown-menu/paper-dropdown-menu-light"; import "@polymer/paper-listbox/paper-listbox"; import "@polymer/paper-item/paper-item"; +import YAMLTextArea from "../yaml_textarea"; + import DeviceCondition from "./device"; import LogicalCondition from "./logical"; import NumericStateCondition from "./numeric_state"; @@ -31,6 +33,7 @@ export default class ConditionEdit extends Component { super(); this.typeChanged = this.typeChanged.bind(this); + this.onYamlChange = this.onYamlChange.bind(this); } public typeChanged(ev) { @@ -44,20 +47,24 @@ export default class ConditionEdit extends Component { } } - public render({ index, condition, onChange, hass, localize }) { + public render({ index, condition, onChange, hass, localize, yamlMode }) { // tslint:disable-next-line: variable-name const Comp = TYPES[condition.condition]; const selected = OPTIONS.indexOf(condition.condition); - if (!Comp) { + if (yamlMode || !Comp) { return ( -
- {localize( - "ui.panel.config.automation.editor.conditions.unsupported_condition", - "condition", - condition.condition +
+ {!Comp && ( +
+ {localize( + "ui.panel.config.automation.editor.conditions.unsupported_condition", + "condition", + condition.condition + )} +
)} -
{JSON.stringify(condition, null, 2)}
+
); } @@ -94,4 +101,8 @@ export default class ConditionEdit extends Component {
); } + + private onYamlChange(condition) { + this.props.onChange(this.props.index, condition); + } } diff --git a/src/panels/config/js/condition/condition_row.tsx b/src/panels/config/js/condition/condition_row.tsx index c0cd7821de..386b469a0d 100644 --- a/src/panels/config/js/condition/condition_row.tsx +++ b/src/panels/config/js/condition/condition_row.tsx @@ -8,10 +8,16 @@ import "../../../../components/ha-card"; import ConditionEdit from "./condition_edit"; export default class ConditionRow extends Component { + public state: { yamlMode: boolean }; constructor() { super(); + this.state = { + yamlMode: false, + }; + this.onDelete = this.onDelete.bind(this); + this.switchYamlMode = this.switchYamlMode.bind(this); } public onDelete() { @@ -27,22 +33,32 @@ export default class ConditionRow extends Component { } } - public render(props) { + public render(props, { yamlMode }) { return (
-
+
+ + {yamlMode + ? props.localize( + "ui.panel.config.automation.editor.edit_ui" + ) + : props.localize( + "ui.panel.config.automation.editor.edit_yaml" + )} + {props.localize( "ui.panel.config.automation.editor.conditions.duplicate" @@ -56,9 +72,15 @@ export default class ConditionRow extends Component {
- +
); } + + private switchYamlMode() { + this.setState({ + yamlMode: !this.state.yamlMode, + }); + } } diff --git a/src/panels/config/js/condition/device.tsx b/src/panels/config/js/condition/device.tsx index ab30462f7b..8a899e7bf4 100644 --- a/src/panels/config/js/condition/device.tsx +++ b/src/panels/config/js/condition/device.tsx @@ -1,4 +1,4 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/device/ha-device-picker"; import "../../../../components/device/ha-device-condition-picker"; @@ -8,7 +8,10 @@ import { fetchDeviceConditionCapabilities, deviceAutomationsEqual, } from "../../../../data/device_automation"; -export default class DeviceCondition extends Component { + +import { AutomationComponent } from "../automation-component"; + +export default class DeviceCondition extends AutomationComponent { private _origCondition; constructor() { @@ -20,10 +23,16 @@ export default class DeviceCondition extends Component { } public devicePicked(ev) { + if (!this.initialized) { + return; + } this.setState({ ...this.state, device_id: ev.target.value }); } public deviceConditionPicked(ev) { + if (!this.initialized) { + return; + } let condition = ev.target.value; if ( this._origCondition && @@ -74,6 +83,7 @@ export default class DeviceCondition extends Component { } public componentDidMount() { + this.initialized = true; if (!this.state.capabilities) { this._getCapabilities(); } @@ -98,6 +108,9 @@ export default class DeviceCondition extends Component { } private _extraFieldsChanged(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.condition, ...ev.detail.value, diff --git a/src/panels/config/js/condition/logical.tsx b/src/panels/config/js/condition/logical.tsx index a81cfedecd..0341921b84 100644 --- a/src/panels/config/js/condition/logical.tsx +++ b/src/panels/config/js/condition/logical.tsx @@ -1,29 +1,22 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import Condition from "./index"; +import { AutomationComponent } from "../automation-component"; -export default class LogicalCondition extends Component { - private _mounted = false; +export default class LogicalCondition extends AutomationComponent { constructor() { super(); this.conditionChanged = this.conditionChanged.bind(this); } public conditionChanged(conditions) { - if (this._mounted) { - this.props.onChange(this.props.index, { - ...this.props.condition, - conditions, - }); + if (!this.initialized) { + return; } - } - - public componentWillMount() { - this._mounted = true; - } - - public componentWillUnmount() { - this._mounted = false; + this.props.onChange(this.props.index, { + ...this.props.condition, + conditions, + }); } /* eslint-disable camelcase */ diff --git a/src/panels/config/js/condition/numeric_state.tsx b/src/panels/config/js/condition/numeric_state.tsx index eb739101aa..0ca3660af3 100644 --- a/src/panels/config/js/condition/numeric_state.tsx +++ b/src/panels/config/js/condition/numeric_state.tsx @@ -1,11 +1,12 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "@polymer/paper-input/paper-input"; import "../../../../components/ha-textarea"; import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class NumericStateCondition extends Component { +export default class NumericStateCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); @@ -15,6 +16,9 @@ export default class NumericStateCondition extends Component { } public entityPicked(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.condition, entity_id: ev.target.value, diff --git a/src/panels/config/js/condition/state.tsx b/src/panels/config/js/condition/state.tsx index 53bb383e15..91f06e88dc 100644 --- a/src/panels/config/js/condition/state.tsx +++ b/src/panels/config/js/condition/state.tsx @@ -1,10 +1,11 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "@polymer/paper-input/paper-input"; import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class StateCondition extends Component { +export default class StateCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); @@ -14,6 +15,9 @@ export default class StateCondition extends Component { } public entityPicked(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.condition, entity_id: ev.target.value, diff --git a/src/panels/config/js/condition/sun.tsx b/src/panels/config/js/condition/sun.tsx index 0243e08495..ee3f9b9fef 100644 --- a/src/panels/config/js/condition/sun.tsx +++ b/src/panels/config/js/condition/sun.tsx @@ -1,11 +1,12 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "@polymer/paper-input/paper-input"; import "@polymer/paper-radio-button/paper-radio-button"; import "@polymer/paper-radio-group/paper-radio-group"; import { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class SunCondition extends Component { +export default class SunCondition extends AutomationComponent { private onChange: (obj: any) => void; private afterPicked: (obj: any) => void; private beforePicked: (obj: any) => void; @@ -19,6 +20,9 @@ export default class SunCondition extends Component { } public radioGroupPicked(key, ev) { + if (!this.initialized) { + return; + } const condition = { ...this.props.condition }; if (ev.target.selected) { diff --git a/src/panels/config/js/condition/template.tsx b/src/panels/config/js/condition/template.tsx index f4cd50dc3c..1a0ee07f2e 100644 --- a/src/panels/config/js/condition/template.tsx +++ b/src/panels/config/js/condition/template.tsx @@ -1,9 +1,10 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/ha-textarea"; import { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class TemplateCondition extends Component { +export default class TemplateCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/condition/time.tsx b/src/panels/config/js/condition/time.tsx index 427f81e9b2..0e74ce437f 100644 --- a/src/panels/config/js/condition/time.tsx +++ b/src/panels/config/js/condition/time.tsx @@ -1,9 +1,10 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class TimeCondition extends Component { +export default class TimeCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/condition/zone.tsx b/src/panels/config/js/condition/zone.tsx index 924284dd98..5d9c9b6bff 100644 --- a/src/panels/config/js/condition/zone.tsx +++ b/src/panels/config/js/condition/zone.tsx @@ -1,13 +1,15 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/entity/ha-entity-picker"; import { hasLocation } from "../../../../common/entity/has_location"; import { computeStateDomain } from "../../../../common/entity/compute_state_domain"; +import { AutomationComponent } from "../automation-component"; + function zoneAndLocationFilter(stateObj) { return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone"; } -export default class ZoneCondition extends Component { +export default class ZoneCondition extends AutomationComponent { constructor() { super(); @@ -16,6 +18,9 @@ export default class ZoneCondition extends Component { } public entityPicked(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.condition, entity_id: ev.target.value, @@ -23,6 +28,9 @@ export default class ZoneCondition extends Component { } public zonePicked(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.condition, zone: ev.target.value,