mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-15 05:50:24 +00:00
Close dialogs on history back (#6354)
This commit is contained in:
@@ -6,15 +6,18 @@ declare global {
|
||||
interface HASSDomEvents {
|
||||
"show-dialog": ShowDialogParams<unknown>;
|
||||
"close-dialog": undefined;
|
||||
"dialog-closed": DialogClosedParams;
|
||||
}
|
||||
// for add event listener
|
||||
interface HTMLElementEventMap {
|
||||
"show-dialog": HASSDomEvent<ShowDialogParams<unknown>>;
|
||||
"dialog-closed": HASSDomEvent<DialogClosedParams>;
|
||||
}
|
||||
}
|
||||
|
||||
interface HassDialog<T = HASSDomEvents[ValidHassDomEvent]> extends HTMLElement {
|
||||
showDialog(params: T);
|
||||
closeDialog?: () => boolean | void;
|
||||
}
|
||||
|
||||
interface ShowDialogParams<T> {
|
||||
@@ -23,16 +26,30 @@ interface ShowDialogParams<T> {
|
||||
dialogParams: T;
|
||||
}
|
||||
|
||||
export interface DialogClosedParams {
|
||||
dialog: string;
|
||||
}
|
||||
|
||||
export interface DialogState {
|
||||
dialog: string;
|
||||
open: boolean;
|
||||
oldState: null | DialogState;
|
||||
dialogParams?: unknown;
|
||||
}
|
||||
|
||||
const LOADED = {};
|
||||
|
||||
export const showDialog = async (
|
||||
element: HTMLElement & ProvideHassElement,
|
||||
root: ShadowRoot | HTMLElement,
|
||||
dialogImport: () => Promise<unknown>,
|
||||
dialogTag: string,
|
||||
dialogParams: unknown
|
||||
dialogParams: unknown,
|
||||
dialogImport?: () => Promise<unknown>
|
||||
) => {
|
||||
if (!(dialogTag in LOADED)) {
|
||||
if (!dialogImport) {
|
||||
return;
|
||||
}
|
||||
LOADED[dialogTag] = dialogImport().then(() => {
|
||||
const dialogEl = document.createElement(dialogTag) as HassDialog;
|
||||
element.provideHass(dialogEl);
|
||||
@@ -40,19 +57,55 @@ export const showDialog = async (
|
||||
return dialogEl;
|
||||
});
|
||||
}
|
||||
|
||||
history.replaceState(
|
||||
{
|
||||
dialog: dialogTag,
|
||||
open: false,
|
||||
oldState:
|
||||
history.state?.open && history.state?.dialog !== dialogTag
|
||||
? history.state
|
||||
: null,
|
||||
},
|
||||
""
|
||||
);
|
||||
try {
|
||||
history.pushState(
|
||||
{ dialog: dialogTag, dialogParams: dialogParams, open: true },
|
||||
""
|
||||
);
|
||||
} catch (err) {
|
||||
// dialogParams could not be cloned, probably contains callback
|
||||
history.pushState(
|
||||
{ dialog: dialogTag, dialogParams: null, open: true },
|
||||
""
|
||||
);
|
||||
}
|
||||
|
||||
const dialogElement = await LOADED[dialogTag];
|
||||
dialogElement.showDialog(dialogParams);
|
||||
};
|
||||
|
||||
export const closeDialog = async (dialogTag: string): Promise<boolean> => {
|
||||
if (!(dialogTag in LOADED)) {
|
||||
return true;
|
||||
}
|
||||
const dialogElement = await LOADED[dialogTag];
|
||||
if (dialogElement.closeDialog) {
|
||||
return dialogElement.closeDialog() !== false;
|
||||
}
|
||||
return true;
|
||||
};
|
||||
|
||||
export const makeDialogManager = (
|
||||
element: HTMLElement & ProvideHassElement,
|
||||
root: ShadowRoot | HTMLElement
|
||||
) => {
|
||||
element.addEventListener(
|
||||
"show-dialog",
|
||||
async (e: HASSDomEvent<ShowDialogParams<unknown>>) => {
|
||||
(e: HASSDomEvent<ShowDialogParams<unknown>>) => {
|
||||
const { dialogTag, dialogImport, dialogParams } = e.detail;
|
||||
showDialog(element, root, dialogImport, dialogTag, dialogParams);
|
||||
showDialog(element, root, dialogTag, dialogParams, dialogImport);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user