diff --git a/fold-entity-row.js b/fold-entity-row.js
index 8c3cd81..d7b1a99 100644
--- a/fold-entity-row.js
+++ b/fold-entity-row.js
@@ -1,39 +1,46 @@
-!function(e){var t={};function i(n){if(t[n])return t[n].exports;var o=t[n]={i:n,l:!1,exports:{}};return e[n].call(o.exports,o,o.exports,i),o.l=!0,o.exports}i.m=e,i.c=t,i.d=function(e,t,n){i.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:n})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,t){if(1&t&&(e=i(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var n=Object.create(null);if(i.r(n),Object.defineProperty(n,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)i.d(n,o,function(t){return e[t]}.bind(null,o));return n},i.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(t,"a",t),t},i.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},i.p="",i(i.s=0)}([function(e,t,i){"use strict";i.r(t);const n=Object.getPrototypeOf(customElements.get("home-assistant-main")),o=n.prototype.html,s=n.prototype.css;function r(e,t,i=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},i)i.dispatchEvent(e);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(e)}}const a="custom:";function c(e,t){const i=document.createElement("hui-error-card");return i.setConfig({type:"error",error:e,config:t}),i}function l(e,t){if(!t||"object"!=typeof t||!t.type)return c(`No ${e} type configured`,t);let i=t.type;if(i=i.startsWith(a)?i.substr(a.length):`hui-${i}-${e}`,customElements.get(i))return function(e,t){const i=document.createElement(e);try{i.setConfig(t)}catch(e){return c(e,t)}return i}(i,t);const n=c(`Custom element doesn't exist: ${i}.`,t);n.style.display="None";const o=setTimeout(()=>{n.style.display=""},2e3);return customElements.whenDefined(i).then(()=>{clearTimeout(o),r("ll-rebuild",{},n)}),n}customElements.define("fold-entity-row",class extends n{static get properties(){return{hass:{},open:Boolean}}setConfig(e){this._config=Object.assign({},{open:!1,padding:20,group_config:{}},e),this.open=this._config.open,this._head=this._renderRow(this._config.head,!0);let t=this._config.items;this._config.entities&&(t=this._config.entities),"string"==typeof this._config.head&&this._config.head.startsWith("group.")&&(t=document.querySelector("home-assistant").hass.states[this._config.head].attributes.entity_id),t&&(this._entities=t.map(e=>this._renderRow(e)))}_renderRow(e,t=!1){e="string"==typeof e?{entity:e}:e,t||(e=Object.assign({},this._config.group_config,e));const i=function(e){const t=new Set(["call-service","divider","section","weblink"]);if(!e||"object"!=typeof e||!e.entity&&!e.type)return c("Invalid configuration given.",e);const i=e.type||"default";if(t.has(i)||i.startsWith(a))return l("row",e);const n=e.entity.split(".",1)[0];return Object.assign(e,{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"}),l("entity-row",e)}(e);return e.entity&&!["input_number","input_select","input_text","input_datetime","scene","weblink"].includes(e.entity.split(".",1)[0])?i.addEventListener("click",()=>{r("hass-more-info",{entityId:e.entity},this)}):t&&(i.addEventListener("click",()=>this.open=!this.open),i.classList.add("fold-toggle")),t&&"section"===e.type&&i.updateComplete.then(()=>{i.shadowRoot.querySelector(".divider").style.marginRight="-56px"}),i}render(){return this._head.hass=this.hass,this._entities&&this._entities.forEach(e=>e.hass=this.hass),o`
-
-
- ${this._head}
-
-
-
{e.stopPropagation(),this.open=!this.open}}"
+!function(e){var t={};function n(i){if(t[i])return t[i].exports;var o=t[i]={i:i,l:!1,exports:{}};return e[i].call(o.exports,o,o.exports,n),o.l=!0,o.exports}n.m=e,n.c=t,n.d=function(e,t,i){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:i})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var i=Object.create(null);if(n.r(i),Object.defineProperty(i,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var o in e)n.d(i,o,function(t){return e[t]}.bind(null,o));return i},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){"use strict";n.r(t);const i=Object.getPrototypeOf(customElements.get("home-assistant-main")),o=i.prototype.html,s=i.prototype.css;function r(e,t,n=null){if((e=new Event(e,{bubbles:!0,cancelable:!1,composed:!0})).detail=t||{},n)n.dispatchEvent(e);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(e)}}const a="custom:",c=["input_number","input_select","input_text","input_datetime","scene","weblink"];function l(e,t){const n=document.createElement("hui-error-card");return n.setConfig({type:"error",error:e,config:t}),n}function u(e,t){if(!t||"object"!=typeof t||!t.type)return l(`No ${e} type configured`,t);let n=t.type;if(n=n.startsWith(a)?n.substr(a.length):`hui-${n}-${e}`,customElements.get(n))return function(e,t){const n=document.createElement(e);try{n.setConfig(t)}catch(e){return l(e,t)}return n}(n,t);const i=l(`Custom element doesn't exist: ${n}.`,t);i.style.display="None";const o=setTimeout(()=>{i.style.display=""},2e3);return customElements.whenDefined(n).then(()=>{clearTimeout(o),r("ll-rebuild",{},i)}),i}class h extends i{static get properties(){return{hass:{},config:{}}}setConfig(e){var t;this._config=e,this.el?this.el.setConfig(e):this.el=this.create(e),this._hass&&(this.el.hass=this._hass),this.noHass&&(t=this,document.queryselector("home-assistant").provideHass(t))}set config(e){this.setConfig(e)}set hass(e){this._hass=e,this.el&&(this.el.hass=e)}createRenderRoot(){return this}render(){return o`${this.el}`}}if(!customElements.get("card-maker")){class e extends h{create(e){return function(e){return u("card",e)}(e)}}customElements.define("card-maker",e)}if(!customElements.get("element-maker")){class e extends h{create(e){return function(e){return u("element",e)}(e)}}customElements.define("element-maker",e)}if(!customElements.get("entity-row-maker")){class e extends h{create(e){return function(e){const t=new Set(["call-service","divider","section","weblink"]);if(!e)return l("Invalid configuration given.",e);if("string"==typeof e&&(e={entity:e}),"object"!=typeof e||!e.entity&&!e.type)return l("Invalid configuration given.",e);const n=e.type||"default";if(t.has(n)||n.startsWith(a))return u("row",e);const i=e.entity.split(".",1)[0];return Object.assign(e,{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",e)}(e)}}customElements.define("entity-row-maker",e)}customElements.define("fold-entity-row",class extends i{static get properties(){return{hass:{},open:Boolean,items:{}}}setConfig(e){this._config=Object.assign({},{open:!1,padding:20,group_config:{}},e),this.open=this.open||this._config.open,this.items=this._config.items,this._config.entities&&(this.items=this._config.entities),"string"==typeof this._config.head&&this._config.head.startsWith("group.")&&(this.items=document.querySelector("home-assistant").hass.states[this._config.head].attributes.entity_id)}clickRow(e){const t=e.target._config,n=t.entity||("string"==typeof t?t:null);e.stopPropagation(),this.hasMoreInfo(t)?function(e){r("hass-more-info",{entityId:e},document.querySelector("home-assistant"))}(n):e.target.parentElement.hasAttribute("head")&&this.toggle(e)}toggle(e){e&&e.stopPropagation(),this.open=!this.open}hasMoreInfo(e){const t=e.entity||("string"==typeof e?e:null);return!(!t||c.includes(t.split(".",1)[0]))}firstUpdated(){const e=this.shadowRoot.querySelector("#head > entity-row-maker");e.updateComplete.then(()=>{const t=e.querySelector("hui-section-row");t&&t.updateComplete.then(()=>{t.shadowRoot.querySelector(".divider").style.marginRight="-56px"})})}render(){this._entities&&this._entities.forEach(e=>e.hass=this.hass);const e=e=>("string"==typeof e&&(e={entity:e}),Object.assign({},this._config.group_config,e));return o`
+
+
+
-
-
+ >
+
+
- ${this._entities}
+ ${this.items.map(t=>o`
+
+ `)}
`}static get styles(){return s`
#head {
display: flex;
- }
- #entity {
- flex: 1 1 auto;
- width: 0px;
- }
- #toggle {
- flex 0 1 40px;
- display: flex;
+ cursor: pointer;
align-items: center;
}
+ #head entity-row-maker {
+ flex-grow: 1;
+ }
+ #head ha-icon {
+ width: 40px;
+ cursor: pointer
+ }
+
#items {
padding: 0;
margin: 0;
@@ -44,17 +51,7 @@
overflow: visible;
max-height: none;
}
- ha-icon {
- width: 40px;
- }
.state-card-dialog {
cursor: pointer;
}
- .fold-toggle {
- cursor: s-resize;
- }
- .fold-toggle[open], #head[open] .fold-toggle{
- cursor: n-resize;
- }
-
`}})}]);
\ No newline at end of file
diff --git a/src/main.js b/src/main.js
index 4dd7924..701e35a 100644
--- a/src/main.js
+++ b/src/main.js
@@ -1,13 +1,15 @@
import { LitElement, html, css } from "/card-tools/lit-element.js";
-import { fireEvent } from "/card-tools/event.js";
-import { createEntityRow } from "/card-tools/lovelace-element.js";
+import { moreInfo } from "/card-tools/more-info.js";
import { hass } from "/card-tools/hass.js";
+import "/card-tools/card-maker.js";
+import { DOMAINS_HIDE_MORE_INFO } from "/card-tools/lovelace-element.js";
class FoldEntityRow extends LitElement {
static get properties() {
return {
hass: {},
open: Boolean,
+ items: {},
};
}
@@ -19,86 +21,98 @@ class FoldEntityRow extends LitElement {
};
this._config = Object.assign({}, defaults, config);
- this.open = this._config.open;
+ this.open = this.open || this._config.open;
- this._head = this._renderRow(this._config.head, true);
-
- let items = this._config.items;
+ // 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;
if (this._config.entities)
- items = this._config.entities;
+ this.items = this._config.entities;
if (typeof this._config.head === "string" && this._config.head.startsWith("group."))
- items = hass().states[this._config.head].attributes.entity_id;
- if (items)
- this._entities = items.map((e) => this._renderRow(e));
+ this.items = hass().states[this._config.head].attributes.entity_id;
}
- _renderRow(conf, head=false) {
- conf = (typeof conf === "string") ? {entity: conf} : conf;
+ clickRow(ev) {
+ const config = ev.target._config;
+ const entity = config.entity || (typeof config === "string" ? config : null);
- if (!head) {
- conf = Object.assign({}, this._config.group_config, conf);
+ ev.stopPropagation();
+ if(this.hasMoreInfo(config))
+ moreInfo(entity)
+ else if(ev.target.parentElement.hasAttribute('head')) {
+ this.toggle(ev);
}
+ }
- const DOMAINS_HIDE_MORE_INFO = [
- "input_number",
- "input_select",
- "input_text",
- "input_datetime",
- "scene",
- "weblink",
- ];
+ toggle(ev) {
+ if(ev)
+ ev.stopPropagation();
+ this.open = !this.open;
+ }
- const el = createEntityRow(conf);
- if (conf.entity && !DOMAINS_HIDE_MORE_INFO.includes(conf.entity.split(".",1)[0])) {
- el.addEventListener("click", () => {
- fireEvent("hass-more-info", {entityId: conf.entity}, this);
- });
- } else if (head) {
- el.addEventListener("click", () => this.open = !this.open);
- el.classList.add("fold-toggle");
- }
+ hasMoreInfo(config) {
+ const entity = config.entity || (typeof config === "string" ? config : null);
+ if(entity && !DOMAINS_HIDE_MORE_INFO.includes(entity.split(".",1)[0]))
+ return true;
+ return false;
+ }
- if (head && conf.type === "section")
- el.updateComplete.then(() => {
- const divider = el.shadowRoot.querySelector(".divider");
- divider.style.marginRight = "-56px";
- });
-
- return el;
+ 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");
+ headRow.updateComplete.then(() => {
+ const element = headRow.querySelector("hui-section-row");
+ if(element) {
+ element.updateComplete.then(() => {
+ element.shadowRoot.querySelector(".divider").style.marginRight = "-56px";
+ });
+ }
+ });
}
render() {
- this._head.hass = this.hass;
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`
-
-
- ${this._head}
-
-
-
{
- ev.stopPropagation();
- this.open = !this.open;
- }
- }"
+
+
+
-
-
+ >
+
+
- ${this._entities}
+ ${this.items.map(i => html`
+
+ `)}
`;
}
@@ -107,16 +121,17 @@ class FoldEntityRow extends LitElement {
return css`
#head {
display: flex;
- }
- #entity {
- flex: 1 1 auto;
- width: 0px;
- }
- #toggle {
- flex 0 1 40px;
- display: flex;
+ cursor: pointer;
align-items: center;
}
+ #head entity-row-maker {
+ flex-grow: 1;
+ }
+ #head ha-icon {
+ width: 40px;
+ cursor: pointer
+ }
+
#items {
padding: 0;
margin: 0;
@@ -127,19 +142,9 @@ class FoldEntityRow extends LitElement {
overflow: visible;
max-height: none;
}
- ha-icon {
- width: 40px;
- }
.state-card-dialog {
cursor: pointer;
}
- .fold-toggle {
- cursor: s-resize;
- }
- .fold-toggle[open], #head[open] .fold-toggle{
- cursor: n-resize;
- }
-
`;
}