From 3a9f09cb47b193608b2bef66a01bc4e2f8e1de48 Mon Sep 17 00:00:00 2001 From: Wendelin <12148533+wendevlin@users.noreply.github.com> Date: Mon, 23 Sep 2024 17:18:00 +0200 Subject: [PATCH] Migrate dialog restart to ha-md-dialog (#22032) * Fix ha-md-dialog for iOS 12 * Fix ha-md-dialog polyfill loading * Fix ha-md-dialog open prop * Fix multiple polyfill loads in ha-md-dialog * Migrate dialog-restart to ha-md-dialog * Fix dialog-restart to use ha-md-list * Fix dialog opens dialog for ha-md-dialog --- src/components/ha-md-dialog.ts | 45 +++- src/dialogs/restart/dialog-restart.ts | 316 ++++++++++++-------------- 2 files changed, 191 insertions(+), 170 deletions(-) diff --git a/src/components/ha-md-dialog.ts b/src/components/ha-md-dialog.ts index 4e3f76d8a0..3c0b2c0f6e 100644 --- a/src/components/ha-md-dialog.ts +++ b/src/components/ha-md-dialog.ts @@ -7,6 +7,40 @@ import { import { css } from "lit"; import { customElement, property } from "lit/decorators"; +// workaround to be able to overlay an dialog with another dialog +MdDialog.addInitializer(async (instance) => { + await instance.updateComplete; + + const dialogInstance = instance as MdDialog; + + // @ts-expect-error dialog is private + dialogInstance.dialog.prepend(dialogInstance.scrim); + // @ts-expect-error scrim is private + dialogInstance.scrim.style.inset = 0; + // @ts-expect-error scrim is private + dialogInstance.scrim.style.zIndex = 0; + + const { getOpenAnimation, getCloseAnimation } = dialogInstance; + dialogInstance.getOpenAnimation = () => { + const animations = getOpenAnimation.call(this); + animations.container = [ + ...(animations.container ?? []), + ...(animations.dialog ?? []), + ]; + animations.dialog = []; + return animations; + }; + dialogInstance.getCloseAnimation = () => { + const animations = getCloseAnimation.call(this); + animations.container = [ + ...(animations.container ?? []), + ...(animations.dialog ?? []), + ]; + animations.dialog = []; + return animations; + }; +}); + let DIALOG_POLYFILL: Promise; /** @@ -25,7 +59,6 @@ export class HaMdDialog extends MdDialog { constructor() { super(); - this.addEventListener("cancel", this._handleCancel); if (typeof HTMLDialogElement !== "function") { @@ -40,6 +73,11 @@ export class HaMdDialog extends MdDialog { if (this.animate === undefined) { this.quick = true; } + + // if browser doesn't support animate API disable open/close animations + if (this.animate === undefined) { + this.quick = true; + } } // prevent open in older browsers and wait for polyfill to load @@ -80,7 +118,7 @@ export class HaMdDialog extends MdDialog { _handleCancel(closeEvent: Event) { if (this.disableCancelAction) { closeEvent.preventDefault(); - const dialogElement = this.shadowRoot?.querySelector("dialog"); + const dialogElement = this.shadowRoot?.querySelector("dialog .container"); if (this.animate !== undefined) { dialogElement?.animate( [ @@ -144,6 +182,9 @@ export class HaMdDialog extends MdDialog { display: contents; } + slot[name="content"]::slotted(*) { + padding: var(--dialog-content-padding, 24px); + } .scrim { z-index: 10; // overlay navigation } diff --git a/src/dialogs/restart/dialog-restart.ts b/src/dialogs/restart/dialog-restart.ts index 9b953eed47..9da672f667 100644 --- a/src/dialogs/restart/dialog-restart.ts +++ b/src/dialogs/restart/dialog-restart.ts @@ -1,20 +1,21 @@ -import "@material/mwc-list/mwc-list"; import { mdiAutoFix, mdiLifebuoy, mdiPower, mdiPowerCycle, mdiRefresh, + mdiClose, } from "@mdi/js"; import { CSSResultGroup, LitElement, css, html, nothing } from "lit"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property, state, query } from "lit/decorators"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { fireEvent } from "../../common/dom/fire_event"; -import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event"; import "../../components/ha-circular-progress"; -import { createCloseHeading } from "../../components/ha-dialog"; +import "../../components/ha-md-dialog"; +import type { HaMdDialog } from "../../components/ha-md-dialog"; +import "../../components/ha-md-list"; import "../../components/ha-expansion-panel"; -import "../../components/ha-list-item"; +import "../../components/ha-md-list-item"; import { extractApiErrorMessage, ignoreSupervisorError, @@ -45,6 +46,8 @@ class DialogRestart extends LitElement { @state() private _hostInfo?: HassioHostInfo; + @query("ha-md-dialog") private _dialog?: HaMdDialog; + public async showDialog(): Promise { const isHassioLoaded = isComponentLoaded(this.hass, "hassio"); @@ -62,12 +65,16 @@ class DialogRestart extends LitElement { } } - public closeDialog(): void { + private _dialogClosed(): void { this._open = false; this._loadingHostInfo = false; fireEvent(this, "dialog-closed", { dialog: this.localName }); } + public closeDialog(): void { + this._dialog?.close(); + } + protected render() { if (!this._open) { return nothing; @@ -76,157 +83,145 @@ class DialogRestart extends LitElement { const showReload = this.hass.userData?.showAdvanced; const showRebootShutdown = !!this._hostInfo; + const dialogTitle = this.hass.localize("ui.dialogs.restart.heading"); + return html` - - ${this._loadingHostInfo - ? html` -
- -
- ` - : html` - - ${showReload - ? html` - -
- -
- - ${this.hass.localize( - "ui.dialogs.restart.reload.title" - )} - - - ${this.hass.localize( - "ui.dialogs.restart.reload.description" - )} - -
- ` - : nothing} - -
- -
- - ${this.hass.localize("ui.dialogs.restart.restart.title")} - - - ${this.hass.localize( - "ui.dialogs.restart.restart.description" - )} - -
-
- - - ${showRebootShutdown + + + + ${dialogTitle} + +
+ ${this._loadingHostInfo + ? html` +
+ +
+ ` + : html` + + ${showReload ? html` - -
- + +
+ ${this.hass.localize( + "ui.dialogs.restart.reload.title" + )}
- +
${this.hass.localize( - "ui.dialogs.restart.reboot.title" + "ui.dialogs.restart.reload.description" )} - - - ${this.hass.localize( - "ui.dialogs.restart.reboot.description" - )} - - - -
-
- - ${this.hass.localize( - "ui.dialogs.restart.shutdown.title" - )} - - - ${this.hass.localize( - "ui.dialogs.restart.shutdown.description" - )} - -
+
+ +
+ + ` : nothing} - -
- +
+
- +
+ ${this.hass.localize("ui.dialogs.restart.restart.title")} +
+
${this.hass.localize( - "ui.dialogs.restart.restart-safe-mode.title" + "ui.dialogs.restart.restart.description" )} - - - ${this.hass.localize( - "ui.dialogs.restart.restart-safe-mode.description" - )} - - - - - `} - +
+ + + + + + ${showRebootShutdown + ? html` + +
+ +
+
+ ${this.hass.localize( + "ui.dialogs.restart.reboot.title" + )} +
+
+ ${this.hass.localize( + "ui.dialogs.restart.reboot.description" + )} +
+ +
+ +
+ +
+
+ ${this.hass.localize( + "ui.dialogs.restart.shutdown.title" + )} +
+
+ ${this.hass.localize( + "ui.dialogs.restart.shutdown.description" + )} +
+ +
+ ` + : nothing} + +
+ +
+
+ ${this.hass.localize( + "ui.dialogs.restart.restart-safe-mode.title" + )} +
+
+ ${this.hass.localize( + "ui.dialogs.restart.restart-safe-mode.description" + )} +
+ +
+
+
+ `} +
+ `; } - private async _reload(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - + private async _reload() { this.closeDialog(); showToast(this, { @@ -244,13 +239,6 @@ class DialogRestart extends LitElement { } } - private async _restart(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - this._showRestartDialog(); - } - private async _showRestartDialog() { const confirmed = await showConfirmationDialog(this, { title: this.hass.localize("ui.dialogs.restart.restart.confirm_title"), @@ -279,13 +267,6 @@ class DialogRestart extends LitElement { } } - private async _restartSafeMode(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - this._showRestartSafeModeDialog(); - } - private async _showRestartSafeModeDialog() { const confirmed = await showConfirmationDialog(this, { title: this.hass.localize( @@ -320,10 +301,7 @@ class DialogRestart extends LitElement { } } - private async _hostReboot(ev): Promise { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } + private async _hostReboot(): Promise { const confirmed = await showConfirmationDialog(this, { title: this.hass.localize("ui.dialogs.restart.reboot.confirm_title"), text: this.hass.localize("ui.dialogs.restart.reboot.confirm_description"), @@ -357,10 +335,7 @@ class DialogRestart extends LitElement { } } - private async _hostShutdown(ev): Promise { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } + private async _hostShutdown(): Promise { const confirmed = await showConfirmationDialog(this, { title: this.hass.localize("ui.dialogs.restart.shutdown.confirm_title"), text: this.hass.localize( @@ -401,13 +376,13 @@ class DialogRestart extends LitElement { haStyle, haStyleDialog, css` - ha-dialog { + ha-md-dialog { --dialog-content-padding: 0; } @media all and (min-width: 550px) { - ha-dialog { - --mdc-dialog-min-width: 500px; - --mdc-dialog-max-width: 500px; + ha-md-dialog { + min-width: 500px; + max-width: 500px; } } @@ -425,6 +400,11 @@ class DialogRestart extends LitElement { border-radius: 50%; color: #fff; display: flex; + width: 40px; + height: 40px; + display: flex; + align-items: center; + justify-content: center; } .reload { background-color: #5f8a49;