Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Handle sequences under parallel actions #18470

Closed
wants to merge 15 commits into from
Closed
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
2 changes: 2 additions & 0 deletions src/data/action.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import {
mdiDevices,
mdiDotsHorizontal,
mdiExcavator,
mdiFormatListNumbered,
mdiGestureDoubleTap,
mdiHandBackRight,
mdiPalette,
Expand Down Expand Up @@ -36,6 +37,7 @@ export const ACTION_ICONS = {
device_id: mdiDevices,
stop: mdiHandBackRight,
parallel: mdiShuffleDisabled,
sequence: mdiFormatListNumbered,
variables: mdiApplicationVariableOutline,
set_conversation_response: mdiBullhorn,
} as const;
Expand Down
8 changes: 8 additions & 0 deletions src/data/script.ts
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,10 @@ export interface StopAction extends BaseAction {
error?: boolean;
}

export interface SequenceAction extends BaseAction {
sequence: (ManualScriptConfig | Action)[];
}

export interface ParallelAction extends BaseAction {
parallel: ManualScriptConfig | Action | (ManualScriptConfig | Action)[];
}
Expand Down Expand Up @@ -299,6 +303,7 @@ export interface ActionTypes {
play_media: PlayMediaAction;
stop: StopAction;
parallel: ParallelAction;
sequence: SequenceAction;
set_conversation_response: SetConversationResponseAction;
unknown: UnknownAction;
}
Expand Down Expand Up @@ -391,6 +396,9 @@ export const getActionType = (action: Action): ActionType => {
if ("parallel" in action) {
return "parallel";
}
if ("sequence" in action) {
return "sequence";
}
if ("set_conversation_response" in action) {
return "set_conversation_response";
}
Expand Down
10 changes: 10 additions & 0 deletions src/data/script_i18n.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import {
PlayMediaAction,
RepeatAction,
SceneAction,
SequenceAction,
SetConversationResponseAction,
StopAction,
VariablesAction,
Expand Down Expand Up @@ -480,6 +481,15 @@ const tryDescribeAction = <T extends ActionType>(
);
}

if (actionType === "sequence") {
const config = action as SequenceAction;
const numActions = ensureArray(config.sequence).length;
return hass.localize(
`${actionTranslationBaseKey}.sequence.description.full`,
{ number: numActions }
);
}

if (actionType === "set_conversation_response") {
const config = action as SetConversationResponseAction;
return hass.localize(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ import "./types/ha-automation-action-if";
import "./types/ha-automation-action-parallel";
import "./types/ha-automation-action-play_media";
import "./types/ha-automation-action-repeat";
import "./types/ha-automation-action-sequence";
import "./types/ha-automation-action-service";
import "./types/ha-automation-action-set_conversation_response";
import "./types/ha-automation-action-stop";
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,7 @@ export default class HaAutomationAction extends LitElement {
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</ha-button>
<slot name="automationExtraButtons"></slot>
</div>
</div>
</ha-sortable>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,17 @@
import { CSSResultGroup, html, LitElement } from "lit";
import { mdiPlus } from "@mdi/js";
import { html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-textfield";
import { Action, ParallelAction } from "../../../../../data/script";
import { haStyle } from "../../../../../resources/styles";
import {
Action,
ManualScriptConfig,
ParallelAction,
} from "../../../../../data/script";
import type { HomeAssistant, ItemPath } from "../../../../../types";
import "../ha-automation-action";
import type { ActionElement } from "../ha-automation-action-row";
import { HaSequenceAction } from "./ha-automation-action-sequence";

@customElement("ha-automation-action-parallel")
export class HaParallelAction extends LitElement implements ActionElement {
Expand Down Expand Up @@ -34,10 +39,39 @@ export class HaParallelAction extends LitElement implements ActionElement {
.disabled=${this.disabled}
@value-changed=${this._actionsChanged}
.hass=${this.hass}
></ha-automation-action>
>
<ha-button
slot="automationExtraButtons"
outlined
.disabled=${this.disabled}
.label=${this.hass.localize(
"ui.panel.config.automation.editor.actions.type.parallel.add_sequence"
)}
@click=${this._addSequenceAction}
>
<ha-svg-icon .path=${mdiPlus} slot="icon"></ha-svg-icon>
</ha-button>
</ha-automation-action>
`;
}

private _addSequenceAction() {
const currentAction = (this.action.parallel as (
| ManualScriptConfig
| Action
)[]) ?? [this.action.parallel as ManualScriptConfig | Action];
const actions = currentAction.concat({
...HaSequenceAction.defaultConfig,
});

fireEvent(this, "value-changed", {
value: {
...this.action,
parallel: actions,
},
});
}

private _actionsChanged(ev: CustomEvent) {
ev.stopPropagation();
const value = ev.detail.value as Action[];
Expand All @@ -48,10 +82,6 @@ export class HaParallelAction extends LitElement implements ActionElement {
},
});
}

static get styles(): CSSResultGroup {
return haStyle;
}
}

declare global {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import { CSSResultGroup, html, LitElement } from "lit";
import { customElement, property } from "lit/decorators";
import { fireEvent } from "../../../../../common/dom/fire_event";
import "../../../../../components/ha-textfield";
import { Action, SequenceAction } from "../../../../../data/script";
import { haStyle } from "../../../../../resources/styles";
import type { HomeAssistant, ItemPath } from "../../../../../types";
import "../ha-automation-action";
import type { ActionElement } from "../ha-automation-action-row";

@customElement("ha-automation-action-sequence")
export class HaSequenceAction extends LitElement implements ActionElement {
@property({ attribute: false }) public hass!: HomeAssistant;

@property({ type: Boolean }) public disabled = false;

@property({ attribute: false }) public path?: ItemPath;

@property({ attribute: false }) public action!: SequenceAction;

public static get defaultConfig() {
return {
sequence: [],
};
}

protected render() {
const action = this.action;

return html`
<ha-automation-action
.path=${[...(this.path ?? []), "sequence"]}
.actions=${action.sequence}
.disabled=${this.disabled}
@value-changed=${this._actionsChanged}
.hass=${this.hass}
></ha-automation-action>
`;
}

private _actionsChanged(ev: CustomEvent) {
ev.stopPropagation();
const value = ev.detail.value as Action[];
fireEvent(this, "value-changed", {
value: {
...this.action,
sequence: value,
},
});
}

static get styles(): CSSResultGroup {
return haStyle;
}
}

declare global {
interface HTMLElementTagNameMap {
"ha-automation-action-sequence": HaSequenceAction;
}
}
10 changes: 9 additions & 1 deletion src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -3415,11 +3415,19 @@
},
"parallel": {
"label": "Run in parallel",
"add_sequence": "Add sequence of actions",
"description": {
"picker": "Perform a sequence of actions in parallel.",
"picker": "Perform actions in parallel.",
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in parallel"
}
},
"sequence": {
"label": "Run in sequence",
"description": {
"picker": "Perform actions in sequence.",
"full": "Run {number} {number, plural,\n one {action}\n other {actions}\n} in sequence"
}
},
"variables": {
"label": "Define variables",
"description": {
Expand Down
Loading