Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/components/entity/state-info.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,12 @@ class StateInfo extends PolymerElement {
},
hass: Object,
stateObj: Object,
inDialog: Boolean,
overrideName: String
inDialog: Boolean
};
}

computeStateName(stateObj) {
return this.overrideName || computeStateName(stateObj);
return computeStateName(stateObj);
}
}

Expand Down
28 changes: 10 additions & 18 deletions src/panels/lovelace/cards/hui-entities-card.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,15 @@ import '@polymer/iron-flex-layout/iron-flex-layout-classes.js';
import { html } from '@polymer/polymer/lib/utils/html-tag.js';
import { PolymerElement } from '@polymer/polymer/polymer-element.js';

import processConfigEntities from '../common/process-config-entities.js';

import '../../../components/ha-card.js';
import '../components/hui-entities-toggle.js';

// just importing this now as shortcut to import correct state-card-*
import '../../../state-summary/state-card-content.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 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';

/*
* @appliesMixin EventsMixin
Expand Down Expand Up @@ -70,7 +66,7 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {
type: Object,
observer: '_hassChanged',
},
_config: Object,
_config: Object
};
}

Expand Down Expand Up @@ -117,27 +113,23 @@ class HuiEntitiesCard extends EventsMixin(PolymerElement) {

for (const entity of entities) {
const entityId = entity.entity;

const element = createEntityRowElement(entity, this.hass);
const element = createEntityRowElement(entity);
if (entityId && !DOMAINS_HIDE_MORE_INFO.includes(computeDomain(entityId))) {
element.classList.add('state-card-dialog');
element.addEventListener('click', () => this.fire('hass-more-info', { entityId }));
}

this._elements.push({ entityId, element });
element.hass = this.hass;
this._elements.push(element);
const container = document.createElement('div');
container.appendChild(element);
root.appendChild(container);
}
}

_hassChanged(hass) {
for (let i = 0; i < this._elements.length; i++) {
const { entityId, element } = this._elements[i];
const stateObj = hass.states[entityId];
element.stateObj = stateObj;
this._elements.forEach((element) => {
element.hass = hass;
}
});
}
}

Expand Down
53 changes: 33 additions & 20 deletions src/panels/lovelace/common/create-entity-row-element.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,36 @@
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';

const CUSTOM_TYPE_PREFIX = 'custom:';

function _createElement(tag, config, stateObj, hass) {
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) {
const element = document.createElement(tag);
try {
if ('setConfig' in element) element.setConfig(config);
Expand All @@ -17,38 +41,26 @@ function _createElement(tag, config, stateObj, hass) {
return _createErrorElement(err.message, config);
}

element.stateObj = stateObj;
element.hass = hass;
if (config.name) {
element.overrideName = config.name;
}

return element;
}

function _createErrorElement(error, config) {
return _createElement('hui-error-card', createErrorCardConfig(error, config));
}

export default function createEntityRowElement(config, hass) {
export default function createEntityRowElement(config) {
let tag;

if (!config || typeof config !== 'object') {
if (!config || typeof config !== 'object' || !config.entity) {
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 stateObj = hass.states[entityId];
if (type.startsWith(CUSTOM_TYPE_PREFIX)) {
tag = type.substr(CUSTOM_TYPE_PREFIX.length);

if (customElements.get(tag)) {
return _createElement(tag, config, stateObj, hass);
return _createElement(tag, config);
}
const element = _createErrorElement(`Custom element doesn't exist: ${tag}.`, config);

Expand All @@ -58,7 +70,8 @@ export default function createEntityRowElement(config, hass) {
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 changes: 92 additions & 0 deletions src/panels/lovelace/components/hui-generic-entity-row.js
Original file line number Diff line number Diff line change
@@ -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 changes: 56 additions & 0 deletions src/panels/lovelace/entity-rows/hui-cover-entity-row.js
Original file line number Diff line number Diff line change
@@ -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);
Loading