diff --git a/src/common/navigate.ts b/src/common/navigate.ts
index e2e0f26dd0..a9d41ab04d 100644
--- a/src/common/navigate.ts
+++ b/src/common/navigate.ts
@@ -1,3 +1,4 @@
+import { historyPromise } from "../state/url-sync-mixin";
import { fireEvent } from "./dom/fire_event";
import { mainWindow } from "./dom/get_main_window";
@@ -15,6 +16,11 @@ export interface NavigateOptions {
export const navigate = (path: string, options?: NavigateOptions) => {
const replace = options?.replace || false;
+ if (historyPromise) {
+ historyPromise.then(() => navigate(path, options));
+ return;
+ }
+
if (__DEMO__) {
if (replace) {
mainWindow.history.replaceState(
diff --git a/src/panels/config/automation/dialog-new-automation.ts b/src/panels/config/automation/dialog-new-automation.ts
index 3f00995b05..4c3b6723eb 100644
--- a/src/panels/config/automation/dialog-new-automation.ts
+++ b/src/panels/config/automation/dialog-new-automation.ts
@@ -2,7 +2,6 @@ import "@material/mwc-button";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import { fireEvent } from "../../../common/dom/fire_event";
-import { nextRender } from "../../../common/util/render-status";
import "../../../components/ha-blueprint-picker";
import "../../../components/ha-card";
import "../../../components/ha-circular-progress";
@@ -26,8 +25,10 @@ class DialogNewAutomation extends LitElement implements HassDialog {
}
public closeDialog(): void {
+ if (this._opened) {
+ fireEvent(this, "dialog-closed", { dialog: this.localName });
+ }
this._opened = false;
- fireEvent(this, "dialog-closed", { dialog: this.localName });
}
protected render(): TemplateResult {
@@ -66,8 +67,8 @@ class DialogNewAutomation extends LitElement implements HassDialog {
"ui.panel.config.automation.dialog_new.start_empty_description"
)}
-
+
+
`;
@@ -75,7 +76,6 @@ class DialogNewAutomation extends LitElement implements HassDialog {
private async _blueprintPicked(ev: CustomEvent) {
this.closeDialog();
- await nextRender();
showAutomationEditor({ use_blueprint: { path: ev.detail.value } });
}
@@ -85,7 +85,6 @@ class DialogNewAutomation extends LitElement implements HassDialog {
private async _blank() {
this.closeDialog();
- await nextRender();
showAutomationEditor();
}
diff --git a/src/state/url-sync-mixin.ts b/src/state/url-sync-mixin.ts
index 684f9a79dc..d8cc554b75 100644
--- a/src/state/url-sync-mixin.ts
+++ b/src/state/url-sync-mixin.ts
@@ -13,6 +13,11 @@ import { Constructor } from "../types";
const DEBUG = false;
+// eslint-disable-next-line import/no-mutable-exports
+export let historyPromise: Promise | undefined;
+
+let historyResolve: undefined | (() => void);
+
export const urlSyncMixin = <
T extends Constructor
>(
@@ -62,16 +67,26 @@ export const urlSyncMixin = <
if (DEBUG) {
console.log("remove state", ev.detail.dialog);
}
- this._ignoreNextPopState = true;
- mainWindow.history.back();
+ if (history.length) {
+ this._ignoreNextPopState = true;
+ historyPromise = new Promise((resolve) => {
+ historyResolve = () => {
+ resolve();
+ historyResolve = undefined;
+ historyPromise = undefined;
+ };
+ mainWindow.history.back();
+ });
+ }
}
};
private _popstateChangeListener = (ev: PopStateEvent) => {
if (this._ignoreNextPopState) {
if (
- ev.state?.oldState?.replaced ||
- ev.state?.oldState?.dialogParams === null
+ history.length &&
+ (ev.state?.oldState?.replaced ||
+ ev.state?.oldState?.dialogParams === null)
) {
// if the previous dialog was replaced, or we could not copy the params, and the current dialog is closed, we should also remove the previous dialog from history
if (DEBUG) {
@@ -80,7 +95,13 @@ export const urlSyncMixin = <
mainWindow.history.back();
return;
}
+ if (DEBUG) {
+ console.log("ignore popstate");
+ }
this._ignoreNextPopState = false;
+ if (historyResolve) {
+ historyResolve();
+ }
return;
}
if (ev.state && "dialog" in ev.state) {
@@ -89,6 +110,9 @@ export const urlSyncMixin = <
}
this._handleDialogStateChange(ev.state);
}
+ if (historyResolve) {
+ historyResolve();
+ }
};
private async _handleDialogStateChange(state: DialogState) {