diff --git a/fold-entity-row.js b/fold-entity-row.js index 040a64d..f038f16 100644 --- a/fold-entity-row.js +++ b/fold-entity-row.js @@ -1,11 +1,6 @@ -!function(t){var e={};function i(n){if(e[n])return e[n].exports;var s=e[n]={i:n,l:!1,exports:{}};return t[n].call(s.exports,s,s.exports,i),s.l=!0,s.exports}i.m=t,i.c=e,i.d=function(t,e,n){i.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:n})},i.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},i.t=function(t,e){if(1&e&&(t=i(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var s in t)i.d(n,s,function(e){return t[e]}.bind(null,s));return n},i.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return i.d(e,"a",e),e},i.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},i.p="",i(i.s=0)}([function(t,e,i){"use strict";i.r(e);const n=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),s=n.prototype.html,o=n.prototype.css;function r(){return document.querySelector("home-assistant").hass}const a="custom:",c=["input_number","input_select","input_text","scene","weblink"];function l(t,e){const i=document.createElement("hui-error-card");return i.setConfig({type:"error",error:t,config:e}),i}function h(t,e){if(!e||"object"!=typeof e||!e.type)return l(`No ${t} type configured`,e);let i=e.type;if(i=i.startsWith(a)?i.substr(a.length):`hui-${i}-${t}`,customElements.get(i))return function(t,e){const i=document.createElement(t);try{i.setConfig(e)}catch(t){return l(t,e)}return i}(i,e);const n=l(`Custom element doesn't exist: ${i}.`,e);n.style.display="None";const s=setTimeout(()=>{n.style.display=""},2e3);return customElements.whenDefined(i).then(()=>{clearTimeout(s),function(t,e,i=null){if((t=new Event(t,{bubbles:!0,cancelable:!1,composed:!0})).detail=e||{},i)i.dispatchEvent(t);else{var n=document.querySelector("home-assistant");(n=(n=(n=(n=(n=(n=(n=(n=(n=(n=(n=n&&n.shadowRoot)&&n.querySelector("home-assistant-main"))&&n.shadowRoot)&&n.querySelector("app-drawer-layout partial-panel-resolver"))&&n.shadowRoot||n)&&n.querySelector("ha-panel-lovelace"))&&n.shadowRoot)&&n.querySelector("hui-root"))&&n.shadowRoot)&&n.querySelector("ha-app-layout #view"))&&n.firstElementChild)&&n.dispatchEvent(t)}}("ll-rebuild",{},n)}),n}class u extends n{static get properties(){return{hass:{},config:{},noHass:{type:Boolean}}}setConfig(t){var e;this._config=t,this.el?this.el.setConfig(t):this.el=this.create(t),this._hass&&(this.el.hass=this._hass),this.noHass&&(e=this,document.querySelector("home-assistant").provideHass(e))}set config(t){this.setConfig(t)}set hass(t){this._hass=t,this.el&&(this.el.hass=t)}createRenderRoot(){return this}render(){return s`${this.el}`}}if(!customElements.get("card-maker")){class t extends u{create(t){return function(t){return h("card",t)}(t)}getCardSize(){return this.firstElementChild&&this.firstElementChild.getCardSize?this.firstElementChild.getCardSize():1}}customElements.define("card-maker",t)}if(!customElements.get("element-maker")){class t extends u{create(t){return function(t){return h("element",t)}(t)}}customElements.define("element-maker",t)}if(!customElements.get("entity-row-maker")){class t extends u{create(t){return function(t){const e=new Set(["call-service","divider","section","weblink"]);if(!t)return l("Invalid configuration given.",t);if("string"==typeof t&&(t={entity:t}),"object"!=typeof t||!t.entity&&!t.type)return l("Invalid configuration given.",t);const i=t.type||"default";if(e.has(i)||i.startsWith(a))return h("row",t);const n=t.entity.split(".",1)[0];return Object.assign(t,{type:{alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"}[n]||"text"}),h("entity-row",t)}(t)}}customElements.define("entity-row-maker",t)}customElements.define("fold-entity-row",class extends n{static get properties(){return{_hass:{},open:Boolean,items:{}}}setConfig(t){this._config=Object.assign({},{open:!1,padding:20,group_config:{}},t),this.open=this.open||this._config.open,this.head=this._config.head,this._config.entity&&(this.head=this._config.entity),"string"==typeof this.head&&(this.head={entity:this.head}),this.items=this._config.items,this._config.entities&&(this.items=this._config.entities),this.head.entity&&this.head.entity.startsWith("group.")&&!this.items&&(this.items=r().states[this.head.entity].attributes.entity_id)}clickRow(t){t.stopPropagation();const e=t.target.parentElement._config;this.hasMoreInfo(e)||e.tap_action?customElements.get("hui-entities-card").prototype._handleClick.bind(this)(e):t.target.parentElement.hasAttribute("head")&&this.toggle(t)}toggle(t){t&&t.stopPropagation(),this.open=!this.open}hasMoreInfo(t){const e=t.entity||("string"==typeof t?t:null);return!(!e||c.includes(e.split(".",1)[0]))}firstUpdated(){const t=this.shadowRoot.querySelector("#head > entity-row-maker");t.updateComplete.then(()=>{const e=t.querySelector("hui-section-row");e&&e.updateComplete.then(()=>{e.shadowRoot.querySelector(".divider").style.marginRight="-56px"})})}set hass(t){this._hass=t}render(){this._entities&&this._entities.forEach(t=>t.hass=this._hass);const t=t=>("string"==typeof t&&(t={entity:t}),Object.assign({},this._config.group_config,t));return s` +!function(t){var e={};function n(i){if(e[i])return e[i].exports;var o=e[i]={i:i,l:!1,exports:{}};return t[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=t,n.c=e,n.d=function(t,e,i){n.o(t,e)||Object.defineProperty(t,e,{enumerable:!0,get:i})},n.r=function(t){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(t,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(t,"__esModule",{value:!0})},n.t=function(t,e){if(1&e&&(t=n(t)),8&e)return t;if(4&e&&"object"==typeof t&&t&&t.__esModule)return t;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:t}),2&e&&"string"!=typeof t)for(var o in t)n.d(i,o,function(e){return t[e]}.bind(null,o));return i},n.n=function(t){var e=t&&t.__esModule?function(){return t.default}:function(){return t};return n.d(e,"a",e),e},n.o=function(t,e){return Object.prototype.hasOwnProperty.call(t,e)},n.p="",n(n.s=0)}([function(t,e,n){"use strict";n.r(e);const i=customElements.get("home-assistant-main")?Object.getPrototypeOf(customElements.get("home-assistant-main")):Object.getPrototypeOf(customElements.get("hui-view")),o=i.prototype.html,r=i.prototype.css;function s(){return document.querySelector("home-assistant").hass}const a="custom:",c=["input_number","input_select","input_text","scene","weblink"];function l(t,e){const n=document.createElement("hui-error-card");return n.setConfig({type:"error",error:t,config:e}),n}function u(t,e){if(!e||"object"!=typeof e||!e.type)return l(`No ${t} type configured`,e);let n=e.type;if(n=n.startsWith(a)?n.substr(a.length):`hui-${n}-${t}`,customElements.get(n))return function(t,e){const n=document.createElement(t);try{n.setConfig(e)}catch(t){return l(t,e)}return n}(n,e);const i=l(`Custom element doesn't exist: ${n}.`,e);i.style.display="None";const o=setTimeout(()=>{i.style.display=""},2e3);return customElements.whenDefined(n).then(()=>{clearTimeout(o),function(t,e,n=null){if((t=new Event(t,{bubbles:!0,cancelable:!1,composed:!0})).detail=e||{},n)n.dispatchEvent(t);else{var i=document.querySelector("home-assistant");(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=(i=i&&i.shadowRoot)&&i.querySelector("home-assistant-main"))&&i.shadowRoot)&&i.querySelector("app-drawer-layout partial-panel-resolver"))&&i.shadowRoot||i)&&i.querySelector("ha-panel-lovelace"))&&i.shadowRoot)&&i.querySelector("hui-root"))&&i.shadowRoot)&&i.querySelector("ha-app-layout #view"))&&i.firstElementChild)&&i.dispatchEvent(t)}}("ll-rebuild",{},i)}),i}function d(t){const e=new Set(["call-service","divider","section","weblink"]);if(!t)return l("Invalid configuration given.",t);if("string"==typeof t&&(t={entity:t}),"object"!=typeof t||!t.entity&&!t.type)return l("Invalid configuration given.",t);const n=t.type||"default";if(e.has(n)||n.startsWith(a))return u("row",t);const i=t.entity.split(".",1)[0];return Object.assign(t,{type:{alert:"toggle",automation:"toggle",climate:"climate",cover:"cover",fan:"toggle",group:"group",input_boolean:"toggle",input_number:"input-number",input_select:"input-select",input_text:"input-text",light:"toggle",lock:"lock",media_player:"media-player",remote:"toggle",scene:"scene",script:"script",sensor:"sensor",timer:"timer",switch:"toggle",vacuum:"toggle",water_heater:"climate",input_datetime:"input-datetime"}[i]||"text"}),u("entity-row",t)}customElements.define("fold-entity-row",class extends i{static get properties(){return{open:Boolean,items:{}}}setConfig(t){this._config=Object.assign({},{open:!1,padding:20,group_config:{}},t),this.open=this.open||this._config.open;let e=this._config.head;this._config.entity&&(e=this._config.entity),"string"==typeof e&&(e={entity:e});let n=this._config.items;this._config.entities&&(n=this._config.entities),e.entity&&e.entity.startsWith("group.")&&!n&&(n=s().states[e.entity].attributes.entity_id);const i=t=>("string"==typeof t&&(t={entity:t}),Object.assign({},this._config.group_config,t));this.head=d(e),this.head.hass=s(),this.head.addEventListener("click",t=>{this.hasMoreInfo(e)||e.tap_action||this.toggle(t)}),this.head.setAttribute("head","head"),this.rows=n.map(t=>{const e=d(i(t));return e.hass=s(),this.hasMoreInfo(t)&&e.classList.add("state-card-dialog"),e})}toggle(t){t&&t.stopPropagation(),this.open=!this.open}hasMoreInfo(t){const e=t.entity||("string"==typeof t?t:null);return!(!e||c.includes(e.split(".",1)[0]))}firstUpdated(){const t=this.head;t.updateComplete.then(()=>{const e=t.querySelector("hui-section-row");e&&e.updateComplete.then(()=>{e.shadowRoot.querySelector(".divider").style.marginRight="-56px"})})}set hass(t){this.rows.forEach(e=>e.hass=t),this.head.hass=t}render(){return o` - `}static get styles(){return o` + `}static get styles(){return r` #head { --toggle-icon-width: 40px; display: flex; cursor: pointer; align-items: center; } - #head entity-row-maker { + #head :not(ha-icon) { flex-grow: 1; max-width: calc(100% - var(--toggle-icon-width)); } diff --git a/src/main.js b/src/main.js index 9288316..3792346 100644 --- a/src/main.js +++ b/src/main.js @@ -1,12 +1,10 @@ import { LitElement, html, css } from "card-tools/src/lit-element.js"; import { hass } from "card-tools/src/hass.js"; -import "card-tools/src/card-maker.js"; -import { DOMAINS_HIDE_MORE_INFO } from "card-tools/src/lovelace-element.js"; +import { DOMAINS_HIDE_MORE_INFO, createEntityRow } from "card-tools/src/lovelace-element.js"; class FoldEntityRow extends LitElement { static get properties() { return { - _hass: {}, open: Boolean, items: {}, }; @@ -22,33 +20,43 @@ class FoldEntityRow extends LitElement { this._config = Object.assign({}, defaults, config); this.open = this.open || this._config.open; - this.head = this._config.head; + let head = this._config.head; if (this._config.entity) - this.head = this._config.entity; - if (typeof this.head === "string") - this.head = {entity: this.head}; + head = this._config.entity; + if (typeof head === "string") + head = {entity: head}; // Items are taken from the first available of the following // - The group specified as head // - config entities: (this allows auto-population of the list) // - config items: (for backwards compatibility - not recommended) - this.items = this._config.items; + let items = this._config.items; if (this._config.entities) - this.items = this._config.entities; - if (this.head.entity && this.head.entity.startsWith("group.") && !this.items) - this.items = hass().states[this.head.entity].attributes.entity_id; - } + items = this._config.entities; + if (head.entity && head.entity.startsWith("group.") && !items) + items = hass().states[head.entity].attributes.entity_id; - clickRow(ev) { - ev.stopPropagation(); - - const config = ev.target.parentElement._config; - - if(this.hasMoreInfo(config) || config.tap_action) { - customElements.get('hui-entities-card').prototype._handleClick.bind(this)(config); - } else if(ev.target.parentElement.hasAttribute('head')) { - this.toggle(ev); + const fix_config = (config) => { + if(typeof config === "string") + config = {entity: config}; + return Object.assign({}, this._config.group_config, config); } + + this.head = createEntityRow(head); + this.head.hass = hass(); + this.head.addEventListener("click", (ev) => { + if(!this.hasMoreInfo(head) && !head.tap_action) + this.toggle(ev); + }); + this.head.setAttribute('head', 'head'); + + this.rows = items.map((i) => { + const row = createEntityRow(fix_config(i)); + row.hass = hass(); + if(this.hasMoreInfo(i)) + row.classList.add("state-card-dialog"); + return row; + }); } toggle(ev) { @@ -66,7 +74,7 @@ class FoldEntityRow extends LitElement { firstUpdated() { // If the header is a section-row, adjust the divider line a bit to look better - const headRow = this.shadowRoot.querySelector("#head > entity-row-maker"); + const headRow = this.head; headRow.updateComplete.then(() => { const element = headRow.querySelector("hui-section-row"); if(element) { @@ -78,27 +86,14 @@ class FoldEntityRow extends LitElement { } set hass(hass) { - this._hass = hass; + this.rows.forEach((e) => e.hass = hass); + this.head.hass = hass; } render() { - if (this._entities) - this._entities.forEach((e) => e.hass = this._hass); - - const fix_config = (config) => { - if(typeof config === "string") - config = {entity: config}; - return Object.assign({}, this._config.group_config, config); - } - return html` `; } @@ -133,7 +121,7 @@ class FoldEntityRow extends LitElement { cursor: pointer; align-items: center; } - #head entity-row-maker { + #head :not(ha-icon) { flex-grow: 1; max-width: calc(100% - var(--toggle-icon-width)); }