mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +00:00
Fix dialog navigation by making navigate()
async (#23254)
* Fix dialog navigation by making `navigate()` async * close all dialogs on `navigate` * log warning when navigation is blocked * fix
This commit is contained in:
commit
63d97398c1
@ -1,3 +1,4 @@
|
|||||||
|
import { closeAllDialogs } from "../dialogs/make-dialog-manager";
|
||||||
import { fireEvent } from "./dom/fire_event";
|
import { fireEvent } from "./dom/fire_event";
|
||||||
import { mainWindow } from "./dom/get_main_window";
|
import { mainWindow } from "./dom/get_main_window";
|
||||||
|
|
||||||
@ -13,31 +14,46 @@ export interface NavigateOptions {
|
|||||||
data?: any;
|
data?: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const navigate = (path: string, options?: NavigateOptions) => {
|
export const navigate = async (path: string, options?: NavigateOptions) =>
|
||||||
const replace = options?.replace || false;
|
new Promise<boolean>((resolve) => {
|
||||||
|
// need to wait for history state to be updated in case a dialog was closed before calling navigate
|
||||||
|
setTimeout(async () => {
|
||||||
|
const { history } = mainWindow;
|
||||||
|
let replace = options?.replace || false;
|
||||||
|
if (history.state?.dialog) {
|
||||||
|
const closed = await closeAllDialogs();
|
||||||
|
if (!closed) {
|
||||||
|
// eslint-disable-next-line no-console
|
||||||
|
console.warn("Navigation blocked, because dialog refused to close");
|
||||||
|
resolve(false);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// if there were open dialogs, we discard the current state
|
||||||
|
replace = true;
|
||||||
|
}
|
||||||
|
|
||||||
if (__DEMO__) {
|
if (__DEMO__) {
|
||||||
if (replace) {
|
if (replace) {
|
||||||
mainWindow.history.replaceState(
|
history.replaceState(
|
||||||
mainWindow.history.state?.root
|
history.state?.root ? { root: true } : (options?.data ?? null),
|
||||||
? { root: true }
|
"",
|
||||||
: (options?.data ?? null),
|
`${mainWindow.location.pathname}#${path}`
|
||||||
"",
|
);
|
||||||
`${mainWindow.location.pathname}#${path}`
|
} else {
|
||||||
);
|
mainWindow.location.hash = path;
|
||||||
} else {
|
}
|
||||||
mainWindow.location.hash = path;
|
} else if (replace) {
|
||||||
}
|
history.replaceState(
|
||||||
} else if (replace) {
|
history.state?.root ? { root: true } : (options?.data ?? null),
|
||||||
mainWindow.history.replaceState(
|
"",
|
||||||
mainWindow.history.state?.root ? { root: true } : (options?.data ?? null),
|
path
|
||||||
"",
|
);
|
||||||
path
|
} else {
|
||||||
);
|
history.pushState(options?.data ?? null, "", path);
|
||||||
} else {
|
}
|
||||||
mainWindow.history.pushState(options?.data ?? null, "", path);
|
fireEvent(mainWindow, "location-changed", {
|
||||||
}
|
replace,
|
||||||
fireEvent(mainWindow, "location-changed", {
|
});
|
||||||
replace,
|
resolve(true);
|
||||||
|
});
|
||||||
});
|
});
|
||||||
};
|
|
||||||
|
@ -171,7 +171,20 @@ export const closeLastDialog = async () => {
|
|||||||
""
|
""
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
return closed;
|
||||||
}
|
}
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
export const closeAllDialogs = async () => {
|
||||||
|
while (OPEN_DIALOG_STACK.length) {
|
||||||
|
// eslint-disable-next-line no-await-in-loop
|
||||||
|
const closed = await closeLastDialog();
|
||||||
|
if (!closed) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
const _handleClosed = async (ev: HASSDomEvent<DialogClosedParams>) => {
|
const _handleClosed = async (ev: HASSDomEvent<DialogClosedParams>) => {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user