Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 10 additions & 6 deletions js/editor/automation.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { h, Component } from 'preact';

import Trigger from './trigger';
import Condition from './condition';
import Script from './script';

export default class Automation extends Component {
Expand All @@ -9,6 +10,7 @@ export default class Automation extends Component {

this.onChange = this.onChange.bind(this);
this.triggerChanged = this.triggerChanged.bind(this);
this.conditionChanged = this.conditionChanged.bind(this);
this.actionChanged = this.actionChanged.bind(this);
}

Expand All @@ -26,6 +28,13 @@ export default class Automation extends Component {
});
}

conditionChanged(condition) {
this.props.onChange({
...this.props.automation,
condition,
});
}

actionChanged(action) {
this.props.onChange({
...this.props.automation,
Expand Down Expand Up @@ -83,12 +92,7 @@ export default class Automation extends Component {
Learn more about conditions.
</a></p>
</span>
<paper-card>
<div class='card-content'>
Conditions are not supported yet.
<pre>{JSON.stringify(condition, null, 2)}</pre>
</div>
</paper-card>
<Condition condition={condition} onChange={this.conditionChanged} />
</ha-config-section>}

<ha-config-section is-wide={isWide}>
Expand Down
71 changes: 71 additions & 0 deletions js/editor/condition/condition_edit.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
import { h, Component } from 'preact';

import NumericStateCondition from './numeric_state';
import StateCondition from './state';
import SunCondition from './sun';
import TemplateCondition from './template';
import TimeCondition from './time';
import ZoneCondition from './zone';

const TYPES = {
state: StateCondition,
numeric_state: NumericStateCondition,
sun: SunCondition,
template: TemplateCondition,
time: TimeCondition,
zone: ZoneCondition,
};

const OPTIONS = Object.keys(TYPES).sort();

export default class ConditionRow extends Component {
constructor() {
super();

this.typeChanged = this.typeChanged.bind(this);
}

typeChanged(ev) {
const type = ev.target.selectedItem.innerHTML;

if (type !== this.props.condition.condition) {
this.props.onChange(this.props.index, {
condition: type,
...TYPES[type].defaultConfig
});
}
}

render({ index, condition, onChange }) {
const Comp = TYPES[condition.condition];
const selected = OPTIONS.indexOf(condition.condition);

if (!Comp) {
return (
<div>
Unsupported condition: {condition.condition}
<pre>{JSON.stringify(condition, null, 2)}</pre>
</div>
);
}

return (
<div>
<paper-dropdown-menu-light label="Condition Type" no-animations>
<paper-listbox
slot="dropdown-content"
selected={selected}
oniron-select={this.typeChanged}
>
{OPTIONS.map(opt => <paper-item>{opt}</paper-item>)}
</paper-listbox>
</paper-dropdown-menu-light>
<Comp
index={index}
condition={condition}
onChange={onChange}
/>
</div>
);
}
}
45 changes: 45 additions & 0 deletions js/editor/condition/condition_row.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import { h, Component } from 'preact';

import ConditionEdit from './condition_edit';

export default class ConditionRow extends Component {
constructor() {
super();

this.onDelete = this.onDelete.bind(this);
}

onDelete() {
// eslint-disable-next-line
if (confirm('Sure you want to delete?')) {
this.props.onChange(this.props.index, null);
}
}

render(props) {
return (
<paper-card>
<div class='card-menu'>
<paper-menu-button
no-animations
horizontal-align="right"
horizontal-offset="-5"
vertical-offset="-5"
>
<paper-icon-button
icon="mdi:dots-vertical"
slot="dropdown-trigger"
/>
<paper-listbox slot="dropdown-content">
<paper-item disabled>Duplicate</paper-item>
<paper-item onTap={this.onDelete}>Delete</paper-item>
</paper-listbox>
</paper-menu-button>
</div>
<div class='card-content'>
<ConditionEdit {...props} />
</div>
</paper-card>
);
}
}
50 changes: 50 additions & 0 deletions js/editor/condition/index.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
import { h, Component } from 'preact';

import ConditionRow from './condition_row';

export default class Condition extends Component {
constructor() {
super();

this.addCondition = this.addCondition.bind(this);
this.conditionChanged = this.conditionChanged.bind(this);
}

addCondition() {
const condition = this.props.condition.concat({
condition: 'state',
});

this.props.onChange(condition);
}

conditionChanged(index, newValue) {
const condition = this.props.condition.concat();

if (newValue === null) {
condition.splice(index, 1);
} else {
condition[index] = newValue;
}

this.props.onChange(condition);
}

render({ condition }) {
return (
<div class="triggers">
{condition.map((cnd, idx) => (
<ConditionRow
index={idx}
condition={cnd}
onChange={this.conditionChanged}
/>))}
<paper-card>
<div class='card-actions add-card'>
<paper-button onTap={this.addCondition}>Add condition</paper-button>
</div>
</paper-card>
</div>
);
}
}
51 changes: 51 additions & 0 deletions js/editor/condition/numeric_state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
import { h, Component } from 'preact';

import { onChangeEvent } from '../util';

export default class NumericStateCondition extends Component {
constructor() {
super();

this.onChange = onChangeEvent.bind(this, 'condition');
}

/* eslint-disable camelcase */
render({ condition }) {
const { value_template, entity_id, below, above } = condition;
return (
<div>
<paper-input
label="Entity Id"
name="entity_id"
value={entity_id}
onChange={this.onChange}
/>
<paper-input
label="Above"
name="above"
value={above}
onChange={this.onChange}
/>
<paper-input
label="Below"
name="below"
value={below}
onChange={this.onChange}
/>
<paper-textarea
label="Value template (optional)"
name="value_template"
value={value_template}
onvalue-changed={this.onChange}
/>
</div>
);
}
}

NumericStateCondition.defaultConfig = {
entity_id: '',
above: '',
below: '',
value_template: '',
};
39 changes: 39 additions & 0 deletions js/editor/condition/state.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
import { h, Component } from 'preact';

import { onChangeEvent } from '../util';

export default class StateCondition extends Component {
constructor() {
super();

this.onChange = onChangeEvent.bind(this, 'condition');
}

/* eslint-disable camelcase */
render({ condition }) {
const { entity_id, state } = condition;
const cndFor = condition.for;
return (
<div>
<paper-input
label="Entity Id"
name="entity_id"
value={entity_id}
onChange={this.onChange}
/>
<paper-input
label="State"
name="state"
value={state}
onChange={this.onChange}
/>
{cndFor && <pre>For: {JSON.stringify(cndFor, null, 2)}</pre>}
</div>
);
}
}

StateCondition.defaultConfig = {
entity_id: '',
state: '',
};
74 changes: 74 additions & 0 deletions js/editor/condition/sun.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { h, Component } from 'preact';

import { onChangeEvent } from '../util';

export default class SunCondition extends Component {
constructor() {
super();

this.onChange = onChangeEvent.bind(this, 'condition');
this.afterPicked = this.radioGroupPicked.bind(this, 'after');
this.beforePicked = this.radioGroupPicked.bind(this, 'before');
}

radioGroupPicked(key, ev) {
const condition = { ...this.props.condition };

if (ev.target.selected) {
condition[key] = ev.target.value;
} else {
delete condition[key];
}

this.props.onChange(this.props.index, condition);
}

render({ condition }) {
/* eslint-disable camelcase */
const { after, after_offset, before, before_offset } = condition;
return (
<div>
<label id="beforelabel">Before:</label>
<paper-radio-group
allow-empty-selection
selected={before}
aria-labelledby="beforelabel"
onpaper-radio-group-changed={this.beforePicked}
>
<paper-radio-button name="sunrise">Sunrise</paper-radio-button>
<paper-radio-button name="sunset">Sunset</paper-radio-button>
</paper-radio-group>

<paper-input
label="Before offset (optional)"
name="before_offset"
value={before_offset}
onChange={this.onChange}
disabled={before === undefined}
/>

<label id="afterlabel">After:</label>
<paper-radio-group
allow-empty-selection
selected={after}
aria-labelledby="afterlabel"
onpaper-radio-group-changed={this.afterPicked}
>
<paper-radio-button name="sunrise">Sunrise</paper-radio-button>
<paper-radio-button name="sunset">Sunset</paper-radio-button>
</paper-radio-group>

<paper-input
label="After offset (optional)"
name="after_offset"
value={after_offset}
onChange={this.onChange}
disabled={after === undefined}
/>
</div>
);
}
}

SunCondition.defaultConfig = {
};
Loading