mirror of
https://github.com/home-assistant/frontend.git
synced 2025-12-24 04:39:01 +00:00
Fix inability to leave scene creation page without saving (#28546)
This commit is contained in:
@@ -17,25 +17,36 @@ export interface NavigateOptions {
|
|||||||
// max time to wait for dialogs to close before navigating
|
// max time to wait for dialogs to close before navigating
|
||||||
const DIALOG_WAIT_TIMEOUT = 500;
|
const DIALOG_WAIT_TIMEOUT = 500;
|
||||||
|
|
||||||
export const navigate = async (
|
/**
|
||||||
path: string,
|
* Ensures all dialogs are closed before navigation.
|
||||||
options?: NavigateOptions,
|
* Returns true if navigation can proceed, false if a dialog refused to close.
|
||||||
timestamp = Date.now()
|
*/
|
||||||
) => {
|
const ensureDialogsClosed = async (timestamp: number): Promise<boolean> => {
|
||||||
const { history } = mainWindow;
|
const { history } = mainWindow;
|
||||||
if (history.state?.dialog && Date.now() - timestamp < DIALOG_WAIT_TIMEOUT) {
|
|
||||||
|
if (!history.state?.dialog || Date.now() - timestamp >= DIALOG_WAIT_TIMEOUT) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
const closed = await closeAllDialogs();
|
const closed = await closeAllDialogs();
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
// eslint-disable-next-line no-console
|
// eslint-disable-next-line no-console
|
||||||
console.warn("Navigation blocked, because dialog refused to close");
|
console.warn("Navigation blocked, because dialog refused to close");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return new Promise<boolean>((resolve) => {
|
|
||||||
// need to wait for history state to be updated in case a dialog was closed
|
// wait for history state to be updated after dialog closed
|
||||||
setTimeout(() => {
|
await new Promise<void>((resolve) => {
|
||||||
navigate(path, options, timestamp).then(resolve);
|
setTimeout(resolve);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
return ensureDialogsClosed(timestamp);
|
||||||
|
};
|
||||||
|
|
||||||
|
export const navigate = async (path: string, options?: NavigateOptions) => {
|
||||||
|
const canProceed = await ensureDialogsClosed(Date.now());
|
||||||
|
if (!canProceed) {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
const replace = options?.replace || false;
|
const replace = options?.replace || false;
|
||||||
|
|
||||||
@@ -68,10 +79,14 @@ export const navigate = async (
|
|||||||
* Navigate back in history, with fallback to a default path if no history exists.
|
* Navigate back in history, with fallback to a default path if no history exists.
|
||||||
* This prevents a user from getting stuck when they navigate directly to a page with no history.
|
* This prevents a user from getting stuck when they navigate directly to a page with no history.
|
||||||
*/
|
*/
|
||||||
export const goBack = (fallbackPath?: string) => {
|
export const goBack = async (fallbackPath?: string): Promise<void> => {
|
||||||
const { history } = mainWindow;
|
const canProceed = await ensureDialogsClosed(Date.now());
|
||||||
|
if (!canProceed) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Check if we have history to go back to
|
// Check if we have history to go back to
|
||||||
|
const { history } = mainWindow;
|
||||||
if (history.length > 1) {
|
if (history.length > 1) {
|
||||||
history.back();
|
history.back();
|
||||||
return;
|
return;
|
||||||
|
|||||||
Reference in New Issue
Block a user