mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 19:56:42 +00:00
Separate row entity elements for Lovelace (#1461)
* Separate row entity elements for Lovelace * Update * Update * Add fan * Add support for last changed * Feedback * Feedback2 * Update * Update * Fix timer * Update * Lint
This commit is contained in:
parent
9ab4158e0a
commit
8c44e243e1
@ -82,13 +82,12 @@ class StateInfo extends PolymerElement {
|
|||||||
},
|
},
|
||||||
hass: Object,
|
hass: Object,
|
||||||
stateObj: Object,
|
stateObj: Object,
|
||||||
inDialog: Boolean,
|
inDialog: Boolean
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
computeStateName(stateObj) {
|
computeStateName(stateObj) {
|
||||||
return this.overrideName || computeStateName(stateObj);
|
return computeStateName(stateObj);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,20 +2,16 @@ import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
|
|||||||
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
import processConfigEntities from '../common/process-config-entities.js';
|
|
||||||
|
|
||||||
import '../../../components/ha-card.js';
|
import '../../../components/ha-card.js';
|
||||||
import '../components/hui-entities-toggle.js';
|
import '../components/hui-entities-toggle.js';
|
||||||
|
|
||||||
// just importing this now as shortcut to import correct state-card-*
|
import createEntityRowElement from '../common/create-entity-row-element.js';
|
||||||
import '../../../state-summary/state-card-content.js';
|
import processConfigEntities from '../common/process-config-entities.js';
|
||||||
|
import computeDomain from '../../../common/entity/compute_domain.js';
|
||||||
|
import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js';
|
||||||
|
|
||||||
import EventsMixin from '../../../mixins/events-mixin.js';
|
import EventsMixin from '../../../mixins/events-mixin.js';
|
||||||
|
|
||||||
import createEntityRowElement from '../common/create-entity-row-element.js';
|
|
||||||
import { DOMAINS_HIDE_MORE_INFO } from '../../../common/const.js';
|
|
||||||
import computeDomain from '../../../common/entity/compute_domain.js';
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* @appliesMixin EventsMixin
|
* @appliesMixin EventsMixin
|
||||||
*/
|
*/
|
||||||
@ -70,7 +66,7 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|||||||
type: Object,
|
type: Object,
|
||||||
observer: '_hassChanged',
|
observer: '_hassChanged',
|
||||||
},
|
},
|
||||||
_config: Object,
|
_config: Object
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,14 +113,13 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|||||||
|
|
||||||
for (const entity of entities) {
|
for (const entity of entities) {
|
||||||
const entityId = entity.entity;
|
const entityId = entity.entity;
|
||||||
|
const element = createEntityRowElement(entity);
|
||||||
const element = createEntityRowElement(entity, this.hass);
|
|
||||||
if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) {
|
if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) {
|
||||||
element.classList.add('state-card-dialog');
|
element.classList.add('state-card-dialog');
|
||||||
element.addEventListener('click', () => this.fire('hass-more-info', { entityId }));
|
element.addEventListener('click', () => this.fire('hass-more-info', { entityId }));
|
||||||
}
|
}
|
||||||
|
element.hass = this.hass;
|
||||||
this._elements.push({ entityId, element });
|
this._elements.push(element);
|
||||||
const container = document.createElement('div');
|
const container = document.createElement('div');
|
||||||
container.appendChild(element);
|
container.appendChild(element);
|
||||||
root.appendChild(container);
|
root.appendChild(container);
|
||||||
@ -132,12 +127,9 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_hassChanged(hass) {
|
_hassChanged(hass) {
|
||||||
for (let i = 0; i < this._elements.length; i++) {
|
this._elements.forEach((element) => {
|
||||||
const { entityId, element } = this._elements[i];
|
|
||||||
const stateObj = hass.states[entityId];
|
|
||||||
element.stateObj = stateObj;
|
|
||||||
element.hass = hass;
|
element.hass = hass;
|
||||||
}
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,12 +1,36 @@
|
|||||||
import fireEvent from '../../../common/dom/fire_event.js';
|
import fireEvent from '../../../common/dom/fire_event.js';
|
||||||
|
|
||||||
import stateCardType from '../../../common/entity/state_card_type.js';
|
import '../entity-rows/hui-cover-entity-row.js';
|
||||||
|
import '../entity-rows/hui-input-number-entity-row.js';
|
||||||
|
import '../entity-rows/hui-input-select-entity-row.js';
|
||||||
|
import '../entity-rows/hui-input-text-entity-row.js';
|
||||||
|
import '../entity-rows/hui-lock-entity-row.js';
|
||||||
|
import '../entity-rows/hui-scene-entity-row.js';
|
||||||
|
import '../entity-rows/hui-script-entity-row.js';
|
||||||
|
import '../entity-rows/hui-text-entity-row.js';
|
||||||
|
import '../entity-rows/hui-timer-entity-row.js';
|
||||||
|
import '../entity-rows/hui-toggle-entity-row.js';
|
||||||
|
|
||||||
import createErrorCardConfig from './create-error-card-config.js';
|
import createErrorCardConfig from './create-error-card-config.js';
|
||||||
|
|
||||||
const CUSTOM_TYPE_PREFIX = 'custom:';
|
const CUSTOM_TYPE_PREFIX = 'custom:';
|
||||||
|
const DOMAIN_TO_ELEMENT_TYPE = {
|
||||||
|
cover: 'cover',
|
||||||
|
fan: 'toggle',
|
||||||
|
group: 'toggle',
|
||||||
|
input_boolean: 'toggle',
|
||||||
|
input_number: 'input-number',
|
||||||
|
input_select: 'input-select',
|
||||||
|
input_text: 'input-text',
|
||||||
|
light: 'toggle',
|
||||||
|
lock: 'lock',
|
||||||
|
scene: 'scene',
|
||||||
|
script: 'script',
|
||||||
|
timer: 'timer',
|
||||||
|
switch: 'toggle'
|
||||||
|
};
|
||||||
|
|
||||||
function _createElement(tag, config, stateObj, hass) {
|
function _createElement(tag, config) {
|
||||||
const element = document.createElement(tag);
|
const element = document.createElement(tag);
|
||||||
try {
|
try {
|
||||||
if ('setConfig' in element) element.setConfig(config);
|
if ('setConfig' in element) element.setConfig(config);
|
||||||
@ -17,12 +41,6 @@ function _createElement(tag, config, stateObj, hass) {
|
|||||||
return _createErrorElement(err.message, config);
|
return _createErrorElement(err.message, config);
|
||||||
}
|
}
|
||||||
|
|
||||||
element.stateObj = stateObj;
|
|
||||||
element.hass = hass;
|
|
||||||
if (config.name) {
|
|
||||||
element.overrideName = config.name;
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,25 +48,19 @@ function _createErrorElement(error, config) {
|
|||||||
return _createElement('hui-error-card', createErrorCardConfig(error, config));
|
return _createElement('hui-error-card', createErrorCardConfig(error, config));
|
||||||
}
|
}
|
||||||
|
|
||||||
export default function createEntityRowElement(config, hass) {
|
export default function createEntityRowElement(config) {
|
||||||
let tag;
|
let tag;
|
||||||
|
|
||||||
if (!config || typeof config !== 'object') {
|
if (!config || typeof config !== 'object' || !config.entity) {
|
||||||
return _createErrorElement('Invalid config given.', config);
|
return _createErrorElement('Invalid config given.', config);
|
||||||
}
|
}
|
||||||
|
|
||||||
const entityId = config.entity;
|
|
||||||
if (!(entityId in hass.states)) {
|
|
||||||
return _createErrorElement('Entity not found.', config);
|
|
||||||
}
|
|
||||||
|
|
||||||
const type = config.type || 'default';
|
const type = config.type || 'default';
|
||||||
const stateObj = hass.states[entityId];
|
|
||||||
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
|
||||||
tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
tag = type.substr(CUSTOM_TYPE_PREFIX.length);
|
||||||
|
|
||||||
if (customElements.get(tag)) {
|
if (customElements.get(tag)) {
|
||||||
return _createElement(tag, config, stateObj, hass);
|
return _createElement(tag, config);
|
||||||
}
|
}
|
||||||
const element = _createErrorElement(`Custom element doesn't exist: ${tag}.`, config);
|
const element = _createErrorElement(`Custom element doesn't exist: ${tag}.`, config);
|
||||||
|
|
||||||
@ -58,7 +70,8 @@ export default function createEntityRowElement(config, hass) {
|
|||||||
return element;
|
return element;
|
||||||
}
|
}
|
||||||
|
|
||||||
tag = stateObj ? `state-card-${stateCardType(hass, stateObj)}` : 'state-card-display';
|
const domain = config.entity.split('.', 1)[0];
|
||||||
|
tag = `hui-${DOMAIN_TO_ELEMENT_TYPE[domain] || 'text'}-entity-row`;
|
||||||
|
|
||||||
return _createElement(tag, config, stateObj, hass);
|
return _createElement(tag, config);
|
||||||
}
|
}
|
||||||
|
92
src/panels/lovelace/components/hui-generic-entity-row.js
Normal file
92
src/panels/lovelace/components/hui-generic-entity-row.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../../../components/entity/state-badge.js';
|
||||||
|
import '../../../components/ha-relative-time.js';
|
||||||
|
|
||||||
|
import computeStateName from '../../../common/entity/compute_state_name.js';
|
||||||
|
|
||||||
|
import EventsMixin from '../../../mixins/events-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin EventsMixin
|
||||||
|
*/
|
||||||
|
class HuiGenericEntityRow extends EventsMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
}
|
||||||
|
.flex {
|
||||||
|
margin-left: 16px;
|
||||||
|
flex: 1;
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
}
|
||||||
|
.secondary,
|
||||||
|
ha-relative-time {
|
||||||
|
display: block;
|
||||||
|
color: var(--secondary-text-color);
|
||||||
|
}
|
||||||
|
.not-found {
|
||||||
|
flex: 1;
|
||||||
|
background-color: yellow;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<template is="dom-if" if="[[_stateObj]]">
|
||||||
|
<state-badge state-obj="[[_stateObj]]"></state-badge>
|
||||||
|
<div class="flex">
|
||||||
|
<div class="info">
|
||||||
|
[[_computeName(config.name, _stateObj)]]
|
||||||
|
<template is="dom-if" if="[[config.secondary_info]]">
|
||||||
|
<template is="dom-if" if="[[_equals(config.secondary_info, 'entity-id')]]">
|
||||||
|
<div class="secondary">
|
||||||
|
[[_stateObj.entity_id]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[_equals(config.secondary_info, 'last-changed')]]">
|
||||||
|
<ha-relative-time
|
||||||
|
hass="[[hass]]"
|
||||||
|
datetime="[[_stateObj.last_changed]]"
|
||||||
|
></ha-relative-time>
|
||||||
|
</template>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
<slot></slot>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[!_stateObj]]">
|
||||||
|
<div class="not-found">
|
||||||
|
Entity not available: [[config.entity]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, config.entity)'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_equals(a, b) {
|
||||||
|
return a === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeName(name, stateObj) {
|
||||||
|
return name || computeStateName(stateObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-generic-entity-row', HuiGenericEntityRow);
|
56
src/panels/lovelace/entity-rows/hui-cover-entity-row.js
Normal file
56
src/panels/lovelace/entity-rows/hui-cover-entity-row.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
import '../../../components/ha-cover-controls.js';
|
||||||
|
import '../../../components/ha-cover-tilt-controls.js';
|
||||||
|
import CoverEntity from '../../../util/cover-model.js';
|
||||||
|
|
||||||
|
class HuiCoverEntityRow extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<template is="dom-if" if="[[!_entityObj.isTiltOnly]]">
|
||||||
|
<ha-cover-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-controls>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[_entityObj.isTiltOnly]]">
|
||||||
|
<ha-cover-tilt-controls hass="[[hass]]" state-obj="[[_stateObj]]"></ha-cover-tilt-controls>
|
||||||
|
</template>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)'
|
||||||
|
},
|
||||||
|
_entityObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeEntityObj(hass, _stateObj)'
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeEntityObj(hass, stateObj) {
|
||||||
|
return stateObj ? new CoverEntity(hass, stateObj) : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-cover-entity-row', HuiCoverEntityRow);
|
147
src/panels/lovelace/entity-rows/hui-input-number-entity-row.js
Normal file
147
src/panels/lovelace/entity-rows/hui-input-number-entity-row.js
Normal file
@ -0,0 +1,147 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-input/paper-input.js';
|
||||||
|
import '@polymer/paper-slider/paper-slider.js';
|
||||||
|
import { IronResizableBehavior } from '@polymer/iron-resizable-behavior/iron-resizable-behavior.js';
|
||||||
|
import { mixinBehaviors } from '@polymer/polymer/lib/legacy/class.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
class HuiInputNumberEntityRow extends mixinBehaviors([IronResizableBehavior], PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
.flex {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
.state {
|
||||||
|
min-width: 45px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
paper-input {
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
id="input_number_card"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'slider')]]">
|
||||||
|
<div class="flex">
|
||||||
|
<paper-slider
|
||||||
|
min="[[_min]]"
|
||||||
|
max="[[_max]]"
|
||||||
|
value="{{_value}}"
|
||||||
|
step="[[_step]]"
|
||||||
|
pin
|
||||||
|
on-change="_selectedValueChanged"
|
||||||
|
ignore-bar-touch
|
||||||
|
></paper-slider>
|
||||||
|
<div class="state">[[_value]] [[_stateObj.attributes.unit_of_measurement]]</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[_equals(_stateObj.attributes.mode, 'box')]]">
|
||||||
|
<paper-input
|
||||||
|
no-label-float
|
||||||
|
auto-validate
|
||||||
|
pattern="[0-9]+([\\.][0-9]+)?"
|
||||||
|
step="[[_step]]"
|
||||||
|
min="[[_min]]"
|
||||||
|
max="[[_max]]"
|
||||||
|
value="{{_value}}"
|
||||||
|
type="number"
|
||||||
|
on-change="_selectedValueChanged"
|
||||||
|
></paper-input>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)',
|
||||||
|
observer: '_stateObjChanged'
|
||||||
|
},
|
||||||
|
_min: {
|
||||||
|
type: Number,
|
||||||
|
value: 0
|
||||||
|
},
|
||||||
|
_max: {
|
||||||
|
type: Number,
|
||||||
|
value: 100
|
||||||
|
},
|
||||||
|
_step: Number,
|
||||||
|
_value: Number
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
if (typeof ResizeObserver === 'function') {
|
||||||
|
const ro = new ResizeObserver((entries) => {
|
||||||
|
entries.forEach(() => {
|
||||||
|
this._hiddenState();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
ro.observe(this.$.input_number_card);
|
||||||
|
} else {
|
||||||
|
this.addEventListener('iron-resize', this._hiddenState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_equals(a, b) {
|
||||||
|
return a === b;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_hiddenState() {
|
||||||
|
if (this._stateObj.attributes.mode !== 'slider') return;
|
||||||
|
const sliderwidth = this.shadowRoot.querySelector('paper-slider').offsetWidth;
|
||||||
|
const stateElement = this.shadowRoot.querySelector('.state');
|
||||||
|
if (sliderwidth < 100) {
|
||||||
|
stateElement.style.display = 'none';
|
||||||
|
} else if (sliderwidth >= 145) {
|
||||||
|
stateElement.style.display = 'inline';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateObjChanged(stateObj, oldStateObj) {
|
||||||
|
this.setProperties({
|
||||||
|
_min: Number(stateObj.attributes.min),
|
||||||
|
_max: Number(stateObj.attributes.max),
|
||||||
|
_step: Number(stateObj.attributes.step),
|
||||||
|
_value: Number(stateObj.state)
|
||||||
|
});
|
||||||
|
if (oldStateObj && stateObj.attributes.mode === 'slider' && oldStateObj.attributes.mode !== 'slider') {
|
||||||
|
this._hiddenState();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedValueChanged() {
|
||||||
|
if (this._value === Number(this._stateObj.state)) return;
|
||||||
|
|
||||||
|
this.hass.callService('input_number', 'set_value', {
|
||||||
|
value: this._value,
|
||||||
|
entity_id: this._stateObj.entity_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-input-number-entity-row', HuiInputNumberEntityRow);
|
101
src/panels/lovelace/entity-rows/hui-input-select-entity-row.js
Normal file
101
src/panels/lovelace/entity-rows/hui-input-select-entity-row.js
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
|
||||||
|
import '@polymer/paper-item/paper-item.js';
|
||||||
|
import '@polymer/paper-listbox/paper-listbox.js';
|
||||||
|
|
||||||
|
import '../../../components/entity/state-badge.js';
|
||||||
|
|
||||||
|
import computeStateName from '../../../common/entity/compute_state_name.js';
|
||||||
|
|
||||||
|
import EventsMixin from '../../../mixins/events-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin EventsMixin
|
||||||
|
*/
|
||||||
|
class HuiInputSelectEntityRow extends EventsMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
:host {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
}
|
||||||
|
paper-dropdown-menu {
|
||||||
|
margin-left: 16px;
|
||||||
|
flex: 1;
|
||||||
|
}
|
||||||
|
.not-found {
|
||||||
|
flex: 1;
|
||||||
|
background-color: yellow;
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<template is="dom-if" if="[[_stateObj]]">
|
||||||
|
<state-badge state-obj="[[_stateObj]]"></state-badge>
|
||||||
|
<paper-dropdown-menu on-click="_stopPropagation" selected-item-label="{{_selected}}" label="[[_computeName(_config.name, _stateObj)]]">
|
||||||
|
<paper-listbox slot="dropdown-content" selected="[[_computeSelected(_stateObj)]]">
|
||||||
|
<template is="dom-repeat" items="[[_stateObj.attributes.options]]">
|
||||||
|
<paper-item>[[item]]</paper-item>
|
||||||
|
</template>
|
||||||
|
</paper-listbox>
|
||||||
|
</paper-dropdown-menu>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[!_stateObj]]">
|
||||||
|
<div class="not-found">
|
||||||
|
Entity not available: [[_config.entity]]
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)'
|
||||||
|
},
|
||||||
|
_selected: {
|
||||||
|
type: String,
|
||||||
|
observer: '_selectedChanged',
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeName(name, stateObj) {
|
||||||
|
return name || computeStateName(stateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeSelected(stateObj) {
|
||||||
|
return stateObj.attributes.options.indexOf(stateObj.state);
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedChanged(option) {
|
||||||
|
// Selected Option will transition to '' before transitioning to new value
|
||||||
|
if (option === '' || option === this._stateObj.state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hass.callService('input_select', 'select_option', {
|
||||||
|
option: option,
|
||||||
|
entity_id: this._stateObj.entity_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_stopPropagation(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-input-select-entity-row', HuiInputSelectEntityRow);
|
67
src/panels/lovelace/entity-rows/hui-input-text-entity-row.js
Normal file
67
src/panels/lovelace/entity-rows/hui-input-text-entity-row.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-input/paper-input.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
class HuiInputTextEntityRow extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<paper-input
|
||||||
|
no-label-float
|
||||||
|
minlength="[[_stateObj.attributes.min]]"
|
||||||
|
maxlength="[[_stateObj.attributes.max]]"
|
||||||
|
value="{{_value}}"
|
||||||
|
auto-validate="[[_stateObj.attributes.pattern]]"
|
||||||
|
pattern="[[_stateObj.attributes.pattern]]"
|
||||||
|
type="[[_stateObj.attributes.mode]]"
|
||||||
|
on-change="_selectedValueChanged"
|
||||||
|
placeholder="(empty value)"
|
||||||
|
></paper-input>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)',
|
||||||
|
observer: '_stateObjChanged',
|
||||||
|
},
|
||||||
|
_value: String
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateObjChanged(stateObj) {
|
||||||
|
this._value = stateObj.state;
|
||||||
|
}
|
||||||
|
|
||||||
|
_selectedValueChanged() {
|
||||||
|
if (this._value === this._stateObj.state) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.hass.callService('input_text', 'set_value', {
|
||||||
|
value: this._value,
|
||||||
|
entity_id: this._stateObj.entity_id,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-input-text-entity-row', HuiInputTextEntityRow);
|
67
src/panels/lovelace/entity-rows/hui-lock-entity-row.js
Normal file
67
src/panels/lovelace/entity-rows/hui-lock-entity-row.js
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-button/paper-button.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class HuiLockEntityRow extends LocalizeMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
paper-button {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<paper-button on-click="_callService">
|
||||||
|
[[_computeButtonTitle(_stateObj.state)]]
|
||||||
|
</paper-button>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeButtonTitle(state) {
|
||||||
|
return state === 'locked' ?
|
||||||
|
this.localize('ui.card.lock.unlock') : this.localize('ui.card.lock.lock');
|
||||||
|
}
|
||||||
|
|
||||||
|
_callService(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
const stateObj = this._stateObj;
|
||||||
|
this.hass.callService('lock', stateObj.state === 'locked' ?
|
||||||
|
'unlock' : 'lock', { entity_id: stateObj.entity_id });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-lock-entity-row', HuiLockEntityRow);
|
56
src/panels/lovelace/entity-rows/hui-scene-entity-row.js
Normal file
56
src/panels/lovelace/entity-rows/hui-scene-entity-row.js
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-button/paper-button.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class HuiSceneEntityRow extends LocalizeMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
paper-button {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<paper-button on-click="_callService">
|
||||||
|
[[localize('ui.card.scene.activate')]]
|
||||||
|
</paper-button>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_callService(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.hass.callService('scene', 'turn_on', { entity_id: this._config.entity });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-scene-entity-row', HuiSceneEntityRow);
|
64
src/panels/lovelace/entity-rows/hui-script-entity-row.js
Normal file
64
src/panels/lovelace/entity-rows/hui-script-entity-row.js
Normal file
@ -0,0 +1,64 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
import '@polymer/paper-button/paper-button.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
import '../../../components/entity/ha-entity-toggle.js';
|
||||||
|
|
||||||
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class HuiScriptEntityRow extends LocalizeMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<style>
|
||||||
|
paper-button {
|
||||||
|
color: var(--primary-color);
|
||||||
|
font-weight: 500;
|
||||||
|
margin: 0;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<template is="dom-if" if="[[_stateObj.attributes.can_cancel]]">
|
||||||
|
<ha-entity-toggle state-obj="[[_stateObj]]" hass="[[hass]]"></ha-entity-toggle>
|
||||||
|
</template>
|
||||||
|
<template is="dom-if" if="[[!_stateObj.attributes.can_cancel]]">
|
||||||
|
<paper-button on-click="_callService">[[localize('ui.card.script.execute')]]</paper-button>
|
||||||
|
</template>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_callService(ev) {
|
||||||
|
ev.stopPropagation();
|
||||||
|
this.hass.callService('script', 'turn_on', { entity_id: this._config.entity });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-script-entity-row', HuiScriptEntityRow);
|
53
src/panels/lovelace/entity-rows/hui-text-entity-row.js
Normal file
53
src/panels/lovelace/entity-rows/hui-text-entity-row.js
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
import computeStateDisplay from '../../../common/entity/compute_state_display.js';
|
||||||
|
|
||||||
|
import LocalizeMixin from '../../../mixins/localize-mixin.js';
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @appliesMixin LocalizeMixin
|
||||||
|
*/
|
||||||
|
class HuiTextEntityRow extends LocalizeMixin(PolymerElement) {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
[[_computeState(_stateObj)]]
|
||||||
|
</div>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)'
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeState(stateObj) {
|
||||||
|
return computeStateDisplay(this.localize, stateObj);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-text-entity-row', HuiTextEntityRow);
|
92
src/panels/lovelace/entity-rows/hui-timer-entity-row.js
Normal file
92
src/panels/lovelace/entity-rows/hui-timer-entity-row.js
Normal file
@ -0,0 +1,92 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
|
||||||
|
import timerTimeRemaining from '../../../common/entity/timer_time_remaining.js';
|
||||||
|
import secondsToDuration from '../../../common/datetime/seconds_to_duration.js';
|
||||||
|
|
||||||
|
class HuiTimerEntityRow extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<div>
|
||||||
|
[[_computeDisplay(_stateObj, _timeRemaining)]]
|
||||||
|
</div>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object,
|
||||||
|
_stateObj: {
|
||||||
|
type: Object,
|
||||||
|
computed: '_computeStateObj(hass.states, _config.entity)',
|
||||||
|
observer: '_stateObjChanged'
|
||||||
|
},
|
||||||
|
_timeRemaining: Number
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
disconnectedCallback() {
|
||||||
|
super.disconnectedCallback();
|
||||||
|
this._clearInterval();
|
||||||
|
}
|
||||||
|
|
||||||
|
_stateObjChanged(stateObj) {
|
||||||
|
if (stateObj) {
|
||||||
|
this._startInterval(stateObj);
|
||||||
|
} else {
|
||||||
|
this._clearInterval();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_clearInterval() {
|
||||||
|
if (this._updateRemaining) {
|
||||||
|
clearInterval(this._updateRemaining);
|
||||||
|
this._updateRemaining = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_startInterval(stateObj) {
|
||||||
|
this._clearInterval();
|
||||||
|
this._calculateRemaining(stateObj);
|
||||||
|
|
||||||
|
if (stateObj.state === 'active') {
|
||||||
|
this._updateRemaining = setInterval(() => this._calculateRemaining(this._stateObj), 1000);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
_calculateRemaining(stateObj) {
|
||||||
|
this._timeRemaining = timerTimeRemaining(stateObj);
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeDisplay(stateObj, time) {
|
||||||
|
if (stateObj.state === 'idle' || time === 0) return stateObj.state;
|
||||||
|
|
||||||
|
let display = secondsToDuration(time);
|
||||||
|
|
||||||
|
if (stateObj.state === 'paused') {
|
||||||
|
display += ' (paused)';
|
||||||
|
}
|
||||||
|
|
||||||
|
return display;
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-timer-entity-row', HuiTimerEntityRow);
|
37
src/panels/lovelace/entity-rows/hui-toggle-entity-row.js
Normal file
37
src/panels/lovelace/entity-rows/hui-toggle-entity-row.js
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
|
||||||
|
import { PolymerElement } from '@polymer/polymer/polymer-element.js';
|
||||||
|
|
||||||
|
import '../components/hui-generic-entity-row.js';
|
||||||
|
import '../../../components/entity/ha-entity-toggle.js';
|
||||||
|
|
||||||
|
class HuiToggleEntityRow extends PolymerElement {
|
||||||
|
static get template() {
|
||||||
|
return html`
|
||||||
|
<hui-generic-entity-row
|
||||||
|
hass="[[hass]]"
|
||||||
|
config="[[_config]]"
|
||||||
|
>
|
||||||
|
<ha-entity-toggle hass="[[hass]]" state-obj="[[_computeStateObj(hass.states, _config.entity)]]"></ha-entity-toggle>
|
||||||
|
</hui-generic-entity-row>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
hass: Object,
|
||||||
|
_config: Object
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
_computeStateObj(states, entityId) {
|
||||||
|
return states && entityId in states ? states[entityId] : null;
|
||||||
|
}
|
||||||
|
|
||||||
|
setConfig(config) {
|
||||||
|
if (!config || !config.entity) {
|
||||||
|
throw new Error('Entity not configured.');
|
||||||
|
}
|
||||||
|
this._config = config;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define('hui-toggle-entity-row', HuiToggleEntityRow);
|
@ -37,7 +37,8 @@ class HuiUnusedEntities extends PolymerElement {
|
|||||||
const root = this.$.root;
|
const root = this.$.root;
|
||||||
if (root.lastChild) root.removeChild(root.lastChild);
|
if (root.lastChild) root.removeChild(root.lastChild);
|
||||||
|
|
||||||
const entities = computeUnusedEntities(this.hass, config);
|
const entities = computeUnusedEntities(this.hass, config).map(entity =>
|
||||||
|
({ entity, secondary_info: 'entity-id' }));
|
||||||
const cardConfig = {
|
const cardConfig = {
|
||||||
type: 'entities',
|
type: 'entities',
|
||||||
title: 'Unused entities',
|
title: 'Unused entities',
|
||||||
|
@ -30,12 +30,11 @@ class StateCardClimate extends PolymerElement {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,8 +45,7 @@ class StateCardClimate extends PolymerElement {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -38,12 +38,11 @@ class StateCardConfigurator extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +53,7 @@ class StateCardConfigurator extends LocalizeMixin(PolymerElement) {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,12 +29,11 @@ class StateCardCover extends PolymerElement {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -49,8 +48,7 @@ class StateCardCover extends PolymerElement {
|
|||||||
entityObj: {
|
entityObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
computed: 'computeEntityObj(hass, stateObj)',
|
computed: 'computeEntityObj(hass, stateObj)',
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,12 +46,11 @@ class StateCardDisplay extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -62,8 +61,7 @@ class StateCardDisplay extends LocalizeMixin(PolymerElement) {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,12 +51,11 @@ class StateCardInputNumber extends mixinBehaviors([
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -105,16 +104,9 @@ class StateCardInputNumber extends mixinBehaviors([
|
|||||||
type: Number,
|
type: Number,
|
||||||
value: 3
|
value: 3
|
||||||
},
|
},
|
||||||
step: {
|
step: Number,
|
||||||
type: Number,
|
value: Number,
|
||||||
},
|
mode: String
|
||||||
value: {
|
|
||||||
type: Number,
|
|
||||||
},
|
|
||||||
mode: {
|
|
||||||
type: String,
|
|
||||||
},
|
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,13 +59,12 @@ class StateCardInputSelect extends PolymerElement {
|
|||||||
selectedOption: {
|
selectedOption: {
|
||||||
type: String,
|
type: String,
|
||||||
observer: 'selectedOptionChanged',
|
observer: 'selectedOptionChanged',
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeStateName(stateObj) {
|
_computeStateName(stateObj) {
|
||||||
return this.overrideName || computeStateName(stateObj);
|
return computeStateName(stateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
computeSelected(stateObj) {
|
computeSelected(stateObj) {
|
||||||
|
@ -25,12 +25,11 @@ class StateCardInputText extends PolymerElement {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,8 +49,7 @@ class StateCardInputText extends PolymerElement {
|
|||||||
},
|
},
|
||||||
|
|
||||||
pattern: String,
|
pattern: String,
|
||||||
value: String,
|
value: String
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -38,8 +38,7 @@ class StateCardLock extends LocalizeMixin(PolymerElement) {
|
|||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -54,8 +53,7 @@ class StateCardLock extends LocalizeMixin(PolymerElement) {
|
|||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
},
|
||||||
isLocked: Boolean,
|
isLocked: Boolean
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -53,12 +53,11 @@ class StateCardMediaPlayer extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,8 +72,7 @@ class StateCardMediaPlayer extends LocalizeMixin(PolymerElement) {
|
|||||||
playerObj: {
|
playerObj: {
|
||||||
type: Object,
|
type: Object,
|
||||||
computed: 'computePlayerObj(hass, stateObj)',
|
computed: 'computePlayerObj(hass, stateObj)',
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -32,12 +32,11 @@ class StateCardScene extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -48,8 +47,7 @@ class StateCardScene extends LocalizeMixin(PolymerElement) {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,12 +43,11 @@ class StateCardScript extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -59,8 +58,7 @@ class StateCardScript extends LocalizeMixin(PolymerElement) {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,12 +7,8 @@ import '../components/entity/state-info.js';
|
|||||||
|
|
||||||
import timerTimeRemaining from '../common/entity/timer_time_remaining.js';
|
import timerTimeRemaining from '../common/entity/timer_time_remaining.js';
|
||||||
import secondsToDuration from '../common/datetime/seconds_to_duration.js';
|
import secondsToDuration from '../common/datetime/seconds_to_duration.js';
|
||||||
import LocalizeMixin from '../mixins/localize-mixin.js';
|
|
||||||
|
|
||||||
/*
|
class StateCardTimer extends PolymerElement {
|
||||||
* @appliesMixin LocalizeMixin
|
|
||||||
*/
|
|
||||||
class StateCardTimer extends LocalizeMixin(PolymerElement) {
|
|
||||||
static get template() {
|
static get template() {
|
||||||
return html`
|
return html`
|
||||||
<style include="iron-flex iron-flex-alignment"></style>
|
<style include="iron-flex iron-flex-alignment"></style>
|
||||||
@ -36,12 +32,11 @@ class StateCardTimer extends LocalizeMixin(PolymerElement) {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -56,8 +51,7 @@ class StateCardTimer extends LocalizeMixin(PolymerElement) {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,12 +25,11 @@ class StateCardToggle extends PolymerElement {
|
|||||||
|
|
||||||
static get stateInfoTemplate() {
|
static get stateInfoTemplate() {
|
||||||
return html`
|
return html`
|
||||||
<state-info
|
<state-info
|
||||||
hass="[[hass]]"
|
hass="[[hass]]"
|
||||||
state-obj="[[stateObj]]"
|
state-obj="[[stateObj]]"
|
||||||
in-dialog="[[inDialog]]"
|
in-dialog="[[inDialog]]"
|
||||||
override-name="[[overrideName]]">
|
></state-info>
|
||||||
</state-info>
|
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -41,8 +40,7 @@ class StateCardToggle extends PolymerElement {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -40,8 +40,7 @@ class StateCardWeblink extends PolymerElement {
|
|||||||
inDialog: {
|
inDialog: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
value: false,
|
value: false,
|
||||||
},
|
}
|
||||||
overrideName: String
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ class StateCardWeblink extends PolymerElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
_computeStateName(stateObj) {
|
_computeStateName(stateObj) {
|
||||||
return this.overrideName || computeStateName(stateObj);
|
return computeStateName(stateObj);
|
||||||
}
|
}
|
||||||
|
|
||||||
onTap(ev) {
|
onTap(ev) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user