home-automation-home-assistant/www/lovelace/custom/auto-entities/auto-entities.js

195 lines
46 KiB
JavaScript
Raw Normal View History

function t(t,e,i,n){var s,o=arguments.length,r=o<3?e:null===n?n=Object.getOwnPropertyDescriptor(e,i):n;if("object"==typeof Reflect&&"function"==typeof Reflect.decorate)r=Reflect.decorate(t,e,i,n);else for(var a=t.length-1;a>=0;a--)(s=t[a])&&(r=(o<3?s(r):o>3?s(e,i,r):s(e,i))||r);return o>3&&r&&Object.defineProperty(e,i,r),r}const e="undefined"!=typeof window&&null!=window.customElements&&void 0!==window.customElements.polyfillWrapFlushCallback,i=(t,e,i=null)=>{for(;e!==i;){const i=e.nextSibling;t.removeChild(e),e=i}},n=`{{lit-${String(Math.random()).slice(2)}}}`,s=`\x3c!--${n}--\x3e`,o=new RegExp(`${n}|${s}`);class r{constructor(t,e){this.parts=[],this.element=e;const i=[],s=[],r=document.createTreeWalker(e.content,133,null,!1);let c=0,h=-1,u=0;const{strings:p,values:{length:f}}=t;for(;u<f;){const t=r.nextNode();if(null!==t){if(h++,1===t.nodeType){if(t.hasAttributes()){const e=t.attributes,{length:i}=e;let n=0;for(let t=0;t<i;t++)a(e[t].name,"$lit$")&&n++;for(;n-- >0;){const e=p[u],i=d.exec(e)[2],n=i.toLowerCase()+"$lit$",s=t.getAttribute(n);t.removeAttribute(n);const r=s.split(o);this.parts.push({type:"attribute",index:h,name:i,strings:r}),u+=r.length-1}}"TEMPLATE"===t.tagName&&(s.push(t),r.currentNode=t.content)}else if(3===t.nodeType){const e=t.data;if(e.indexOf(n)>=0){const n=t.parentNode,s=e.split(o),r=s.length-1;for(let e=0;e<r;e++){let i,o=s[e];if(""===o)i=l();else{const t=d.exec(o);null!==t&&a(t[2],"$lit$")&&(o=o.slice(0,t.index)+t[1]+t[2].slice(0,-"$lit$".length)+t[3]),i=document.createTextNode(o)}n.insertBefore(i,t),this.parts.push({type:"node",index:++h})}""===s[r]?(n.insertBefore(l(),t),i.push(t)):t.data=s[r],u+=r}}else if(8===t.nodeType)if(t.data===n){const e=t.parentNode;null!==t.previousSibling&&h!==c||(h++,e.insertBefore(l(),t)),c=h,this.parts.push({type:"node",index:h}),null===t.nextSibling?t.data="":(i.push(t),h--),u++}else{let e=-1;for(;-1!==(e=t.data.indexOf(n,e+1));)this.parts.push({type:"node",index:-1}),u++}}else r.currentNode=s.pop()}for(const t of i)t.parentNode.removeChild(t)}}const a=(t,e)=>{const i=t.length-e.length;return i>=0&&t.slice(i)===e},c=t=>-1!==t.index,l=()=>document.createComment(""),d=/([ \x09\x0a\x0c\x0d])([^\0-\x1F\x7F-\x9F "'>=/]+)([ \x09\x0a\x0c\x0d]*=[ \x09\x0a\x0c\x0d]*(?:[^ \x09\x0a\x0c\x0d"'`<>=]*|"[^"]*|'[^']*))$/;function h(t,e){const{element:{content:i},parts:n}=t,s=document.createTreeWalker(i,133,null,!1);let o=p(n),r=n[o],a=-1,c=0;const l=[];let d=null;for(;s.nextNode();){a++;const t=s.currentNode;for(t.previousSibling===d&&(d=null),e.has(t)&&(l.push(t),null===d&&(d=t)),null!==d&&c++;void 0!==r&&r.index===a;)r.index=null!==d?-1:r.index-c,o=p(n,o),r=n[o]}l.forEach((t=>t.parentNode.removeChild(t)))}const u=t=>{let e=11===t.nodeType?0:1;const i=document.createTreeWalker(t,133,null,!1);for(;i.nextNode();)e++;return e},p=(t,e=-1)=>{for(let i=e+1;i<t.length;i++){const e=t[i];if(c(e))return i}return-1};const f=new WeakMap,g=t=>"function"==typeof t&&f.has(t),_={},m={};class v{constructor(t,e,i){this.__parts=[],this.template=t,this.processor=e,this.options=i}update(t){let e=0;for(const i of this.__parts)void 0!==i&&i.setValue(t[e]),e++;for(const t of this.__parts)void 0!==t&&t.commit()}_clone(){const t=e?this.template.element.content.cloneNode(!0):document.importNode(this.template.element.content,!0),i=[],n=this.template.parts,s=document.createTreeWalker(t,133,null,!1);let o,r=0,a=0,l=s.nextNode();for(;r<n.length;)if(o=n[r],c(o)){for(;a<o.index;)a++,"TEMPLATE"===l.nodeName&&(i.push(l),s.currentNode=l.content),null===(l=s.nextNode())&&(s.currentNode=i.pop(),l=s.nextNode());if("node"===o.type){const t=this.processor.handleTextExpression(this.options);t.insertAfterNode(l.previousSibling),this.__parts.push(t)}else this.__parts.push(...this.processor.handleAttributeExpressions(l,o.name,o.strings,this.options));r++}else this.__parts.push(void 0),r++;return e&&(document.adoptNode(t),customElements.upgrade(t)),t}}const y=window.trustedTypes&&trustedTypes.createPolicy("lit-html",{createHTML:t=>t}),w=` ${n} `;class b{constructor(t,e,i,n){this.strings=t,this.values=e,this.type=i,this.proc
<div class="card-config">
<div class="toolbar">
<mwc-tab-bar
.activeIndex=${this._selectedTab}
@MDCTabBar:activated=${this._handleSwitchTab}
>
<mwc-tab .label=${"Filters"}></mwc-tab>
<mwc-tab .label=${"Sorting"}></mwc-tab>
<mwc-tab .label=${"Card"}></mwc-tab>
</mwc-tab-bar>
</div>
<div id="editor">
${[this._renderFilterEditor,this._renderSortEditor,this._renderCardEditor][this._selectedTab].bind(this)()}
</div>
</div>
`:V``}_renderFilterEditor(){return V`
${this._config.filter.include.map(((t,e)=>V`
<div class="filter">
<div class="toolbar">
<mwc-icon-button
.disabled=${0===e}
@click=${()=>this._moveFilterGroup(e,-1)}
>
<ha-icon .icon=${"mdi:arrow-up"}></ha-icon>
</mwc-icon-button>
<mwc-icon-button
.disabled=${e===this._config.filter.include.length-1}
@click=${()=>this._moveFilterGroup(e,1)}
>
<ha-icon .icon=${"mdi:arrow-down"}></ha-icon>
</mwc-icon-button>
<mwc-icon-button
@click=${()=>this._deleteFilterGroup(e)}
>
<ha-icon .icon=${"mdi:close"}></ha-icon>
</mwc-icon-button>
</div>
${void 0===t.type?V`
${Object.entries(t).map((([t,i],n)=>V`
${Ot.includes(t)?V`
<div class="option">
<paper-dropdown-menu>
<paper-listbox
.selected=${Ot.indexOf(t)}
slot="dropdown-content"
@selected-item-changed=${i=>this._changeFilterKey(e,t,i)}
>
${Ot.map((t=>V` <paper-item>${t}</paper-item> `))}
</paper-listbox>
</paper-dropdown-menu>
<paper-input
.value=${i}
@change=${i=>this._changeFilterValue(e,t,i)}
>
<mwc-icon-button
slot="suffix"
@click=${()=>this._removeFilter(e,t)}
>
<ha-icon .icon=${"mdi:close"}></ha-icon>
</mwc-icon-button>
</paper-input>
</div>
`:"options"===t?V``:V`<p><b>Some filters are not shown</b></p>
<p>
Please switch to the CODE EDITOR to access all
options.
</p>`}
`))}
<mwc-button @click=${()=>this._addFilter(e)}>
<ha-icon .icon=${"mdi:plus"}></ha-icon>Add filter
</mwc-button>
<ha-yaml-editor
.label=${"Options"}
.defaultValue=${this._config.filter.include[e].options}
.group=${e}
@value-changed=${t=>this._changeGroupOptions(e,t)}
></ha-yaml-editor>
`:V`<ha-yaml-editor
.defaultValue=${this._config.filter.include[e]}
.group=${e}
@value-changed=${t=>this._changeSpecialEntry(e,t)}
></ha-yaml-editor>`}
</div>
`))}
<mwc-button @click=${this._addFilterGroup}>
<ha-icon .icon=${"mdi:plus"}></ha-icon>Add filter group
</mwc-button>
<mwc-button @click=${this._addSpecialEntry}>
<ha-icon .icon=${"mdi:plus"}></ha-icon>Add non-filter entry
</mwc-button>
`}_renderSortEditor(){var t,e,i,n;return V`
<div class="sort">
${(null===(t=this._config.sort)||void 0===t?void 0:t.method)&&!$t.includes(this._config.sort.method)?V`<p>
<b>Your sort method is not handled by the GUI editor.</b>
</p>
<p>Please switch to the CODE EDITOR to access all options.</p>`:V`
Method:
<paper-dropdown-menu>
<paper-listbox
.selected=${$t.includes(null===(e=this._config.sort)||void 0===e?void 0:e.method)?$t.indexOf(null===(i=this._config.sort)||void 0===i?void 0:i.method):0}
slot="dropdown-content"
@selected-item-changed=${this._changeSortMethod}
>
${$t.map((t=>V` <paper-item>${t}</paper-item> `))}
</paper-listbox>
</paper-dropdown-menu>
<ha-formfield .label=${"Reverse"}>
<ha-switch
.checked=${!0===(null===(n=this._config.sort)||void 0===n?void 0:n.reverse)}
@change=${t=>this._sortOptionToggle("reverse",t)}
></ha-switch>
<ha-formfield> </ha-formfield
></ha-formfield>
`}
</div>
`}_renderCardEditor(){var t;return V`
<div class="card">
<ha-formfield .label=${"Display when empty"}>
<ha-switch
.checked=${!1!==this._config.show_empty}
@change=${this._showEmptyToggle}
></ha-switch>
</ha-formfield>
<paper-input
.label=${"Card parameter"}
.value=${null!==(t=this._config.card_param)&&void 0!==t?t:""}
@change=${this._changeCardParam}
>
</paper-input>
${this._config.card?V`
<div class="card-options">
<mwc-button
@click=${this._toggleCardMode}
.disabled=${!this._cardGUIModeAvailable}
class="gui-mode-button"
>
${!this._cardEditorEl||this._cardGUIMode?"Show code editor":"Show Visual Editor"}
</mwc-button>
<mwc-icon-button
.title=${"Delete card"}
@click=${this._deleteCard}
>
<ha-icon .icon=${"mdi:delete"}></ha-icon>
</mwc-icon-button>
</div>
<hui-card-element-editor
.hass=${this.hass}
.lovelace=${this.lovelace}
.value=${this._getCardConfig()}
@config-changed=${this._handleCardConfigChanged}
@GUImode-changed=${this._cardGUIModeChanged}
></hui-card-element-editor>
`:V`
<hui-card-picker
.hass=${this.hass}
.lovelace=${this.lovelace}
@config-changed=${this._handleCardPicked}
></hui-card-picker>
`}
</div>
`}static get styles(){return[it`
mwc-tab-bar {
border-bottom: 1px solid var(--divider-color);
}
.filter,
.card {
margin-top: 8px;
border: 1px solid var(--divider-color);
padding: 12px;
}
.filter .option {
display: flex;
align-items: flex-end;
}
.filter .option paper-dropdown-menu {
margin-right: 16px;
width: 150px;
}
.filter .option paper-input {
flex-grow: 2;
}
.filter .toolbar,
.card .card-options {
display: flex;
justify-content: flex-end;
width: 100%;
}
.gui-mode-button {
margin-right: auto;
}
`]}}function Tt(t,e){if(t===e)return!0;if(typeof t!=typeof e)return!1;if(!(t instanceof Object&&e instanceof Object))return!1;for(const i in t)if(t.hasOwnProperty(i)){if(!e.hasOwnProperty(i))return!1;if(t[i]!==e[i]){if("object"!=typeof t[i])return!1;if(!Tt(t[i],e[i]))return!1}}for(const i in e)if(e.hasOwnProperty(i)&&!t.hasOwnProperty(i))return!1;return!0}t([Y()],Nt.prototype,"_config",void 0),t([K()],Nt.prototype,"lovelace",void 0),t([K()],Nt.prototype,"hass",void 0),t([Y()],Nt.prototype,"_selectedTab",void 0),t([Y()],Nt.prototype,"_cardGUIMode",void 0),t([Y()],Nt.prototype,"_cardGUIModeAvailable",void 0),t([function(t,e){return(i,n)=>{const s={get(){return this.renderRoot.querySelector(t)},enumerable:!0,configurable:!0};if(e){const e="symbol"==typeof n?Symbol():`__${n}`;s.get=function(){return void 0===this[e]&&(this[e]=this.renderRoot.querySelector(t)),this[e]}}return void 0!==n?Q(s,i,n):X(s,i)}}("hui-card-element-editor")],Nt.prototype,"_cardEditorEl",void 0),customElements.define("auto-entities-editor",Nt),window.customCards=window.customCards||[],window.customCards.push({type:"auto-entities",name:"Auto Entities",preview:!1,description:"Entity Filter on Steroids. Auto Entities allows you to fill other cards with entities automatically, based on a number of attributes."});class kt extends st{constructor(){super(...arguments),this._updateCooldown={timer:void 0,rerun:!1},this._renderer=t=>{this._template="string"==typeof t?t.split(/[\s,]+/):t}}static getConfigElement(){return document.createElement("auto-entities-editor")}static getStubConfig(){return{card:{type:"entities"},filter:{include:[],exclude:[]}}}setConfig(t){var e,i;if(!t)throw new Error("No configuration.");if(!(null===(e=t.card)||void 0===e?void 0:e.type))throw new Error("No card type specified.");if(!t.filter&&!t.entities)throw new Error("No filters specified.");t=JSON.parse(JSON.stringify(t)),this._config=t,(null===(i=this._config.filter)||void 0===i?void 0:i.template)&&ht(this._config.filter.template)&&pt(this._renderer,this._config.filter.template,{config:t}),this._cardBuilt=new Promise((t=>this._cardBuiltResolve=t)),queueMicrotask((()=>this.update_all()))}connectedCallback(){var t,e;super.connectedCallback(),(null===(e=null===(t=this._config)||void 0===t?void 0:t.filter)||void 0===e?void 0:e.template)&&ht(this._config.filter.template)&&pt(this._renderer,this._config.filter.template,{config:this._config})}disconnectedCallback(){super.disconnectedCallback(),ft(this._renderer)}async update_all(){if(this.card&&(this.card.hass=this.hass),this._updateCooldown.timer)return void(this._updateCooldown.rerun=!0);this._updateCooldown.rerun=!1,this._updateCooldown.timer=window.setTimeout((()=>{this._updateCooldown.timer=void 0,this._updateCooldown.rerun&&this.update_all()}),500);const t=await this.update_entities();this.update_card(t)}async update_card(t){var e,i;if(this._entities&&Tt(t,this._entities)&&Tt(this._cardConfig,this._config.card))return;const n=(null===(e=this._cardConfig)||void 0===e?void 0:e.type)!==this._config.card.type;this._entities=t,this._cardConfig=JSON.parse(JSON.stringify(this._config.card));const s=Object.assign({[this._config.card_param||"entities"]:t},this._config.card);if(!this.card||n){const t=await window.loadCardHelpers();this.card=await t.createCardElement(s)}else this.card.setConfig(s);null===(i=this._cardBuiltResolve)||void 0===i||i.call(this),this.card.hass=this.hass;const o=0===t.length&&!1===this._config.show_empty;this.style.display=o?"none":null,this.style.margin=o?"0":null}async update_entities(){var t,e,i;const n=t=>t?"string"==typeof t?{entity:t.trim()}:t:null;let s=[...(null===(e=null===(t=this._config)||void 0===t?void 0:t.entities)||void 0===e?void 0:e.map(n))||[]];if(!this.hass||!this._config.filter)return s;if(this._template&&(s=s.concat(this._template.map(n))),s=s.filter(Boolean),this._config.filter.include){const t=Object.keys(this.hass.states).map(n);for(const e of this._config.filter.include){if(e.type){s.push(e);continue}let i=[];for(const n of t)await St(this.hass,e,n.entity)&&i.push(JSON.parse(JSON.stringi