diff --git a/src/panels/config/core/ha-config-section-updates.ts b/src/panels/config/core/ha-config-section-updates.ts index 3207620850..e0c0c6411e 100644 --- a/src/panels/config/core/ha-config-section-updates.ts +++ b/src/panels/config/core/ha-config-section-updates.ts @@ -1,22 +1,35 @@ +import type { ActionDetail } from "@material/mwc-list"; import "@material/mwc-list/mwc-list-item"; import { mdiDotsVertical } from "@mdi/js"; import { HassEntities } from "home-assistant-js-websocket"; import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; +import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { caseInsensitiveStringCompare } from "../../../common/string/compare"; import "../../../components/ha-alert"; import "../../../components/ha-bar"; import "../../../components/ha-button-menu"; +import "../../../components/ha-card"; import "../../../components/ha-metric"; +import { extractApiErrorMessage } from "../../../data/hassio/common"; +import { + fetchHassioSupervisorInfo, + HassioSupervisorInfo, + reloadSupervisor, + setSupervisorOption, + SupervisorOptions, +} from "../../../data/hassio/supervisor"; import { updateCanInstall, UpdateEntity } from "../../../data/update"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { + showAlertDialog, + showConfirmationDialog, +} from "../../../dialogs/generic/show-dialog-box"; import "../../../layouts/hass-subpage"; import type { HomeAssistant } from "../../../types"; import { showToast } from "../../../util/toast"; import "../dashboard/ha-config-updates"; -import "./ha-config-analytics"; @customElement("ha-config-section-updates") class HaConfigSectionUpdates extends LitElement { @@ -26,8 +39,20 @@ class HaConfigSectionUpdates extends LitElement { @state() private _showSkipped = false; + @state() private _supervisorInfo?: HassioSupervisorInfo; + private _notifyUpdates = false; + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + + if (isComponentLoaded(this.hass, "hassio")) { + fetchHassioSupervisorInfo(this.hass).then((data) => { + this._supervisorInfo = data; + }); + } + } + protected render(): TemplateResult { const canInstallUpdates = this._filterUpdateEntitiesWithInstall( this.hass.states, @@ -44,18 +69,27 @@ class HaConfigSectionUpdates extends LitElement { - + ${this._showSkipped ? this.hass.localize("ui.panel.config.updates.hide_skipped") : this.hass.localize("ui.panel.config.updates.show_skipped")} + ${this._supervisorInfo?.channel !== "dev" + ? html` + + ${this._supervisorInfo?.channel === "stable" + ? this.hass.localize("ui.panel.config.updates.join_beta") + : this.hass.localize("ui.panel.config.updates.leave_beta")} + + ` + : ""}
@@ -111,8 +145,53 @@ class HaConfigSectionUpdates extends LitElement { } } - private _toggleSkipped(): void { - this._showSkipped = !this._showSkipped; + private _handleAction(ev: CustomEvent) { + switch (ev.detail.index) { + case 0: + this._showSkipped = !this._showSkipped; + break; + case 1: + this._toggleBeta(); + break; + } + } + + private async _toggleBeta(): Promise { + if (this._supervisorInfo!.channel === "stable") { + const confirmed = await showConfirmationDialog(this, { + title: this.hass.localize("ui.dialogs.join_beta_channel.title"), + text: html`${this.hass.localize("ui.dialogs.join_beta_channel.warning")} +
+ ${this.hass.localize("ui.dialogs.join_beta_channel.backup")} +

+ ${this.hass.localize("ui.dialogs.join_beta_channel.release_items")} +
    +
  • Home Assistant Core
  • +
  • Home Assistant Supervisor
  • +
  • Home Assistant Operating System
  • +
+
+ ${this.hass.localize("ui.dialogs.join_beta_channel.confirm")}`, + confirmText: this.hass.localize("ui.panel.config.updates.join_beta"), + dismissText: this.hass.localize("ui.common.cancel"), + }); + + if (!confirmed) { + return; + } + } + + try { + const data: Partial = { + channel: this._supervisorInfo!.channel === "stable" ? "beta" : "stable", + }; + await setSupervisorOption(this.hass, data); + await reloadSupervisor(this.hass); + } catch (err: any) { + showAlertDialog(this, { + text: extractApiErrorMessage(err), + }); + } } private async _checkUpdates(): Promise { diff --git a/src/translations/en.json b/src/translations/en.json index cb884a4a66..80a30f6966 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1026,6 +1026,13 @@ "docker": "[%key:supervisor::system::supervisor::unhealthy_reason::docker%]", "untrusted": "[%key:supervisor::system::supervisor::unhealthy_reason::untrusted%]" } + }, + "join_beta_channel": { + "title": "Join the beta channel", + "warning": "[%key:supervisor::system::supervisor::beta_warning%]", + "backup": "[%key:supervisor::system::supervisor::beta_backup%]", + "release_items": "[%key:supervisor::system::supervisor::beta_release_items%]", + "confirm": "[%key:supervisor::system::supervisor::beta_join_confirm%]" } }, "duration": { @@ -1169,6 +1176,8 @@ "show": "show", "show_skipped": "Show skipped", "hide_skipped": "Hide skipped", + "join_beta": "[%key:supervisor::system::supervisor::join_beta_action%]", + "leave_beta": "[%key:supervisor::system::supervisor::leave_beta_action%]", "skipped": "Skipped" }, "areas": {