From b03abc249be706992b2a3a7626c73d5f0abcfd40 Mon Sep 17 00:00:00 2001 From: Zack Barett Date: Tue, 26 Apr 2022 23:52:22 -0500 Subject: [PATCH] Fix Updates Page Toast - Move to overflow (#12453) --- src/data/update.ts | 77 +++++++++ .../config/core/ha-config-section-updates.ts | 161 +++++------------- .../config/dashboard/ha-config-dashboard.ts | 86 +--------- 3 files changed, 124 insertions(+), 200 deletions(-) diff --git a/src/data/update.ts b/src/data/update.ts index 8976e66f36..e76a8947a3 100644 --- a/src/data/update.ts +++ b/src/data/update.ts @@ -1,10 +1,15 @@ import type { + HassEntities, HassEntityAttributeBase, HassEntityBase, } from "home-assistant-js-websocket"; import { BINARY_STATE_ON } from "../common/const"; +import { computeStateDomain } from "../common/entity/compute_state_domain"; import { supportsFeature } from "../common/entity/supports-feature"; +import { caseInsensitiveStringCompare } from "../common/string/compare"; +import { showAlertDialog } from "../dialogs/generic/show-dialog-box"; import { HomeAssistant } from "../types"; +import { showToast } from "../util/toast"; export const UPDATE_SUPPORT_INSTALL = 1; export const UPDATE_SUPPORT_SPECIFIC_VERSION = 2; @@ -47,3 +52,75 @@ export const updateReleaseNotes = (hass: HomeAssistant, entityId: string) => type: "update/release_notes", entity_id: entityId, }); + +export const filterUpdateEntities = (entities: HassEntities) => + ( + Object.values(entities).filter( + (entity) => computeStateDomain(entity) === "update" + ) as UpdateEntity[] + ).sort((a, b) => { + if (a.attributes.title === "Home Assistant Core") { + return -3; + } + if (b.attributes.title === "Home Assistant Core") { + return 3; + } + if (a.attributes.title === "Home Assistant Operating System") { + return -2; + } + if (b.attributes.title === "Home Assistant Operating System") { + return 2; + } + if (a.attributes.title === "Home Assistant Supervisor") { + return -1; + } + if (b.attributes.title === "Home Assistant Supervisor") { + return 1; + } + return caseInsensitiveStringCompare( + a.attributes.title || a.attributes.friendly_name || "", + b.attributes.title || b.attributes.friendly_name || "" + ); + }); + +export const filterUpdateEntitiesWithInstall = ( + entities: HassEntities, + showSkipped = false +) => + filterUpdateEntities(entities).filter((entity) => + updateCanInstall(entity, showSkipped) + ); + +export const checkForEntityUpdates = async ( + element: HTMLElement, + hass: HomeAssistant +) => { + const entities = filterUpdateEntities(hass.states).map( + (entity) => entity.entity_id + ); + + if (!entities.length) { + showAlertDialog(element, { + title: hass.localize("ui.panel.config.updates.no_update_entities.title"), + text: hass.localize( + "ui.panel.config.updates.no_update_entities.description" + ), + warning: true, + }); + return; + } + + await hass.callService("homeassistant", "update_entity", { + entity_id: entities, + }); + + if (filterUpdateEntitiesWithInstall(hass.states).length) { + showToast(element, { + message: hass.localize("ui.panel.config.updates.updates_refreshed"), + }); + } else { + showToast(element, { + message: hass.localize("ui.panel.config.updates.no_new_updates"), + }); + } +}; diff --git a/src/panels/config/core/ha-config-section-updates.ts b/src/panels/config/core/ha-config-section-updates.ts index 708d44de51..f5cc96ecae 100644 --- a/src/panels/config/core/ha-config-section-updates.ts +++ b/src/panels/config/core/ha-config-section-updates.ts @@ -1,13 +1,11 @@ import type { ActionDetail } from "@material/mwc-list"; import "@material/mwc-list/mwc-list-item"; -import { mdiDotsVertical } from "@mdi/js"; +import { mdiDotsVertical, mdiRefresh } from "@mdi/js"; import { HassEntities } from "home-assistant-js-websocket"; -import { css, html, LitElement, PropertyValues, TemplateResult } from "lit"; +import { css, html, LitElement, 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"; @@ -21,14 +19,16 @@ import { setSupervisorOption, SupervisorOptions, } from "../../../data/hassio/supervisor"; -import { updateCanInstall, UpdateEntity } from "../../../data/update"; +import { + checkForEntityUpdates, + filterUpdateEntitiesWithInstall, +} from "../../../data/update"; 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"; @customElement("ha-config-section-updates") @@ -41,8 +41,6 @@ class HaConfigSectionUpdates extends LitElement { @state() private _supervisorInfo?: HassioSupervisorInfo; - private _notifyUpdates = false; - protected firstUpdated(changedProps) { super.firstUpdated(changedProps); @@ -66,31 +64,38 @@ class HaConfigSectionUpdates extends LitElement { .narrow=${this.narrow} .header=${this.hass.localize("ui.panel.config.updates.caption")} > - +
- - ${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")} - - ` - : ""} - + + + + ${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" + )} + + ` + : ""} + +
@@ -107,44 +112,12 @@ class HaConfigSectionUpdates extends LitElement { ${this.hass.localize("ui.panel.config.updates.no_updates")} `}
-
- - ${this.hass.localize("ui.panel.config.updates.check_updates")} - -
`; } - protected override updated(changedProps: PropertyValues): void { - super.updated(changedProps); - - if ( - !changedProps.has("hass") || - !this._notifyUpdates || - !changedProps.has("_showSkipped") - ) { - return; - } - this._notifyUpdates = false; - if ( - this._filterUpdateEntitiesWithInstall(this.hass.states, this._showSkipped) - .length - ) { - showToast(this, { - message: this.hass.localize( - "ui.panel.config.updates.updates_refreshed" - ), - }); - } else { - showToast(this, { - message: this.hass.localize("ui.panel.config.updates.no_new_updates"), - }); - } - } - private _handleAction(ev: CustomEvent) { switch (ev.detail.index) { case 0: @@ -195,64 +168,12 @@ class HaConfigSectionUpdates extends LitElement { } private async _checkUpdates(): Promise { - const _entities = this._filterUpdateEntities(this.hass.states).map( - (entity) => entity.entity_id - ); - - if (_entities.length) { - this._notifyUpdates = true; - await this.hass.callService("homeassistant", "update_entity", { - entity_id: _entities, - }); - return; - } - showAlertDialog(this, { - title: this.hass.localize( - "ui.panel.config.updates.no_update_entities.title" - ), - text: this.hass.localize( - "ui.panel.config.updates.no_update_entities.description" - ), - warning: true, - }); + checkForEntityUpdates(this, this.hass); } - private _filterUpdateEntities = memoizeOne((entities: HassEntities) => - ( - Object.values(entities).filter( - (entity) => computeStateDomain(entity) === "update" - ) as UpdateEntity[] - ).sort((a, b) => { - if (a.attributes.title === "Home Assistant Core") { - return -3; - } - if (b.attributes.title === "Home Assistant Core") { - return 3; - } - if (a.attributes.title === "Home Assistant Operating System") { - return -2; - } - if (b.attributes.title === "Home Assistant Operating System") { - return 2; - } - if (a.attributes.title === "Home Assistant Supervisor") { - return -1; - } - if (b.attributes.title === "Home Assistant Supervisor") { - return 1; - } - return caseInsensitiveStringCompare( - a.attributes.title || a.attributes.friendly_name || "", - b.attributes.title || b.attributes.friendly_name || "" - ); - }) - ); - private _filterUpdateEntitiesWithInstall = memoizeOne( (entities: HassEntities, showSkipped: boolean) => - this._filterUpdateEntities(entities).filter((entity) => - updateCanInstall(entity, showSkipped) - ) + filterUpdateEntitiesWithInstall(entities, showSkipped) ); static styles = css` @@ -270,12 +191,6 @@ class HaConfigSectionUpdates extends LitElement { display: flex; margin-bottom: max(24px, env(safe-area-inset-bottom)); } - .card-actions { - height: 48px; - display: flex; - justify-content: space-between; - align-items: center; - } .card-content { display: flex; diff --git a/src/panels/config/dashboard/ha-config-dashboard.ts b/src/panels/config/dashboard/ha-config-dashboard.ts index 5eaa08aaa6..f4ad00f027 100644 --- a/src/panels/config/dashboard/ha-config-dashboard.ts +++ b/src/panels/config/dashboard/ha-config-dashboard.ts @@ -3,7 +3,7 @@ import "@material/mwc-list/mwc-list-item"; import { mdiCloudLock, mdiDotsVertical, mdiMagnify, mdiNewBox } from "@mdi/js"; import "@polymer/app-layout/app-header/app-header"; import "@polymer/app-layout/app-toolbar/app-toolbar"; -import type { HassEntities } from "home-assistant-js-websocket"; +import { HassEntities } from "home-assistant-js-websocket"; import { css, CSSResultGroup, @@ -15,8 +15,6 @@ import { 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-button-menu"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; @@ -25,15 +23,17 @@ import "../../../components/ha-menu-button"; import "../../../components/ha-svg-icon"; import "../../../components/ha-tip"; import { CloudStatus } from "../../../data/cloud"; -import { updateCanInstall, UpdateEntity } from "../../../data/update"; -import { showAlertDialog } from "../../../dialogs/generic/show-dialog-box"; +import { + checkForEntityUpdates, + filterUpdateEntitiesWithInstall, + UpdateEntity, +} from "../../../data/update"; import { showQuickBar } from "../../../dialogs/quick-bar/show-dialog-quick-bar"; import "../../../layouts/ha-app-layout"; import { PageNavigation } from "../../../layouts/hass-tabs-subpage"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant } from "../../../types"; import { documentationUrl } from "../../../util/documentation-url"; -import { showToast } from "../../../util/toast"; import "../ha-config-section"; import { configSections } from "../ha-panel-config"; import "./ha-config-navigation"; @@ -113,8 +113,6 @@ class HaConfigDashboard extends LitElement { @state() private _tip?: string; - private _notifyUpdates = false; - private _pages = memoizeOne((clouStatus, isLoaded) => { const pages: PageNavigation[] = []; if (clouStatus && isLoaded) { @@ -219,60 +217,12 @@ class HaConfigDashboard extends LitElement { if (!this._tip && changedProps.has("hass")) { this._tip = randomTip(this.hass); } - - if (!changedProps.has("hass") || !this._notifyUpdates) { - return; - } - this._notifyUpdates = false; - if (this._filterUpdateEntitiesWithInstall(this.hass.states).length) { - showToast(this, { - message: this.hass.localize( - "ui.panel.config.updates.updates_refreshed" - ), - }); - } else { - showToast(this, { - message: this.hass.localize("ui.panel.config.updates.no_new_updates"), - }); - } } - private _filterUpdateEntities = memoizeOne((entities: HassEntities) => - ( - Object.values(entities).filter( - (entity) => computeStateDomain(entity) === "update" - ) as UpdateEntity[] - ).sort((a, b) => { - if (a.attributes.title === "Home Assistant Core") { - return -3; - } - if (b.attributes.title === "Home Assistant Core") { - return 3; - } - if (a.attributes.title === "Home Assistant Operating System") { - return -2; - } - if (b.attributes.title === "Home Assistant Operating System") { - return 2; - } - if (a.attributes.title === "Home Assistant Supervisor") { - return -1; - } - if (b.attributes.title === "Home Assistant Supervisor") { - return 1; - } - return caseInsensitiveStringCompare( - a.attributes.title || a.attributes.friendly_name || "", - b.attributes.title || b.attributes.friendly_name || "" - ); - }) - ); - private _filterUpdateEntitiesWithInstall = memoizeOne( (entities: HassEntities): [UpdateEntity[], number] => { - const updates = this._filterUpdateEntities(entities).filter((entity) => - updateCanInstall(entity) - ); + const updates = filterUpdateEntitiesWithInstall(entities); + return [ updates.slice(0, updates.length === 3 ? updates.length : 2), updates.length, @@ -288,27 +238,9 @@ class HaConfigDashboard extends LitElement { } private async _handleMenuAction(ev: CustomEvent) { - const _entities = this._filterUpdateEntities(this.hass.states).map( - (entity) => entity.entity_id - ); switch (ev.detail.index) { case 0: - if (_entities.length) { - this._notifyUpdates = true; - await this.hass.callService("homeassistant", "update_entity", { - entity_id: _entities, - }); - return; - } - showAlertDialog(this, { - title: this.hass.localize( - "ui.panel.config.updates.no_update_entities.title" - ), - text: this.hass.localize( - "ui.panel.config.updates.no_update_entities.description" - ), - warning: true, - }); + checkForEntityUpdates(this, this.hass); break; } }