diff --git a/hassio/src/dashboard/hassio-update.ts b/hassio/src/dashboard/hassio-update.ts index 730d2a245a..13892bf5fc 100644 --- a/hassio/src/dashboard/hassio-update.ts +++ b/hassio/src/dashboard/hassio-update.ts @@ -31,6 +31,7 @@ import { } from "../../../src/dialogs/generic/show-dialog-box"; import { haStyle } from "../../../src/resources/styles"; import { HomeAssistant } from "../../../src/types"; +import { showDialogSupervisorCoreUpdate } from "../dialogs/core/show-dialog-core-update"; import { hassioStyle } from "../resources/hassio-style"; @customElement("hassio-update") @@ -134,6 +135,10 @@ export class HassioUpdate extends LitElement { private async _confirmUpdate(ev): Promise { const item = ev.currentTarget; + if (item.key === "core") { + showDialogSupervisorCoreUpdate(this, { core: this.supervisor.core }); + return; + } item.progress = true; const confirmed = await showConfirmationDialog(this, { title: `Update ${item.name}`, diff --git a/hassio/src/dialogs/addon/dialog-supervisor-addon-update.ts b/hassio/src/dialogs/addon/dialog-supervisor-addon-update.ts index 00c9854ef3..521804a09d 100644 --- a/hassio/src/dialogs/addon/dialog-supervisor-addon-update.ts +++ b/hassio/src/dialogs/addon/dialog-supervisor-addon-update.ts @@ -97,7 +97,7 @@ class DialogSupervisorAddonUpdate extends LitElement { Update ` - : html` + : html`

${this._action === "update" diff --git a/hassio/src/dialogs/core/dialog-supervisor-core-update.ts b/hassio/src/dialogs/core/dialog-supervisor-core-update.ts new file mode 100644 index 0000000000..b42e8805f6 --- /dev/null +++ b/hassio/src/dialogs/core/dialog-supervisor-core-update.ts @@ -0,0 +1,174 @@ +import "@material/mwc-button/mwc-button"; +import { + css, + CSSResult, + customElement, + html, + internalProperty, + LitElement, + TemplateResult, +} from "lit-element"; +import { fireEvent } from "../../../../src/common/dom/fire_event"; +import "../../../../src/components/ha-circular-progress"; +import "../../../../src/components/ha-dialog"; +import "../../../../src/components/ha-settings-row"; +import "../../../../src/components/ha-svg-icon"; +import "../../../../src/components/ha-switch"; +import { extractApiErrorMessage } from "../../../../src/data/hassio/common"; +import { createHassioPartialSnapshot } from "../../../../src/data/hassio/snapshot"; +import { HassioHomeAssistantInfo } from "../../../../src/data/hassio/supervisor"; +import { updateCore } from "../../../../src/data/supervisor/core"; +import { haStyle, haStyleDialog } from "../../../../src/resources/styles"; +import type { HomeAssistant } from "../../../../src/types"; +import { SupervisorDialogSupervisorCoreUpdateParams } from "./show-dialog-core-update"; + +@customElement("dialog-supervisor-core-update") +class DialogSupervisorCoreUpdate extends LitElement { + public hass!: HomeAssistant; + + public core!: HassioHomeAssistantInfo; + + @internalProperty() private _opened = false; + + @internalProperty() private _createSnapshot = true; + + @internalProperty() private _action: "snapshot" | "update" | null = null; + + @internalProperty() private _error?: string; + + public async showDialog( + params: SupervisorDialogSupervisorCoreUpdateParams + ): Promise { + this._opened = true; + this.core = params.core; + await this.updateComplete; + } + + public closeDialog(): void { + this._action = null; + this._createSnapshot = true; + this._opened = false; + fireEvent(this, "dialog-closed", { dialog: this.localName }); + } + + public focus(): void { + this.updateComplete.then(() => + (this.shadowRoot?.querySelector( + "[dialogInitialFocus]" + ) as HTMLElement)?.focus() + ); + } + + protected render(): TemplateResult { + return html` + + ${this._action === null + ? html`

+ Are you sure you want to update Home Assistant Core to version + ${this.core.version_latest}? +
+ + + + Snapshot + + + Create a snapshot of Home Assistant Core before updating + + + + + + Cancel + + + Update + ` + : html` + +

+ ${this._action === "update" + ? `Update to version ${this.core.version_latest} in progress` + : "Creating snapshot in progress"} +

`} + ${this._error ? html`

${this._error}

` : ""} + + `; + } + + private _toggleSnapshot() { + this._createSnapshot = !this._createSnapshot; + } + + private async _update() { + if (this._createSnapshot) { + this._action = "snapshot"; + try { + await createHassioPartialSnapshot(this.hass, { + name: `core_${this.core.version}`, + folders: ["homeassistant"], + homeassistant: true, + }); + } catch (err) { + this._error = extractApiErrorMessage(err); + this._action = null; + return; + } + } + + this._action = "update"; + try { + await updateCore(this.hass); + } catch (err) { + this._error = extractApiErrorMessage(err); + this._action = null; + return; + } + fireEvent(this, "supervisor-colllection-refresh", { colllection: "core" }); + this.closeDialog(); + } + + static get styles(): CSSResult[] { + return [ + haStyle, + haStyleDialog, + css` + .form { + color: var(--primary-text-color); + } + + ha-settings-row { + margin-top: 32px; + padding: 0; + } + + ha-circular-progress { + display: block; + margin: 32px; + text-align: center; + } + + .progress-text { + text-align: center; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "dialog-supervisor-core-update": DialogSupervisorCoreUpdate; + } +} diff --git a/hassio/src/dialogs/core/show-dialog-core-update.ts b/hassio/src/dialogs/core/show-dialog-core-update.ts new file mode 100644 index 0000000000..0c2e173d7c --- /dev/null +++ b/hassio/src/dialogs/core/show-dialog-core-update.ts @@ -0,0 +1,17 @@ +import { fireEvent } from "../../../../src/common/dom/fire_event"; +import { HassioHomeAssistantInfo } from "../../../../src/data/hassio/supervisor"; + +export interface SupervisorDialogSupervisorCoreUpdateParams { + core: HassioHomeAssistantInfo; +} + +export const showDialogSupervisorCoreUpdate = ( + element: HTMLElement, + dialogParams: SupervisorDialogSupervisorCoreUpdateParams +): void => { + fireEvent(element, "show-dialog", { + dialogTag: "dialog-supervisor-core-update", + dialogImport: () => import("./dialog-supervisor-core-update"), + dialogParams, + }); +}; diff --git a/hassio/src/system/hassio-core-info.ts b/hassio/src/system/hassio-core-info.ts index c07ea824f5..e3c455e510 100644 --- a/hassio/src/system/hassio-core-info.ts +++ b/hassio/src/system/hassio-core-info.ts @@ -10,7 +10,6 @@ import { property, TemplateResult, } from "lit-element"; -import { fireEvent } from "../../../src/common/dom/fire_event"; import "../../../src/components/buttons/ha-progress-button"; import "../../../src/components/ha-button-menu"; import "../../../src/components/ha-card"; @@ -20,7 +19,7 @@ import { fetchHassioStats, HassioStats, } from "../../../src/data/hassio/common"; -import { restartCore, updateCore } from "../../../src/data/supervisor/core"; +import { restartCore } from "../../../src/data/supervisor/core"; import { Supervisor } from "../../../src/data/supervisor/supervisor"; import { showAlertDialog, @@ -30,6 +29,7 @@ import { haStyle } from "../../../src/resources/styles"; import { HomeAssistant } from "../../../src/types"; import { bytesToString } from "../../../src/util/bytes-to-string"; import "../components/supervisor-metric"; +import { showDialogSupervisorCoreUpdate } from "../dialogs/core/show-dialog-core-update"; import { hassioStyle } from "../resources/hassio-style"; @customElement("hassio-core-info") @@ -149,35 +149,8 @@ class HassioCoreInfo extends LitElement { } } - private async _coreUpdate(ev: CustomEvent): Promise { - const button = ev.currentTarget as any; - button.progress = true; - - const confirmed = await showConfirmationDialog(this, { - title: "Update Home Assistant Core", - text: `Are you sure you want to update Home Assistant Core to version ${this.supervisor.core.version_latest}?`, - confirmText: "update", - dismissText: "cancel", - }); - - if (!confirmed) { - button.progress = false; - return; - } - - try { - await updateCore(this.hass); - fireEvent(this, "supervisor-colllection-refresh", { - colllection: "core", - }); - } catch (err) { - showAlertDialog(this, { - title: "Failed to update Home Assistant Core", - text: extractApiErrorMessage(err), - }); - } finally { - button.progress = false; - } + private async _coreUpdate(): Promise { + showDialogSupervisorCoreUpdate(this, { core: this.supervisor.core }); } static get styles(): CSSResult[] {