mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-19 07:16:39 +00:00
Add UI for new script functions (#6491)
This commit is contained in:
parent
ca171afe6f
commit
a2153bc6aa
@ -58,6 +58,31 @@ export interface WaitAction {
|
|||||||
timeout?: number;
|
timeout?: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface RepeatAction {
|
||||||
|
repeat: CountRepeat | WhileRepeat | UntilRepeat;
|
||||||
|
}
|
||||||
|
|
||||||
|
interface BaseRepeat {
|
||||||
|
sequence: Action[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface CountRepeat extends BaseRepeat {
|
||||||
|
count: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface WhileRepeat extends BaseRepeat {
|
||||||
|
while: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface UntilRepeat extends BaseRepeat {
|
||||||
|
until: Condition[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ChooseAction {
|
||||||
|
choose: [{ conditions: Condition[]; sequence: Action[] }];
|
||||||
|
default?: Action[];
|
||||||
|
}
|
||||||
|
|
||||||
export type Action =
|
export type Action =
|
||||||
| EventAction
|
| EventAction
|
||||||
| DeviceAction
|
| DeviceAction
|
||||||
@ -65,7 +90,9 @@ export type Action =
|
|||||||
| Condition
|
| Condition
|
||||||
| DelayAction
|
| DelayAction
|
||||||
| SceneAction
|
| SceneAction
|
||||||
| WaitAction;
|
| WaitAction
|
||||||
|
| RepeatAction
|
||||||
|
| ChooseAction;
|
||||||
|
|
||||||
export const triggerScript = (
|
export const triggerScript = (
|
||||||
hass: HomeAssistant,
|
hass: HomeAssistant,
|
||||||
|
@ -15,6 +15,7 @@ import {
|
|||||||
LitElement,
|
LitElement,
|
||||||
property,
|
property,
|
||||||
internalProperty,
|
internalProperty,
|
||||||
|
PropertyValues,
|
||||||
} from "lit-element";
|
} from "lit-element";
|
||||||
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
import { dynamicElement } from "../../../../common/dom/dynamic-element-directive";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
@ -29,6 +30,8 @@ import "./types/ha-automation-action-event";
|
|||||||
import "./types/ha-automation-action-scene";
|
import "./types/ha-automation-action-scene";
|
||||||
import "./types/ha-automation-action-service";
|
import "./types/ha-automation-action-service";
|
||||||
import "./types/ha-automation-action-wait_template";
|
import "./types/ha-automation-action-wait_template";
|
||||||
|
import "./types/ha-automation-action-repeat";
|
||||||
|
import "./types/ha-automation-action-choose";
|
||||||
import { handleStructError } from "../../../lovelace/common/structs/handle-errors";
|
import { handleStructError } from "../../../lovelace/common/structs/handle-errors";
|
||||||
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
import { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||||
import { haStyle } from "../../../../resources/styles";
|
import { haStyle } from "../../../../resources/styles";
|
||||||
@ -41,6 +44,8 @@ const OPTIONS = [
|
|||||||
"scene",
|
"scene",
|
||||||
"service",
|
"service",
|
||||||
"wait_template",
|
"wait_template",
|
||||||
|
"repeat",
|
||||||
|
"choose",
|
||||||
];
|
];
|
||||||
|
|
||||||
const getType = (action: Action) => {
|
const getType = (action: Action) => {
|
||||||
@ -96,6 +101,16 @@ export default class HaAutomationActionRow extends LitElement {
|
|||||||
|
|
||||||
@internalProperty() private _yamlMode = false;
|
@internalProperty() private _yamlMode = false;
|
||||||
|
|
||||||
|
protected updated(changedProperties: PropertyValues) {
|
||||||
|
if (!changedProperties.has("action")) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this._uiModeAvailable = Boolean(getType(this.action));
|
||||||
|
if (!this._uiModeAvailable && !this._yamlMode) {
|
||||||
|
this._yamlMode = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected render() {
|
protected render() {
|
||||||
const type = getType(this.action);
|
const type = getType(this.action);
|
||||||
const selected = type ? OPTIONS.indexOf(type) : -1;
|
const selected = type ? OPTIONS.indexOf(type) : -1;
|
||||||
|
@ -0,0 +1,176 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import {
|
||||||
|
customElement,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
CSSResult,
|
||||||
|
css,
|
||||||
|
} from "lit-element";
|
||||||
|
import { html } from "lit-html";
|
||||||
|
import { Action, ChooseAction } from "../../../../../data/script";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { ActionElement } from "../ha-automation-action-row";
|
||||||
|
import "../../condition/ha-automation-condition-editor";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../ha-automation-action";
|
||||||
|
import { Condition } from "../../../../../data/automation";
|
||||||
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
|
import { mdiDelete } from "@mdi/js";
|
||||||
|
|
||||||
|
@customElement("ha-automation-action-choose")
|
||||||
|
export class HaChooseAction extends LitElement implements ActionElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property() public action!: ChooseAction;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { choose: [{ conditions: [], sequence: [] }], default: [] };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const action = this.action;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
${action.choose.map(
|
||||||
|
(option, idx) => html`<ha-card>
|
||||||
|
<mwc-icon-button
|
||||||
|
.idx=${idx}
|
||||||
|
@click=${this._removeOption}
|
||||||
|
title=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.remove_option"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-svg-icon path=${mdiDelete}></ha-svg-icon>
|
||||||
|
</mwc-icon-button>
|
||||||
|
<div class="card-content">
|
||||||
|
<h2>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.option",
|
||||||
|
"number",
|
||||||
|
idx + 1
|
||||||
|
)}:
|
||||||
|
</h2>
|
||||||
|
<h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.conditions"
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-automation-condition
|
||||||
|
.conditions=${option.conditions}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.idx=${idx}
|
||||||
|
@value-changed=${this._conditionChanged}
|
||||||
|
></ha-automation-condition>
|
||||||
|
<h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.sequence"
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-automation-action
|
||||||
|
.actions=${option.sequence}
|
||||||
|
.hass=${this.hass}
|
||||||
|
.idx=${idx}
|
||||||
|
@value-changed=${this._actionChanged}
|
||||||
|
></ha-automation-action>
|
||||||
|
</div>
|
||||||
|
</ha-card>`
|
||||||
|
)}
|
||||||
|
<ha-card>
|
||||||
|
<div class="card-actions add-card">
|
||||||
|
<mwc-button @click=${this._addOption}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.add_option"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
</div>
|
||||||
|
</ha-card>
|
||||||
|
<h2>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.choose.default"
|
||||||
|
)}:
|
||||||
|
</h2>
|
||||||
|
<ha-automation-action
|
||||||
|
.actions=${action.default || []}
|
||||||
|
@value-changed=${this._defaultChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-automation-action>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _conditionChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value as Condition[];
|
||||||
|
const index = (ev.target as any).idx;
|
||||||
|
const choose = [...this.action.choose];
|
||||||
|
choose[index].conditions = value;
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, choose },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _actionChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value as Action[];
|
||||||
|
const index = (ev.target as any).idx;
|
||||||
|
const choose = [...this.action.choose];
|
||||||
|
choose[index].sequence = value;
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, choose },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _addOption() {
|
||||||
|
const choose = [...this.action.choose];
|
||||||
|
choose.push({ conditions: [], sequence: [] });
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, choose },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _removeOption(ev: CustomEvent) {
|
||||||
|
const index = (ev.currentTarget as any).idx;
|
||||||
|
const choose = [...this.action.choose];
|
||||||
|
choose.splice(index, 1);
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: { ...this.action, choose },
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _defaultChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value as Action[];
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
...this.action,
|
||||||
|
default: value,
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
haStyle,
|
||||||
|
css`
|
||||||
|
ha-card {
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
.add-card mwc-button {
|
||||||
|
display: block;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
mwc-icon-button {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-action-choose": HaChooseAction;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,180 @@
|
|||||||
|
import "@polymer/paper-input/paper-input";
|
||||||
|
import { customElement, LitElement, property, CSSResult } from "lit-element";
|
||||||
|
import { html } from "lit-html";
|
||||||
|
import {
|
||||||
|
RepeatAction,
|
||||||
|
Action,
|
||||||
|
CountRepeat,
|
||||||
|
WhileRepeat,
|
||||||
|
UntilRepeat,
|
||||||
|
} from "../../../../../data/script";
|
||||||
|
import { HomeAssistant } from "../../../../../types";
|
||||||
|
import { ActionElement } from "../ha-automation-action-row";
|
||||||
|
import "../../condition/ha-automation-condition-editor";
|
||||||
|
import type { PaperListboxElement } from "@polymer/paper-listbox";
|
||||||
|
import "@polymer/paper-listbox/paper-listbox";
|
||||||
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
|
import "../ha-automation-action";
|
||||||
|
import { Condition } from "../../../../lovelace/common/validate-condition";
|
||||||
|
import { haStyle } from "../../../../../resources/styles";
|
||||||
|
|
||||||
|
const OPTIONS = ["count", "while", "until"];
|
||||||
|
|
||||||
|
const getType = (action) => {
|
||||||
|
return OPTIONS.find((option) => option in action);
|
||||||
|
};
|
||||||
|
|
||||||
|
@customElement("ha-automation-action-repeat")
|
||||||
|
export class HaRepeatAction extends LitElement implements ActionElement {
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public action!: RepeatAction;
|
||||||
|
|
||||||
|
public static get defaultConfig() {
|
||||||
|
return { repeat: { count: 2, sequence: [] } };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected render() {
|
||||||
|
const action = this.action.repeat;
|
||||||
|
|
||||||
|
const type = getType(action);
|
||||||
|
const selected = type ? OPTIONS.indexOf(type) : -1;
|
||||||
|
|
||||||
|
return html`
|
||||||
|
<paper-dropdown-menu-light
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.repeat.type_select"
|
||||||
|
)}
|
||||||
|
no-animations
|
||||||
|
>
|
||||||
|
<paper-listbox
|
||||||
|
slot="dropdown-content"
|
||||||
|
.selected=${selected}
|
||||||
|
@iron-select=${this._typeChanged}
|
||||||
|
>
|
||||||
|
${OPTIONS.map(
|
||||||
|
(opt) => html`
|
||||||
|
<paper-item .action=${opt}>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.automation.editor.actions.type.repeat.type.${opt}.label`
|
||||||
|
)}
|
||||||
|
</paper-item>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu-light>
|
||||||
|
${type === "count"
|
||||||
|
? html`<paper-input
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.repeat.type.count.label"
|
||||||
|
)}
|
||||||
|
name="count"
|
||||||
|
.value=${(action as CountRepeat).count || "0"}
|
||||||
|
@value-changed=${this._countChanged}
|
||||||
|
></paper-input>`
|
||||||
|
: ""}
|
||||||
|
${type === "while"
|
||||||
|
? html` <h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.automation.editor.actions.type.repeat.type.while.conditions`
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-automation-condition
|
||||||
|
.conditions=${(action as WhileRepeat).while || []}
|
||||||
|
.hass=${this.hass}
|
||||||
|
@value-changed=${this._conditionChanged}
|
||||||
|
></ha-automation-condition>`
|
||||||
|
: ""}
|
||||||
|
${type === "until"
|
||||||
|
? html` <h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.automation.editor.actions.type.repeat.type.until.conditions`
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-automation-condition
|
||||||
|
.conditions=${(action as UntilRepeat).until || []}
|
||||||
|
.hass=${this.hass}
|
||||||
|
@value-changed=${this._conditionChanged}
|
||||||
|
></ha-automation-condition>`
|
||||||
|
: ""}
|
||||||
|
<h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.editor.actions.type.repeat.sequence"
|
||||||
|
)}:
|
||||||
|
</h3>
|
||||||
|
<ha-automation-action
|
||||||
|
.actions=${action.sequence}
|
||||||
|
@value-changed=${this._actionChanged}
|
||||||
|
.hass=${this.hass}
|
||||||
|
></ha-automation-action>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _typeChanged(ev: CustomEvent) {
|
||||||
|
const type = ((ev.target as PaperListboxElement)?.selectedItem as any)
|
||||||
|
?.action;
|
||||||
|
|
||||||
|
if (!type || type === getType(this.action.repeat)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const value = type === "count" ? 2 : [];
|
||||||
|
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
repeat: { [type]: value, sequence: this.action.repeat.sequence },
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _conditionChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value as Condition[];
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
repeat: {
|
||||||
|
...this.action.repeat,
|
||||||
|
[getType(this.action.repeat)!]: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _actionChanged(ev: CustomEvent) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const value = ev.detail.value as Action[];
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
repeat: {
|
||||||
|
...this.action.repeat,
|
||||||
|
sequence: value,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _countChanged(ev: CustomEvent): void {
|
||||||
|
const newVal = ev.detail.value;
|
||||||
|
if ((this.action.repeat as CountRepeat).count === newVal) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
fireEvent(this, "value-changed", {
|
||||||
|
value: {
|
||||||
|
repeat: {
|
||||||
|
...this.action.repeat,
|
||||||
|
count: newVal,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult {
|
||||||
|
return haStyle;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"ha-automation-action-repeat": HaRepeatAction;
|
||||||
|
}
|
||||||
|
}
|
@ -106,9 +106,9 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
@error=${this._onImageError}
|
@error=${this._onImageError}
|
||||||
@load=${this._onImageLoad}
|
@load=${this._onImageLoad}
|
||||||
/>
|
/>
|
||||||
<h1>
|
<h2>
|
||||||
${domainToName(this.hass.localize, this.domain)}
|
${domainToName(this.hass.localize, this.domain)}
|
||||||
</h1>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
<paper-listbox>
|
<paper-listbox>
|
||||||
${this.items.map(
|
${this.items.map(
|
||||||
@ -156,12 +156,12 @@ export class HaIntegrationCard extends LitElement {
|
|||||||
@load=${this._onImageLoad}
|
@load=${this._onImageLoad}
|
||||||
/>
|
/>
|
||||||
</div>
|
</div>
|
||||||
<h1>
|
|
||||||
${item.localized_domain_name}
|
|
||||||
</h1>
|
|
||||||
<h2>
|
<h2>
|
||||||
${item.localized_domain_name === item.title ? "" : item.title}
|
${item.localized_domain_name}
|
||||||
</h2>
|
</h2>
|
||||||
|
<h3>
|
||||||
|
${item.localized_domain_name === item.title ? "" : item.title}
|
||||||
|
</h3>
|
||||||
${devices.length || entities.length
|
${devices.length || entities.length
|
||||||
? html`
|
? html`
|
||||||
<div>
|
<div>
|
||||||
|
@ -79,6 +79,17 @@ export const haStyle = css`
|
|||||||
}
|
}
|
||||||
|
|
||||||
h1 {
|
h1 {
|
||||||
|
font-family: var(--paper-font-headline_-_font-family);
|
||||||
|
-webkit-font-smoothing: var(--paper-font-headline_-_-webkit-font-smoothing);
|
||||||
|
white-space: var(--paper-font-headline_-_white-space);
|
||||||
|
overflow: var(--paper-font-headline_-_overflow);
|
||||||
|
text-overflow: var(--paper-font-headline_-_text-overflow);
|
||||||
|
font-size: var(--paper-font-headline_-_font-size);
|
||||||
|
font-weight: var(--paper-font-headline_-_font-weight);
|
||||||
|
line-height: var(--paper-font-headline_-_line-height);
|
||||||
|
}
|
||||||
|
|
||||||
|
h2 {
|
||||||
font-family: var(--paper-font-title_-_font-family);
|
font-family: var(--paper-font-title_-_font-family);
|
||||||
-webkit-font-smoothing: var(--paper-font-title_-_-webkit-font-smoothing);
|
-webkit-font-smoothing: var(--paper-font-title_-_-webkit-font-smoothing);
|
||||||
white-space: var(--paper-font-title_-_white-space);
|
white-space: var(--paper-font-title_-_white-space);
|
||||||
@ -89,7 +100,7 @@ export const haStyle = css`
|
|||||||
line-height: var(--paper-font-title_-_line-height);
|
line-height: var(--paper-font-title_-_line-height);
|
||||||
}
|
}
|
||||||
|
|
||||||
h2 {
|
h3 {
|
||||||
font-family: var(--paper-font-subhead_-_font-family);
|
font-family: var(--paper-font-subhead_-_font-family);
|
||||||
-webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing);
|
-webkit-font-smoothing: var(--paper-font-subhead_-_-webkit-font-smoothing);
|
||||||
white-space: var(--paper-font-subhead_-_white-space);
|
white-space: var(--paper-font-subhead_-_white-space);
|
||||||
|
@ -1058,6 +1058,31 @@
|
|||||||
},
|
},
|
||||||
"scene": {
|
"scene": {
|
||||||
"label": "Activate scene"
|
"label": "Activate scene"
|
||||||
|
},
|
||||||
|
"repeat": {
|
||||||
|
"label": "Repeat",
|
||||||
|
"type_select": "Repeat type",
|
||||||
|
"type": {
|
||||||
|
"count": { "label": "Count" },
|
||||||
|
"while": {
|
||||||
|
"label": "While",
|
||||||
|
"conditions": "While conditions"
|
||||||
|
},
|
||||||
|
"until": {
|
||||||
|
"label": "Until",
|
||||||
|
"conditions": "Until conditions"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sequence": "Actions"
|
||||||
|
},
|
||||||
|
"choose": {
|
||||||
|
"label": "Choose",
|
||||||
|
"default": "Default actions",
|
||||||
|
"option": "Option {number}",
|
||||||
|
"add_option": "Add option",
|
||||||
|
"remove_option": "Remove option",
|
||||||
|
"conditions": "Conditions",
|
||||||
|
"sequence": "Actions"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user