Skip to content

Commit

Permalink
WIP ux
Browse files Browse the repository at this point in the history
  • Loading branch information
bramkragten committed Jun 24, 2024
1 parent 9e900b5 commit b369e05
Show file tree
Hide file tree
Showing 7 changed files with 98 additions and 21 deletions.
10 changes: 6 additions & 4 deletions src/data/automation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -352,9 +352,11 @@ export const saveAutomationConfig = (
config: AutomationConfig
) => hass.callApi<void>("POST", `config/automation/config/${id}`, config);

export const normalizeAutomationConfig = (
config: AutomationConfig
): AutomationConfig => {
export const normalizeAutomationConfig = <
T extends Partial<AutomationConfig> | AutomationConfig,
>(
config: T
): T => {
// Normalize data: ensure trigger, action and condition are lists
// Happens when people copy paste their automations into the config
for (const key of ["trigger", "condition", "action"]) {
Expand All @@ -367,7 +369,7 @@ export const normalizeAutomationConfig = (
};

export const showAutomationEditor = (data?: Partial<AutomationConfig>) => {
initialAutomationEditorData = normalizeAutomationConfig(data);
initialAutomationEditorData = data;
navigate("/config/automation/edit/new");
};

Expand Down
7 changes: 6 additions & 1 deletion src/data/blueprint.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { HomeAssistant } from "../types";
import { ManualAutomationConfig } from "./automation";
import { Selector } from "./selector";

export type BlueprintDomain = "automation" | "script";
Expand Down Expand Up @@ -42,6 +43,10 @@ export interface BlueprintImportResult {
validation_errors: string[] | null;
}

export interface BlueprintSubstituteResult {
substituted_config: ManualAutomationConfig;
}

export const fetchBlueprints = (hass: HomeAssistant, domain: BlueprintDomain) =>
hass.callWS<Blueprints>({ type: "blueprint/list", domain });

Expand Down Expand Up @@ -98,7 +103,7 @@ export const substituteBlueprint = (
path: string,
input: Record<string, any>
) =>
hass.callWS({
hass.callWS<BlueprintSubstituteResult>({
type: "blueprint/substitute",
domain,
path,
Expand Down
72 changes: 59 additions & 13 deletions src/panels/config/automation/blueprint-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,19 @@ import "@material/mwc-button/mwc-button";
import { HassEntity } from "home-assistant-js-websocket";
import { html, nothing } from "lit";
import { customElement, property } from "lit/decorators";
import { navigate } from "../../../common/navigate";
import { nextRender } from "../../../common/util/render-status";
import "../../../components/ha-alert";
import "../../../components/ha-markdown";
import {
BlueprintAutomationConfig,
normalizeAutomationConfig,
showAutomationEditor,
} from "../../../data/automation";
import { fetchBlueprints, substituteBlueprint } from "../../../data/blueprint";
import { showConfirmationDialog } from "../../lovelace/custom-card-helpers";
import { HaBlueprintGenericEditor } from "../blueprint/blueprint-generic-editor";
import "../../../components/ha-markdown";
import "./manual-automation-editor";

@customElement("blueprint-automation-editor")
export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
Expand Down Expand Up @@ -69,18 +74,59 @@ export class HaBlueprintAutomationEditor extends HaBlueprintGenericEditor {
});
}

private async _substituteBlueprint(): Promise<void> {
const substitute = await substituteBlueprint(
this.hass,
"automation",
this.config.use_blueprint.path,
this.config.use_blueprint.input || {}
);
showAutomationEditor({
alias: this.config.alias,
description: `${this.config.description ? this.config.description : this._blueprint?.metadata.description} (Originated from blueprint ${this._blueprint?.metadata.name})`,
...substitute.substituted_config,
});
public async substituteBlueprint(): Promise<void> {
try {
const substitute = await substituteBlueprint(
this.hass,
"automation",
this.config.use_blueprint.path,
this.config.use_blueprint.input || {}
);

const config = normalizeAutomationConfig(substitute.substituted_config);

const convert = await showConfirmationDialog(this, {
title: "Take control of blueprint automation",
text: html`<manual-automation-editor
.hass=${this.hass}
disabled
.config=${config}
></manual-automation-editor>`,
confirmText: "Create automation",
});

if (convert) {
if (this.dirty) {
const confirmed = await showConfirmationDialog(this, {
title: "Unsaved changes",
text: "You have unsaved changes. Do you want to continue and lose these changes?",
confirmText: "Continue",
});
if (!confirmed) {
return;
}
}
while (
location.pathname === "/config/automation/edit/new" &&
history.length > 1
) {
history.back();
// eslint-disable-next-line no-await-in-loop
await nextRender();
}
if (location.pathname === "/config/automation/edit/new") {
navigate("/config/automation");
await nextRender();
}
showAutomationEditor({
alias: this.config.alias,
description: `${this.config.description ? this.config.description : this._blueprint && "metadata" in this._blueprint ? this._blueprint.metadata.description : ""}${this._blueprint && "metadata" in this._blueprint ? `(Originated from blueprint ${this._blueprint?.metadata.name})` : ""}`,
...substitute.substituted_config,
});
}
} catch (err: any) {
alert(`Failed to substitute blueprint: ${err.message}`);
}
}
}
declare global {
Expand Down
23 changes: 21 additions & 2 deletions src/panels/config/automation/ha-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
mdiDebugStepOver,
mdiDelete,
mdiDotsVertical,
mdiFileEdit,
mdiInformationOutline,
mdiPlay,
mdiPlayCircleOutline,
Expand Down Expand Up @@ -218,7 +219,16 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
></ha-svg-icon>
</ha-list-item>
`
: nothing}
: html`<ha-list-item
graphic="icon"
@click=${this._substituteBlueprint}
.disabled=${this._readOnly}
>
${this.hass.localize(
"ui.panel.config.automation.editor.subtitute_blueprint"
)}
<ha-svg-icon slot="graphic" .path=${mdiFileEdit}></ha-svg-icon>
</ha-list-item>`}
<ha-list-item
.disabled=${!this._readOnly && !this.automationId}
Expand Down Expand Up @@ -332,6 +342,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
.stateObj=${stateObj}
.config=${this._config}
.disabled=${Boolean(this._readOnly)}
.dirty=${this._dirty}
@value-changed=${this._valueChanged}
@duplicate=${this._duplicate}
></blueprint-automation-editor>
Expand All @@ -344,6 +355,8 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
.stateObj=${stateObj}
.config=${this._config}
.disabled=${Boolean(this._readOnly)}
.readOnly=${Boolean(this._readOnly)}
.dirty=${this._dirty}
@value-changed=${this._valueChanged}
@duplicate=${this._duplicate}
></manual-automation-editor>
Expand Down Expand Up @@ -433,7 +446,7 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
}
this._config = {
...baseConfig,
...initData,
...(initData ? normalizeAutomationConfig(initData) : initData),
} as AutomationConfig;
this._entityId = undefined;
this._readOnly = false;
Expand Down Expand Up @@ -627,6 +640,12 @@ export class HaAutomationEditor extends KeyboardShortcutMixin(LitElement) {
}
};

private _substituteBlueprint() {
this.renderRoot
.querySelector("blueprint-automation-editor")
?.substituteBlueprint();
}

private async _duplicate() {
const result = this._readOnly
? await showConfirmationDialog(this, {
Expand Down
4 changes: 3 additions & 1 deletion src/panels/config/automation/manual-automation-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,15 @@ export class HaManualAutomationEditor extends LitElement {

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

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

@property({ attribute: false }) public config!: ManualAutomationConfig;

@property({ attribute: false }) public stateObj?: HassEntity;

protected render() {
return html`
${this.disabled
${this.readOnly
? html`<ha-alert alert-type="warning">
${this.hass.localize("ui.panel.config.automation.editor.read_only")}
<mwc-button slot="action" @click=${this._duplicate}>
Expand Down
2 changes: 2 additions & 0 deletions src/panels/config/blueprint/blueprint-generic-editor.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ export abstract class HaBlueprintGenericEditor extends LitElement {

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

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

@property({ type: Boolean, reflect: true }) public narrow = false;

@state() protected _blueprints?: Blueprints;
Expand Down
1 change: 1 addition & 0 deletions src/translations/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -2759,6 +2759,7 @@
"unavailable": "Automation is unavailable",
"migrate": "Migrate",
"duplicate": "[%key:ui::common::duplicate%]",
"subtitute_blueprint": "Take control of automation",
"run": "[%key:ui::panel::config::automation::editor::actions::run%]",
"rename": "[%key:ui::panel::config::automation::editor::triggers::rename%]",
"show_trace": "Traces",
Expand Down

0 comments on commit b369e05

Please sign in to comment.