diff --git a/src/dialogs/more-info/ha-more-info-dialog.ts b/src/dialogs/more-info/ha-more-info-dialog.ts index 4ae42dd862..4d454bff49 100644 --- a/src/dialogs/more-info/ha-more-info-dialog.ts +++ b/src/dialogs/more-info/ha-more-info-dialog.ts @@ -15,6 +15,7 @@ import { LitElement, css, html, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { cache } from "lit/directives/cache"; import { join } from "lit/directives/join"; +import { keyed } from "lit/directives/keyed"; import { dynamicElement } from "../../common/dom/dynamic-element-directive"; import { fireEvent } from "../../common/dom/fire_event"; import { stopPropagation } from "../../common/dom/stop_propagation"; @@ -96,6 +97,8 @@ export class MoreInfoDialog extends LitElement { @property({ type: Boolean, reflect: true }) public large = false; + @state() private _parentEntityIds: string[] = []; + @state() private _entityId?: string | null; @state() private _currView: View = DEFAULT_VIEW; @@ -207,8 +210,16 @@ export class MoreInfoDialog extends LitElement { private _goBack() { if (this._childView) { this._childView = undefined; - } else { + return; + } + if (this._initialView !== this._currView) { this._setView(this._initialView); + return; + } + if (this._parentEntityIds.length > 0) { + this._entityId = this._parentEntityIds.pop(); + this._currView = DEFAULT_VIEW; + this._loadEntityRegistryEntry(); } } @@ -302,7 +313,9 @@ export class MoreInfoDialog extends LitElement { const isDefaultView = this._currView === DEFAULT_VIEW && !this._childView; const isSpecificInitialView = this._initialView !== DEFAULT_VIEW && !this._childView; - const showCloseIcon = isDefaultView || isSpecificInitialView; + const showCloseIcon = + (isDefaultView && this._parentEntityIds.length === 0) || + isSpecificInitialView; const context = stateObj ? getEntityContext(stateObj, this.hass) @@ -521,54 +534,58 @@ export class MoreInfoDialog extends LitElement { @show-child-view=${this._showChildView} @entity-entry-updated=${this._entryUpdated} @toggle-edit-mode=${this._handleToggleInfoEditModeEvent} + @hass-more-info=${this._handleMoreInfoEvent} > - ${cache( - this._childView - ? html` -
- ${dynamicElement(this._childView.viewTag, { - hass: this.hass, - entry: this._entry, - params: this._childView.viewParams, - })} -
- ` - : this._currView === "info" + ${keyed( + this._entityId, + cache( + this._childView ? html` - +
+ ${dynamicElement(this._childView.viewTag, { + hass: this.hass, + entry: this._entry, + params: this._childView.viewParams, + })} +
` - : this._currView === "history" + : this._currView === "info" ? html` - + .entry=${this._entry} + .editMode=${this._infoEditMode} + > ` - : this._currView === "settings" + : this._currView === "history" ? html` - + > ` - : this._currView === "related" + : this._currView === "settings" ? html` - + .entityId=${this._entityId} + .entry=${this._entry} + > ` - : nothing + : this._currView === "related" + ? html` + + ` + : nothing + ) )} @@ -602,6 +619,19 @@ export class MoreInfoDialog extends LitElement { window.addEventListener("show-dialog", this._disableEscapeKeyClose); } + private _handleMoreInfoEvent(ev) { + ev.stopPropagation(); + const entityId = ev.detail.entityId; + if (!entityId) { + return; + } + this._parentEntityIds = [...this._parentEntityIds, this._entityId!]; + this._entityId = entityId; + this._currView = DEFAULT_VIEW; + this._childView = undefined; + this._loadEntityRegistryEntry(); + } + private _enableEscapeKeyClose = () => { this._isEscapeEnabled = true; }; @@ -667,6 +697,7 @@ export class MoreInfoDialog extends LitElement { display: flex; flex-direction: column; align-items: flex-start; + margin: 0 0 -10px 0; } .title p { diff --git a/src/dialogs/more-info/more-info-content.ts b/src/dialogs/more-info/more-info-content.ts index 25d3cfbf84..8247130a46 100644 --- a/src/dialogs/more-info/more-info-content.ts +++ b/src/dialogs/more-info/more-info-content.ts @@ -1,11 +1,15 @@ import type { HassEntity } from "home-assistant-js-websocket"; -import { LitElement, nothing } from "lit"; +import { css, html, LitElement, nothing } from "lit"; import { customElement, property } from "lit/decorators"; +import memoizeOne from "memoize-one"; +import { dynamicElement } from "../../common/dom/dynamic-element-directive"; +import "../../components/ha-badge"; import type { ExtEntityRegistryEntry } from "../../data/entity_registry"; +import type { TileCardConfig } from "../../panels/lovelace/cards/types"; import { importMoreInfoControl } from "../../panels/lovelace/custom-card-helpers"; +import "../../panels/lovelace/sections/hui-section"; import type { HomeAssistant } from "../../types"; import { stateMoreInfoType } from "./state_more_info_control"; -import { dynamicElement } from "../../common/dom/dynamic-element-directive"; @customElement("more-info-content") class MoreInfoContent extends LitElement { @@ -33,13 +37,47 @@ class MoreInfoContent extends LitElement { } if (!moreInfoType) return nothing; - return dynamicElement(moreInfoType, { - hass: this.hass, - stateObj: this.stateObj, - entry: this.entry, - editMode: this.editMode, - }); + + return html` + ${dynamicElement(moreInfoType, { + hass: this.hass, + stateObj: this.stateObj, + entry: this.entry, + editMode: this.editMode, + })} + ${this.stateObj.attributes.entity_id && + this.stateObj.attributes.entity_id.length + ? html` + + + ` + : nothing} + `; } + + private _entitiesSectionConfig = memoizeOne((entityIds: string[]) => ({ + type: "grid", + cards: entityIds.map( + (entityId) => + ({ + type: "tile", + entity: entityId, + }) as TileCardConfig + ), + })); + + static styles = css` + hui-section { + width: 100%; + display: block; + margin-top: 16px; + } + `; } declare global {