From fa8f6b7b911f0448f7e40bd3705d623680483164 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Mon, 2 Dec 2019 14:08:19 +0100 Subject: [PATCH] Add yaml editor to automation actions and scripts (#4306) * Add yaml editor to automation actions and scripts * Add types * Update event.tsx --- src/panels/config/js/automation-component.tsx | 2 +- src/panels/config/js/condition/device.tsx | 2 +- src/panels/config/js/condition/logical.tsx | 2 +- .../config/js/condition/numeric_state.tsx | 2 +- src/panels/config/js/condition/state.tsx | 2 +- src/panels/config/js/condition/sun.tsx | 2 +- src/panels/config/js/condition/template.tsx | 2 +- src/panels/config/js/condition/time.tsx | 2 +- src/panels/config/js/condition/zone.tsx | 2 +- src/panels/config/js/script/action_edit.tsx | 28 +++++++++++++------ src/panels/config/js/script/action_row.tsx | 28 +++++++++++++++++-- src/panels/config/js/script/call_service.tsx | 11 ++++++-- src/panels/config/js/script/delay.tsx | 5 ++-- src/panels/config/js/script/device.tsx | 15 ++++++++-- src/panels/config/js/script/event.tsx | 9 ++++-- src/panels/config/js/script/scene.tsx | 5 ++-- src/panels/config/js/script/wait.tsx | 5 ++-- src/panels/config/js/trigger/device.tsx | 2 +- src/panels/config/js/trigger/event.tsx | 2 +- src/panels/config/js/trigger/geo_location.tsx | 2 +- .../config/js/trigger/homeassistant.tsx | 2 +- src/panels/config/js/trigger/mqtt.tsx | 2 +- .../config/js/trigger/numeric_state.tsx | 2 +- src/panels/config/js/trigger/state.tsx | 2 +- src/panels/config/js/trigger/sun.tsx | 2 +- src/panels/config/js/trigger/template.tsx | 2 +- src/panels/config/js/trigger/time.tsx | 2 +- src/panels/config/js/trigger/time_pattern.tsx | 2 +- src/panels/config/js/trigger/webhook.tsx | 2 +- src/panels/config/js/trigger/zone.tsx | 2 +- 30 files changed, 105 insertions(+), 45 deletions(-) diff --git a/src/panels/config/js/automation-component.tsx b/src/panels/config/js/automation-component.tsx index 05104f6360..1facca8f27 100644 --- a/src/panels/config/js/automation-component.tsx +++ b/src/panels/config/js/automation-component.tsx @@ -1,6 +1,6 @@ import { h, Component, ComponentChild } from "preact"; -export class AutomationComponent extends Component { +export class AutomationComponent

extends Component { // @ts-ignore protected initialized: boolean; diff --git a/src/panels/config/js/condition/device.tsx b/src/panels/config/js/condition/device.tsx index 8a899e7bf4..fb93f9ae6a 100644 --- a/src/panels/config/js/condition/device.tsx +++ b/src/panels/config/js/condition/device.tsx @@ -11,7 +11,7 @@ import { import { AutomationComponent } from "../automation-component"; -export default class DeviceCondition extends AutomationComponent { +export default class DeviceCondition extends AutomationComponent { private _origCondition; constructor() { diff --git a/src/panels/config/js/condition/logical.tsx b/src/panels/config/js/condition/logical.tsx index 0341921b84..8484b155be 100644 --- a/src/panels/config/js/condition/logical.tsx +++ b/src/panels/config/js/condition/logical.tsx @@ -3,7 +3,7 @@ import { h } from "preact"; import Condition from "./index"; import { AutomationComponent } from "../automation-component"; -export default class LogicalCondition extends AutomationComponent { +export default class LogicalCondition extends AutomationComponent { constructor() { super(); this.conditionChanged = this.conditionChanged.bind(this); diff --git a/src/panels/config/js/condition/numeric_state.tsx b/src/panels/config/js/condition/numeric_state.tsx index 0ca3660af3..a850d3098b 100644 --- a/src/panels/config/js/condition/numeric_state.tsx +++ b/src/panels/config/js/condition/numeric_state.tsx @@ -6,7 +6,7 @@ import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class NumericStateCondition extends AutomationComponent { +export default class NumericStateCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/condition/state.tsx b/src/panels/config/js/condition/state.tsx index 91f06e88dc..4c6e5d8dbc 100644 --- a/src/panels/config/js/condition/state.tsx +++ b/src/panels/config/js/condition/state.tsx @@ -5,7 +5,7 @@ import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class StateCondition extends AutomationComponent { +export default class StateCondition extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/condition/sun.tsx b/src/panels/config/js/condition/sun.tsx index ee3f9b9fef..104e9f7b27 100644 --- a/src/panels/config/js/condition/sun.tsx +++ b/src/panels/config/js/condition/sun.tsx @@ -6,7 +6,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class SunCondition extends AutomationComponent { +export default class SunCondition extends AutomationComponent { private onChange: (obj: any) => void; private afterPicked: (obj: any) => void; private beforePicked: (obj: any) => void; diff --git a/src/panels/config/js/condition/template.tsx b/src/panels/config/js/condition/template.tsx index 1a0ee07f2e..4d73ff2913 100644 --- a/src/panels/config/js/condition/template.tsx +++ b/src/panels/config/js/condition/template.tsx @@ -4,7 +4,7 @@ import "../../../../components/ha-textarea"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class TemplateCondition extends AutomationComponent { +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 0e74ce437f..f9891bc025 100644 --- a/src/panels/config/js/condition/time.tsx +++ b/src/panels/config/js/condition/time.tsx @@ -4,7 +4,7 @@ import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class TimeCondition extends AutomationComponent { +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 5d9c9b6bff..881482f3cb 100644 --- a/src/panels/config/js/condition/zone.tsx +++ b/src/panels/config/js/condition/zone.tsx @@ -9,7 +9,7 @@ function zoneAndLocationFilter(stateObj) { return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone"; } -export default class ZoneCondition extends AutomationComponent { +export default class ZoneCondition extends AutomationComponent { constructor() { super(); diff --git a/src/panels/config/js/script/action_edit.tsx b/src/panels/config/js/script/action_edit.tsx index d7dc398efd..74970d18b0 100644 --- a/src/panels/config/js/script/action_edit.tsx +++ b/src/panels/config/js/script/action_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 CallServiceAction from "./call_service"; import ConditionAction from "./condition"; import DelayAction from "./delay"; @@ -39,6 +41,7 @@ export default class Action extends Component { super(); this.typeChanged = this.typeChanged.bind(this); + this.onYamlChange = this.onYamlChange.bind(this); } public typeChanged(ev) { @@ -50,25 +53,30 @@ export default class Action extends Component { } } - public render({ index, action, onChange, hass, localize }) { + public render({ index, action, onChange, hass, localize, yamlMode }) { const type = getType(action); // tslint:disable-next-line: variable-name const Comp = type && TYPES[type]; // @ts-ignore const selected = OPTIONS.indexOf(type); - if (!Comp) { + if (yamlMode || !Comp) { return ( -

- {localize( - "ui.panel.config.automation.editor.actions.unsupported_action", - "action", - type +
+ {!Comp && ( +
+ {localize( + "ui.panel.config.automation.editor.actions.unsupported_action", + "action", + type + )} +
)} -
{JSON.stringify(action, null, 2)}
+
); } + return (
{
); } + + private onYamlChange(condition) { + this.props.onChange(this.props.index, condition); + } } diff --git a/src/panels/config/js/script/action_row.tsx b/src/panels/config/js/script/action_row.tsx index 67634a3b97..0073d11e38 100644 --- a/src/panels/config/js/script/action_row.tsx +++ b/src/panels/config/js/script/action_row.tsx @@ -8,10 +8,16 @@ import "../../../../components/ha-card"; import ActionEdit from "./action_edit"; export default class Action 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 Action 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.actions.duplicate" @@ -56,9 +72,15 @@ export default class Action extends Component {
- +
); } + + private switchYamlMode() { + this.setState({ + yamlMode: !this.state.yamlMode, + }); + } } diff --git a/src/panels/config/js/script/call_service.tsx b/src/panels/config/js/script/call_service.tsx index 754171ab6e..2f4ee670f9 100644 --- a/src/panels/config/js/script/call_service.tsx +++ b/src/panels/config/js/script/call_service.tsx @@ -1,9 +1,10 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/ha-service-picker"; import YAMLTextArea from "../yaml_textarea"; +import { AutomationComponent } from "../automation-component"; -export default class CallServiceAction extends Component { +export default class CallServiceAction extends AutomationComponent { constructor() { super(); @@ -12,6 +13,9 @@ export default class CallServiceAction extends Component { } public serviceChanged(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.action, service: ev.target.value, @@ -19,6 +23,9 @@ export default class CallServiceAction extends Component { } public serviceDataChanged(data) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.action, data }); } diff --git a/src/panels/config/js/script/delay.tsx b/src/panels/config/js/script/delay.tsx index 193f0841c1..da78c3b809 100644 --- a/src/panels/config/js/script/delay.tsx +++ b/src/panels/config/js/script/delay.tsx @@ -1,8 +1,9 @@ -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 DelayAction extends Component { +export default class DelayAction extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/script/device.tsx b/src/panels/config/js/script/device.tsx index 6d6c15d706..0a59eedbcd 100644 --- a/src/panels/config/js/script/device.tsx +++ b/src/panels/config/js/script/device.tsx @@ -1,8 +1,9 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/device/ha-device-picker"; import "../../../../components/device/ha-device-action-picker"; import "../../../../components/ha-form/ha-form"; +import { AutomationComponent } from "../automation-component"; import { fetchDeviceActionCapabilities, @@ -11,7 +12,7 @@ import { import { DeviceAction } from "../../../../data/script"; import { HomeAssistant } from "../../../../types"; -export default class DeviceActionEditor extends Component< +export default class DeviceActionEditor extends AutomationComponent< { index: number; action: DeviceAction; @@ -78,6 +79,7 @@ export default class DeviceActionEditor extends Component< } public componentDidMount() { + this.initialized = true; if (!this.state.capabilities) { this._getCapabilities(); } @@ -93,10 +95,16 @@ export default class DeviceActionEditor extends Component< } private devicePicked(ev) { + if (!this.initialized) { + return; + } this.setState({ ...this.state, device_id: ev.target.value }); } private deviceActionPicked(ev) { + if (!this.initialized) { + return; + } let deviceAction = ev.target.value; if ( this._origAction && @@ -117,6 +125,9 @@ export default class DeviceActionEditor extends Component< } private _extraFieldsChanged(ev) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.action, ...ev.detail.value, diff --git a/src/panels/config/js/script/event.tsx b/src/panels/config/js/script/event.tsx index 6a45182e6d..77513d5e9c 100644 --- a/src/panels/config/js/script/event.tsx +++ b/src/panels/config/js/script/event.tsx @@ -1,4 +1,4 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "@polymer/paper-input/paper-input"; import YAMLTextArea from "../yaml_textarea"; @@ -6,6 +6,8 @@ import { onChangeEvent } from "../../../../common/preact/event"; import { LocalizeFunc } from "../../../../common/translations/localize"; import { EventAction } from "../../../../data/script"; +import { AutomationComponent } from "../automation-component"; + interface Props { index: number; action: EventAction; @@ -13,7 +15,7 @@ interface Props { onChange: (index: number, action: EventAction) => void; } -export default class EventActionForm extends Component { +export default class EventActionForm extends AutomationComponent { private onChange: (event: Event) => void; static get defaultConfig(): EventAction { @@ -57,6 +59,9 @@ export default class EventActionForm extends Component { } private serviceDataChanged(eventData) { + if (!this.initialized) { + return; + } this.props.onChange(this.props.index, { ...this.props.action, event_data: eventData, diff --git a/src/panels/config/js/script/scene.tsx b/src/panels/config/js/script/scene.tsx index 989fa3b890..7fc52d50c9 100644 --- a/src/panels/config/js/script/scene.tsx +++ b/src/panels/config/js/script/scene.tsx @@ -1,7 +1,8 @@ -import { h, Component } from "preact"; +import { h } from "preact"; import "../../../../components/entity/ha-entity-picker"; +import { AutomationComponent } from "../automation-component"; -export default class SceneAction extends Component { +export default class SceneAction extends AutomationComponent { constructor() { super(); diff --git a/src/panels/config/js/script/wait.tsx b/src/panels/config/js/script/wait.tsx index bfde440211..365d90c8ed 100644 --- a/src/panels/config/js/script/wait.tsx +++ b/src/panels/config/js/script/wait.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 { onChangeEvent } from "../../../../common/preact/event"; +import { AutomationComponent } from "../automation-component"; -export default class WaitAction extends Component { +export default class WaitAction extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/device.tsx b/src/panels/config/js/trigger/device.tsx index 03d5ee3d1b..81e202fc03 100644 --- a/src/panels/config/js/trigger/device.tsx +++ b/src/panels/config/js/trigger/device.tsx @@ -11,7 +11,7 @@ import { import { AutomationComponent } from "../automation-component"; -export default class DeviceTrigger extends AutomationComponent { +export default class DeviceTrigger extends AutomationComponent { private _origTrigger; constructor() { diff --git a/src/panels/config/js/trigger/event.tsx b/src/panels/config/js/trigger/event.tsx index cff15eb95a..da3ab66baf 100644 --- a/src/panels/config/js/trigger/event.tsx +++ b/src/panels/config/js/trigger/event.tsx @@ -6,7 +6,7 @@ import YAMLTextArea from "../yaml_textarea"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class EventTrigger extends AutomationComponent { +export default class EventTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/geo_location.tsx b/src/panels/config/js/trigger/geo_location.tsx index bc4f1060ab..836c04f42b 100644 --- a/src/panels/config/js/trigger/geo_location.tsx +++ b/src/panels/config/js/trigger/geo_location.tsx @@ -7,7 +7,7 @@ import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class GeolocationTrigger extends AutomationComponent { +export default class GeolocationTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/homeassistant.tsx b/src/panels/config/js/trigger/homeassistant.tsx index c6fb1dc721..52bf5ac192 100644 --- a/src/panels/config/js/trigger/homeassistant.tsx +++ b/src/panels/config/js/trigger/homeassistant.tsx @@ -5,7 +5,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { AutomationComponent } from "../automation-component"; -export default class HassTrigger extends AutomationComponent { +export default class HassTrigger extends AutomationComponent { constructor() { super(); diff --git a/src/panels/config/js/trigger/mqtt.tsx b/src/panels/config/js/trigger/mqtt.tsx index a1afdf183a..16cfdb612e 100644 --- a/src/panels/config/js/trigger/mqtt.tsx +++ b/src/panels/config/js/trigger/mqtt.tsx @@ -5,7 +5,7 @@ import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class MQTTTrigger extends AutomationComponent { +export default class MQTTTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor(props) { super(props); diff --git a/src/panels/config/js/trigger/numeric_state.tsx b/src/panels/config/js/trigger/numeric_state.tsx index 35ef709f38..366ee4f32f 100644 --- a/src/panels/config/js/trigger/numeric_state.tsx +++ b/src/panels/config/js/trigger/numeric_state.tsx @@ -8,7 +8,7 @@ import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class NumericStateTrigger extends AutomationComponent { +export default class NumericStateTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor(props) { super(props); diff --git a/src/panels/config/js/trigger/state.tsx b/src/panels/config/js/trigger/state.tsx index 10f0065164..6450ccfae3 100644 --- a/src/panels/config/js/trigger/state.tsx +++ b/src/panels/config/js/trigger/state.tsx @@ -6,7 +6,7 @@ import "../../../../components/entity/ha-entity-picker"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class StateTrigger extends AutomationComponent { +export default class StateTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor(props) { super(props); diff --git a/src/panels/config/js/trigger/sun.tsx b/src/panels/config/js/trigger/sun.tsx index ea70569923..c8d9b01616 100644 --- a/src/panels/config/js/trigger/sun.tsx +++ b/src/panels/config/js/trigger/sun.tsx @@ -7,7 +7,7 @@ import "@polymer/paper-radio-group/paper-radio-group"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class SunTrigger extends AutomationComponent { +export default class SunTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/template.tsx b/src/panels/config/js/trigger/template.tsx index 0d9a3526f0..aa25103043 100644 --- a/src/panels/config/js/trigger/template.tsx +++ b/src/panels/config/js/trigger/template.tsx @@ -5,7 +5,7 @@ import "../../../../components/ha-textarea"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class TemplateTrigger extends AutomationComponent { +export default class TemplateTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/time.tsx b/src/panels/config/js/trigger/time.tsx index a8ab6f7d30..70a2c718c6 100644 --- a/src/panels/config/js/trigger/time.tsx +++ b/src/panels/config/js/trigger/time.tsx @@ -5,7 +5,7 @@ import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class TimeTrigger extends AutomationComponent { +export default class TimeTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/time_pattern.tsx b/src/panels/config/js/trigger/time_pattern.tsx index 2738810cb2..e56c5e1a5d 100644 --- a/src/panels/config/js/trigger/time_pattern.tsx +++ b/src/panels/config/js/trigger/time_pattern.tsx @@ -5,7 +5,7 @@ import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class TimePatternTrigger extends AutomationComponent { +export default class TimePatternTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/webhook.tsx b/src/panels/config/js/trigger/webhook.tsx index 5775895c33..59806e65fa 100644 --- a/src/panels/config/js/trigger/webhook.tsx +++ b/src/panels/config/js/trigger/webhook.tsx @@ -5,7 +5,7 @@ import "@polymer/paper-input/paper-input"; import { onChangeEvent } from "../../../../common/preact/event"; import { AutomationComponent } from "../automation-component"; -export default class WebhookTrigger extends AutomationComponent { +export default class WebhookTrigger extends AutomationComponent { private onChange: (obj: any) => void; constructor() { super(); diff --git a/src/panels/config/js/trigger/zone.tsx b/src/panels/config/js/trigger/zone.tsx index abf54237bd..81914a3d52 100644 --- a/src/panels/config/js/trigger/zone.tsx +++ b/src/panels/config/js/trigger/zone.tsx @@ -12,7 +12,7 @@ function zoneAndLocationFilter(stateObj) { return hasLocation(stateObj) && computeStateDomain(stateObj) !== "zone"; } -export default class ZoneTrigger extends AutomationComponent { +export default class ZoneTrigger extends AutomationComponent { constructor() { super();