`
: ""}
-
-
- ${this._params.domain === "script" &&
- this._visibleOptionals.includes("icon")
- ? html`
-
-
-
-
- `
+ ${this._params.description
+ ? html`${this._params.description}
`
: nothing}
- ${this._visibleOptionals.includes("description")
- ? html` `
- : nothing}
- ${this._visibleOptionals.includes("category")
- ? html` `
- : nothing}
- ${this._visibleOptionals.includes("labels")
- ? html` `
- : nothing}
- ${this._visibleOptionals.includes("area")
- ? html` `
- : nothing}
-
-
- ${this._renderOptionalChip(
- "description",
- this.hass.localize(
- "ui.panel.config.automation.editor.dialog.add_description"
- )
- )}
- ${this._params.domain === "script"
- ? this._renderOptionalChip(
- "icon",
- this.hass.localize(
- "ui.panel.config.automation.editor.dialog.add_icon"
- )
- )
- : nothing}
- ${this._renderOptionalChip(
- "area",
- this.hass.localize(
- "ui.panel.config.automation.editor.dialog.add_area"
- )
- )}
- ${this._renderOptionalChip(
- "category",
- this.hass.localize(
- "ui.panel.config.automation.editor.dialog.add_category"
- )
- )}
- ${this._renderOptionalChip(
- "labels",
- this.hass.localize(
- "ui.panel.config.automation.editor.dialog.add_labels"
- )
- )}
-
+ ${this._renderInputs()} ${this._renderDiscard()}
@@ -247,7 +267,7 @@ class DialogAutomationRename extends LitElement implements HassDialog {
${this.hass.localize(
- this._params.config.alias
+ this._params.config.alias && !this._params.onDiscard
? "ui.panel.config.automation.editor.rename"
: "ui.panel.config.automation.editor.save"
)}
@@ -286,14 +306,19 @@ class DialogAutomationRename extends LitElement implements HassDialog {
}
}
- private _save(): void {
+ private _handleDiscard() {
+ this._params.onDiscard?.();
+ this.closeDialog();
+ }
+
+ private async _save(): Promise {
if (!this._newName) {
this._error = "Name is required";
return;
}
if (this._params.domain === "script") {
- this._params.updateConfig(
+ await this._params.updateConfig(
{
...this._params.config,
alias: this._newName,
@@ -303,7 +328,7 @@ class DialogAutomationRename extends LitElement implements HassDialog {
this._entryUpdates
);
} else {
- this._params.updateConfig(
+ await this._params.updateConfig(
{
...this._params.config,
alias: this._newName,
@@ -351,6 +376,9 @@ class DialogAutomationRename extends LitElement implements HassDialog {
display: block;
margin-bottom: 16px;
}
+ .destructive {
+ --mdc-theme-primary: var(--error-color);
+ }
`,
];
}
@@ -358,6 +386,6 @@ class DialogAutomationRename extends LitElement implements HassDialog {
declare global {
interface HTMLElementTagNameMap {
- "ha-dialog-automation-rename": DialogAutomationRename;
+ "ha-dialog-automation-save": DialogAutomationSave;
}
}
diff --git a/src/panels/config/automation/automation-rename-dialog/show-dialog-automation-rename.ts b/src/panels/config/automation/automation-save-dialog/show-dialog-automation-save.ts
similarity index 58%
rename from src/panels/config/automation/automation-rename-dialog/show-dialog-automation-rename.ts
rename to src/panels/config/automation/automation-save-dialog/show-dialog-automation-save.ts
index 4573fc85f2..cd816443d1 100644
--- a/src/panels/config/automation/automation-rename-dialog/show-dialog-automation-rename.ts
+++ b/src/panels/config/automation/automation-save-dialog/show-dialog-automation-save.ts
@@ -3,13 +3,18 @@ import type { AutomationConfig } from "../../../../data/automation";
import type { ScriptConfig } from "../../../../data/script";
import type { EntityRegistryEntry } from "../../../../data/entity_registry";
-export const loadAutomationRenameDialog = () =>
- import("./dialog-automation-rename");
+export const loadAutomationSaveDialog = () =>
+ import("./dialog-automation-save");
interface BaseRenameDialogParams {
entityRegistryUpdate?: EntityRegistryUpdate;
entityRegistryEntry?: EntityRegistryEntry;
onClose: () => void;
+ onDiscard?: () => void;
+ saveText?: string;
+ description?: string;
+ title?: string;
+ hideInputs?: boolean;
}
export interface EntityRegistryUpdate {
@@ -18,31 +23,35 @@ export interface EntityRegistryUpdate {
category: string;
}
-export interface AutomationRenameDialogParams extends BaseRenameDialogParams {
+export interface AutomationSaveDialogParams extends BaseRenameDialogParams {
config: AutomationConfig;
domain: "automation";
updateConfig: (
config: AutomationConfig,
entityRegistryUpdate: EntityRegistryUpdate
- ) => void;
+ ) => Promise;
}
-export interface ScriptRenameDialogParams extends BaseRenameDialogParams {
+export interface ScriptSaveDialogParams extends BaseRenameDialogParams {
config: ScriptConfig;
domain: "script";
updateConfig: (
config: ScriptConfig,
entityRegistryUpdate: EntityRegistryUpdate
- ) => void;
+ ) => Promise;
}
-export const showAutomationRenameDialog = (
+export type SaveDialogParams =
+ | AutomationSaveDialogParams
+ | ScriptSaveDialogParams;
+
+export const showAutomationSaveDialog = (
element: HTMLElement,
- dialogParams: AutomationRenameDialogParams | ScriptRenameDialogParams
+ dialogParams: SaveDialogParams
): void => {
fireEvent(element, "show-dialog", {
- dialogTag: "ha-dialog-automation-rename",
- dialogImport: loadAutomationRenameDialog,
+ dialogTag: "ha-dialog-automation-save",
+ dialogImport: loadAutomationSaveDialog,
dialogParams,
});
};
diff --git a/src/panels/config/automation/ha-automation-editor.ts b/src/panels/config/automation/ha-automation-editor.ts
index 8d06326d61..77ab99ab88 100644
--- a/src/panels/config/automation/ha-automation-editor.ts
+++ b/src/panels/config/automation/ha-automation-editor.ts
@@ -19,7 +19,7 @@ import {
} from "@mdi/js";
import type { UnsubscribeFunc } from "home-assistant-js-websocket";
import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
-import { LitElement, css, html, nothing } from "lit";
+import { css, html, LitElement, nothing } from "lit";
import { property, state } from "lit/decorators";
import { classMap } from "lit/directives/class-map";
import { consume } from "@lit-labs/context";
@@ -70,8 +70,8 @@ import "../ha-config-section";
import { showAutomationModeDialog } from "./automation-mode-dialog/show-dialog-automation-mode";
import {
type EntityRegistryUpdate,
- showAutomationRenameDialog,
-} from "./automation-rename-dialog/show-dialog-automation-rename";
+ showAutomationSaveDialog,
+} from "./automation-save-dialog/show-dialog-automation-save";
import "./blueprint-automation-editor";
import "./manual-automation-editor";
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
@@ -500,7 +500,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
.label=${this.hass.localize("ui.panel.config.automation.editor.save")}
.disabled=${this._saving}
extended
- @click=${this._saveAutomation}
+ @click=${this._handleSaveAutomation}
>
@@ -743,20 +743,48 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
}
private async _confirmUnsavedChanged(): Promise {
- if (this._dirty) {
- return showConfirmationDialog(this, {
- title: this.hass!.localize(
- "ui.panel.config.automation.editor.unsaved_confirm_title"
- ),
- text: this.hass!.localize(
- "ui.panel.config.automation.editor.unsaved_confirm_text"
- ),
- confirmText: this.hass!.localize("ui.common.leave"),
- dismissText: this.hass!.localize("ui.common.stay"),
- destructive: true,
- });
+ if (!this._dirty) {
+ return true;
}
- return true;
+
+ return new Promise((resolve) => {
+ showAutomationSaveDialog(this, {
+ config: this._config!,
+ domain: "automation",
+ updateConfig: async (config, entityRegistryUpdate) => {
+ this._config = config;
+ this._entityRegistryUpdate = entityRegistryUpdate;
+ this._dirty = true;
+ this.requestUpdate();
+
+ const id = this.automationId || String(Date.now());
+ try {
+ await this._saveAutomation(id);
+ } catch (_err: any) {
+ this.requestUpdate();
+ resolve(false);
+ return;
+ }
+
+ resolve(true);
+ },
+ onClose: () => resolve(false),
+ onDiscard: () => resolve(true),
+ entityRegistryUpdate: this._entityRegistryUpdate,
+ entityRegistryEntry: this._registryEntry,
+ title: this.hass.localize(
+ this.automationId
+ ? "ui.panel.config.automation.editor.leave.unsaved_confirm_title"
+ : "ui.panel.config.automation.editor.leave.unsaved_new_title"
+ ),
+ description: this.hass.localize(
+ this.automationId
+ ? "ui.panel.config.automation.editor.leave.unsaved_confirm_text"
+ : "ui.panel.config.automation.editor.leave.unsaved_new_text"
+ ),
+ hideInputs: this.automationId !== null,
+ });
+ });
}
private _backTapped = async () => {
@@ -878,10 +906,10 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
private async _promptAutomationAlias(): Promise {
return new Promise((resolve) => {
- showAutomationRenameDialog(this, {
+ showAutomationSaveDialog(this, {
config: this._config!,
domain: "automation",
- updateConfig: (config, entityRegistryUpdate) => {
+ updateConfig: async (config, entityRegistryUpdate) => {
this._config = config;
this._entityRegistryUpdate = entityRegistryUpdate;
this._dirty = true;
@@ -910,7 +938,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
});
}
- private async _saveAutomation(): Promise {
+ private async _handleSaveAutomation(): Promise {
if (this._yamlErrors) {
showToast(this, {
message: this._yamlErrors,
@@ -926,6 +954,13 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
}
}
+ await this._saveAutomation(id);
+ if (!this.automationId) {
+ navigate(`/config/automation/edit/${id}`, { replace: true });
+ }
+ }
+
+ private async _saveAutomation(id): Promise {
this._saving = true;
this._validationErrors = undefined;
@@ -990,10 +1025,6 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
}
this._dirty = false;
-
- if (!this.automationId) {
- navigate(`/config/automation/edit/${id}`, { replace: true });
- }
} catch (errors: any) {
this._errors = errors.body?.message || errors.error || errors.body;
showToast(this, {
@@ -1016,7 +1047,7 @@ export class HaAutomationEditor extends PreventUnsavedMixin(
protected supportedShortcuts(): SupportedShortcuts {
return {
- s: () => this._saveAutomation(),
+ s: () => this._handleSaveAutomation(),
};
}
diff --git a/src/panels/config/script/ha-script-editor.ts b/src/panels/config/script/ha-script-editor.ts
index 397d01dc34..584a6cb148 100644
--- a/src/panels/config/script/ha-script-editor.ts
+++ b/src/panels/config/script/ha-script-editor.ts
@@ -62,8 +62,8 @@ import { haStyle } from "../../../resources/styles";
import type { Entries, HomeAssistant, Route } from "../../../types";
import { showToast } from "../../../util/toast";
import { showAutomationModeDialog } from "../automation/automation-mode-dialog/show-dialog-automation-mode";
-import type { EntityRegistryUpdate } from "../automation/automation-rename-dialog/show-dialog-automation-rename";
-import { showAutomationRenameDialog } from "../automation/automation-rename-dialog/show-dialog-automation-rename";
+import type { EntityRegistryUpdate } from "../automation/automation-save-dialog/show-dialog-automation-save";
+import { showAutomationSaveDialog } from "../automation/automation-save-dialog/show-dialog-automation-save";
import "./blueprint-script-editor";
import "./manual-script-editor";
import type { HaManualScriptEditor } from "./manual-script-editor";
@@ -843,10 +843,10 @@ export class HaScriptEditor extends SubscribeMixin(
private async _promptScriptAlias(): Promise {
return new Promise((resolve) => {
- showAutomationRenameDialog(this, {
+ showAutomationSaveDialog(this, {
config: this._config!,
domain: "script",
- updateConfig: (config, entityRegistryUpdate) => {
+ updateConfig: async (config, entityRegistryUpdate) => {
this._config = config;
this._entityRegistryUpdate = entityRegistryUpdate;
this._dirty = true;
diff --git a/src/translations/en.json b/src/translations/en.json
index 47965f9abb..608b8ca821 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -369,7 +369,8 @@
"copied_clipboard": "Copied to clipboard",
"name": "Name",
"optional": "optional",
- "default": "Default"
+ "default": "Default",
+ "dont_save": "Don't save"
},
"components": {
"selectors": {
@@ -3471,6 +3472,12 @@
"placeholder": "Optional description",
"add": "Add description"
},
+ "leave": {
+ "unsaved_new_title": "Save new automation?",
+ "unsaved_new_text": "You can save your changes, or delete this automation. You can't undo this action.",
+ "unsaved_confirm_title": "Save changes?",
+ "unsaved_confirm_text": "You have made some changes in this automation. You can save these changes, or discard them and leave. You can't undo this action."
+ },
"icon": "Icon",
"blueprint": {
"header": "Blueprint",