From 8805ddc76fcf65d9340c7ae364ff17c9b7a9d725 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Wed, 1 Mar 2023 14:43:29 +0100 Subject: [PATCH] Add dedicated more info for no state entity --- src/dialogs/more-info/ha-more-info-info.ts | 29 +-- src/dialogs/more-info/more-info-no-state.ts | 194 ++++++++++++++++++++ 2 files changed, 204 insertions(+), 19 deletions(-) create mode 100644 src/dialogs/more-info/more-info-no-state.ts diff --git a/src/dialogs/more-info/ha-more-info-info.ts b/src/dialogs/more-info/ha-more-info-info.ts index e9d59d3b62..20199af087 100644 --- a/src/dialogs/more-info/ha-more-info-info.ts +++ b/src/dialogs/more-info/ha-more-info-info.ts @@ -13,6 +13,7 @@ import { import "./ha-more-info-history"; import "./ha-more-info-logbook"; import "./more-info-content"; +import "./more-info-no-state"; @customElement("ha-more-info-info") export class MoreInfoInfo extends LitElement { @@ -23,29 +24,20 @@ export class MoreInfoInfo extends LitElement { protected render() { const entityId = this.entityId; const stateObj = this.hass.states[entityId] as HassEntity | undefined; - const entityRegObj = this.hass.entities[entityId]; const domain = computeDomain(entityId); const isNewMoreInfo = stateObj && computeShowNewMoreInfo(stateObj); + if (!stateObj) { + return html` + + `; + } + return html`
- ${!stateObj - ? html` - ${this.hass.localize( - "ui.dialogs.entity_registry.editor.unavailable" - )} - ` - : ""} - ${stateObj?.attributes.restored && entityRegObj - ? html` - ${this.hass.localize( - "ui.dialogs.more_info_control.restored.no_longer_provided", - { - integration: entityRegObj.platform, - } - )} - ` - : ""}
${DOMAINS_NO_INFO.includes(domain) || isNewMoreInfo ? "" @@ -75,7 +67,6 @@ export class MoreInfoInfo extends LitElement { .stateObj=${stateObj} .hass=${this.hass} > -
`; diff --git a/src/dialogs/more-info/more-info-no-state.ts b/src/dialogs/more-info/more-info-no-state.ts new file mode 100644 index 0000000000..50bcafc23c --- /dev/null +++ b/src/dialogs/more-info/more-info-no-state.ts @@ -0,0 +1,194 @@ +import "@material/mwc-button/mwc-button"; +import { mdiExclamationThick } from "@mdi/js"; +import { UnsubscribeFunc } from "home-assistant-js-websocket"; +import { css, html, LitElement, nothing } from "lit"; +import { customElement, property, state } from "lit/decorators"; +import memoizeOne from "memoize-one"; +import "../../components/ha-svg-icon"; +import { + DeviceRegistryEntry, + subscribeDeviceRegistry, + updateDeviceRegistryEntry, +} from "../../data/device_registry"; +import { + EntityRegistryEntry, + subscribeEntityRegistry, + updateEntityRegistryEntry, +} from "../../data/entity_registry"; +import { SubscribeMixin } from "../../mixins/subscribe-mixin"; +import { showDeviceRegistryDetailDialog } from "../../panels/config/devices/device-registry-detail/show-dialog-device-registry-detail"; +import type { HomeAssistant } from "../../types"; +import { showAlertDialog } from "../generic/show-dialog-box"; + +@customElement("more-info-no-state") +export class MoreInfoNoState extends SubscribeMixin(LitElement) { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public entityId!: string; + + @state() private _devices?: DeviceRegistryEntry[]; + + @state() private _entities?: EntityRegistryEntry[]; + + public hassSubscribe(): UnsubscribeFunc[] { + return [ + subscribeDeviceRegistry(this.hass.connection, (devices) => { + this._devices = devices; + }), + subscribeEntityRegistry(this.hass.connection!, (entities) => { + this._entities = entities; + }), + ]; + } + + private getDeviceEntry = memoizeOne( + ( + deviceId: string, + devices?: DeviceRegistryEntry[] + ): DeviceRegistryEntry | undefined => + devices?.find((device) => device.id === deviceId) + ); + + private getEntityEntry = memoizeOne( + ( + entityId: string, + entities?: EntityRegistryEntry[] + ): EntityRegistryEntry | undefined => + entities?.find((entity) => entity.entity_id === entityId) + ); + + private _openDeviceSettings() { + const entity = this.getEntityEntry(this.entityId, this._entities); + + if (!entity?.device_id) return; + const device = this.getDeviceEntry(entity.device_id, this._devices); + + if (!device) return; + + showDeviceRegistryDetailDialog(this, { + device: device, + updateEntry: async (updates) => { + await updateDeviceRegistryEntry(this.hass, device.id, updates); + }, + }); + } + + private async _enableEntry() { + const entity = this.getEntityEntry(this.entityId, this._entities); + if (!entity) return; + + const result = await updateEntityRegistryEntry( + this.hass!, + entity.entity_id, + { disabled_by: null } + ); + + if (result.require_restart) { + showAlertDialog(this, { + text: this.hass.localize( + "ui.dialogs.entity_registry.editor.enabled_restart_confirm" + ), + }); + } + if (result.reload_delay) { + showAlertDialog(this, { + text: this.hass.localize( + "ui.dialogs.entity_registry.editor.enabled_delay_confirm", + "delay", + result.reload_delay + ), + }); + } + } + + protected render() { + const entityId = this.entityId; + + const entity = this.getEntityEntry(entityId, this._entities); + const device = entity?.device_id + ? this.getDeviceEntry(entity.device_id, this._devices) + : undefined; + + return html` + ${ + device?.disabled_by + ? html` +
+ +

+ ${this.hass!.localize( + "ui.dialogs.entity_registry.editor.device_disabled" + )} +

+ + ${this.hass!.localize( + "ui.dialogs.entity_registry.editor.open_device_settings" + )} + +
+ ` + : entity?.disabled_by + ? html` +
+ +

+ ${this.hass!.localize( + "ui.dialogs.entity_registry.editor.entity_disabled" + )} +

+ ${["user", "integration"].includes(entity.disabled_by!) + ? html` + + ${this.hass!.localize( + "ui.dialogs.entity_registry.editor.enable_entity" + )} + ` + : nothing} +
+ ` + : html` +
+ +

+ ${this.hass!.localize( + "ui.dialogs.entity_registry.editor.unavailable" + )} +

+
+ ` + } + + `; + } + + static get styles() { + return css` + .content { + display: flex; + flex-direction: column; + align-items: center; + padding: 8px 24px 24px 24px; + } + .content ha-svg-icon { + background-color: var(--warning-color); + color: white; + padding: 16px; + border-radius: 50%; + margin-bottom: 8px; + } + .content p { + font-weight: 400; + font-size: 14px; + line-height: 20px; + letter-spacing: 0.25px; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "more-info-no-state": MoreInfoNoState; + } +}