diff --git a/src/dialogs/more-info/controls/more-info-group.js b/src/dialogs/more-info/controls/more-info-group.js deleted file mode 100644 index fabab470cc..0000000000 --- a/src/dialogs/more-info/controls/more-info-group.js +++ /dev/null @@ -1,111 +0,0 @@ -import { dom } from "@polymer/polymer/lib/legacy/polymer.dom"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -/* eslint-plugin-disable lit */ -import { PolymerElement } from "@polymer/polymer/polymer-element"; -import dynamicContentUpdater from "../../../common/dom/dynamic_content_updater"; -import { computeStateDomain } from "../../../common/entity/compute_state_domain"; -import "../../../state-summary/state-card-content"; - -class MoreInfoGroup extends PolymerElement { - static get template() { - return html` - - -
- - `; - } - - static get properties() { - return { - hass: { - type: Object, - }, - - stateObj: { - type: Object, - }, - - states: { - type: Array, - computed: "computeStates(stateObj, hass)", - }, - }; - } - - static get observers() { - return ["statesChanged(stateObj, states)"]; - } - - computeStates(stateObj, hass) { - const states = []; - const entIds = stateObj.attributes.entity_id || []; - - for (let i = 0; i < entIds.length; i++) { - const state = hass.states[entIds[i]]; - - if (state) { - states.push(state); - } - } - - return states; - } - - statesChanged(stateObj, states) { - let groupDomainStateObj = false; - let groupDomain = false; - - if (states && states.length > 0) { - const baseStateObj = states.find((s) => s.state === "on") || states[0]; - groupDomain = computeStateDomain(baseStateObj); - - // Groups need to be filtered out or we'll show content of - // first child above the children of the current group - if (groupDomain !== "group") { - groupDomainStateObj = { - ...baseStateObj, - entity_id: stateObj.entity_id, - attributes: { ...baseStateObj.attributes }, - }; - - for (let i = 0; i < states.length; i++) { - if (groupDomain !== computeStateDomain(states[i])) { - groupDomainStateObj = false; - break; - } - } - } - } - - if (!groupDomainStateObj) { - const el = dom(this.$.groupedControlDetails); - if (el.lastChild) { - el.removeChild(el.lastChild); - } - } else { - dynamicContentUpdater( - this.$.groupedControlDetails, - "MORE-INFO-" + groupDomain.toUpperCase(), - { stateObj: groupDomainStateObj, hass: this.hass } - ); - } - } -} - -customElements.define("more-info-group", MoreInfoGroup); diff --git a/src/dialogs/more-info/controls/more-info-group.ts b/src/dialogs/more-info/controls/more-info-group.ts new file mode 100644 index 0000000000..788d1a2f6b --- /dev/null +++ b/src/dialogs/more-info/controls/more-info-group.ts @@ -0,0 +1,111 @@ +import { HassEntity } from "home-assistant-js-websocket"; +import { + LitElement, + property, + CSSResult, + css, + internalProperty, + PropertyValues, +} from "lit-element"; +import { html, TemplateResult } from "lit-html"; +import { dynamicElement } from "../../../common/dom/dynamic-element-directive"; +import { computeStateDomain } from "../../../common/entity/compute_state_domain"; +import "../../../state-summary/state-card-content"; +import { GroupEntity, HomeAssistant } from "../../../types"; +import { + importMoreInfoControl, + domainMoreInfoType, +} from "../state_more_info_control"; + +class MoreInfoGroup extends LitElement { + @property({ attribute: false }) public hass!: HomeAssistant; + + @property() public stateObj?: GroupEntity; + + @internalProperty() private _groupDomainStateObj?: HassEntity; + + @internalProperty() private _moreInfoType?: string; + + protected updated(changedProperties: PropertyValues) { + if ( + !this.hass || + !this.stateObj || + (!changedProperties.has("hass") && !changedProperties.has("stateObj")) + ) { + return; + } + + const states = this.stateObj.attributes.entity_id + .map((entity_id) => this.hass.states[entity_id]) + .filter((state) => state); + + if (!states.length) { + this._groupDomainStateObj = undefined; + this._moreInfoType = undefined; + return; + } + + const baseStateObj = states.find((s) => s.state === "on") || states[0]; + const groupDomain = computeStateDomain(baseStateObj); + + // Groups need to be filtered out or we'll show content of + // first child above the children of the current group + if ( + groupDomain !== "group" && + states.every((state) => groupDomain === computeStateDomain(state)) + ) { + this._groupDomainStateObj = { + ...baseStateObj, + entity_id: this.stateObj.entity_id, + attributes: { ...baseStateObj.attributes }, + }; + const type = domainMoreInfoType(groupDomain); + importMoreInfoControl(type); + this._moreInfoType = type === "hidden" ? undefined : `more-info-${type}`; + } else { + this._groupDomainStateObj = undefined; + this._moreInfoType = undefined; + } + } + + protected render(): TemplateResult { + if (!this.hass || !this.stateObj) { + return html``; + } + return html`${this._moreInfoType + ? dynamicElement(this._moreInfoType, { + hass: this.hass, + stateObj: this._groupDomainStateObj, + }) + : ""} + ${this.stateObj.attributes.entity_id.map((entity_id) => { + const state = this.hass!.states[entity_id]; + if (!state) { + return ""; + } + return html` + + `; + })}`; + } + + static get styles(): CSSResult { + return css` + state-card-content { + display: block; + margin-top: 8px; + } + `; + } +} + +customElements.define("more-info-group", MoreInfoGroup); + +declare global { + interface HTMLElementTagNameMap { + "more-info-group": MoreInfoGroup; + } +} diff --git a/src/dialogs/more-info/state_more_info_control.ts b/src/dialogs/more-info/state_more_info_control.ts index c2b97d9c59..6f8cf904ab 100644 --- a/src/dialogs/more-info/state_more_info_control.ts +++ b/src/dialogs/more-info/state_more_info_control.ts @@ -32,6 +32,10 @@ const LAZY_LOADED_MORE_INFO_CONTROL = { export const stateMoreInfoType = (stateObj: HassEntity): string => { const domain = computeStateDomain(stateObj); + return domainMoreInfoType(domain); +}; + +export const domainMoreInfoType = (domain: string): string => { if (DOMAINS_WITH_MORE_INFO.includes(domain)) { return domain; }