diff --git a/src/panels/lovelace/ha-panel-lovelace.js b/src/panels/lovelace/ha-panel-lovelace.js index 1d5c82d717..b05825d33e 100644 --- a/src/panels/lovelace/ha-panel-lovelace.js +++ b/src/panels/lovelace/ha-panel-lovelace.js @@ -16,9 +16,16 @@ import './hui-root.js'; class Lovelace extends PolymerElement { static get template() { return html` + + + @@ -31,14 +38,6 @@ class Lovelace extends PolymerElement { show-menu="[[showMenu]]" > - - - `; } diff --git a/src/panels/lovelace/hui-glance-card.js b/src/panels/lovelace/hui-glance-card.js new file mode 100644 index 0000000000..74da286b62 --- /dev/null +++ b/src/panels/lovelace/hui-glance-card.js @@ -0,0 +1,136 @@ +import { html } from '@polymer/polymer/lib/utils/html-tag.js'; +import { PolymerElement } from '@polymer/polymer/polymer-element.js'; + +import computeStateDisplay from '../../common/entity/compute_state_display.js'; +import computeStateName from '../../common/entity/compute_state_name.js'; + +import '../../components/entity/state-badge.js'; +import '../../components/ha-card.js'; + +import EventsMixin from '../../mixins/events-mixin.js'; +import LocalizeMixin from '../../mixins/localize-mixin.js'; + +/* + * @appliesMixin EventsMixin + * @appliesMixin LocalizeMixin + */ +class HuiGlanceCard extends LocalizeMixin(EventsMixin(PolymerElement)) { + static get template() { + return html` + + + + + [[_computeTitle(config)]] + + + + + + [[_computeName(item, hass.states)]] + + [[_computeState(item, hass.states)]] + + + + + + [[_error]] + + + `; + } + + static get properties() { + return { + hass: Object, + config: Object, + _entities: { + type: Array, + computed: '_computeEntities(config)' + }, + _error: String + }; + } + + getCardSize() { + return 3; + } + + _computeTitle(config) { + return config.title; + } + + _computeEntities(config) { + if (config && config.entities && Array.isArray(config.entities)) { + this._error = null; + return config.entities; + } + this._error = 'Error in card configuration.'; + return []; + } + + _showEntity(item, states) { + return item in states; + } + + _computeName(item, states) { + return computeStateName(states[item]); + } + + _computeStateObj(item, states) { + return states[item]; + } + + _computeState(item, states) { + return computeStateDisplay(this.localize, states[item]); + } + + _openDialog(ev) { + this.fire('hass-more-info', { entityId: ev.model.item }); + } +} + +customElements.define('hui-glance-card', HuiGlanceCard); diff --git a/src/panels/lovelace/hui-root.js b/src/panels/lovelace/hui-root.js index 685de280b3..f57543d920 100644 --- a/src/panels/lovelace/hui-root.js +++ b/src/panels/lovelace/hui-root.js @@ -62,22 +62,27 @@ class HUIRoot extends EventsMixin(PolymerElement) { - + `; } static get properties() { return { - hass: Object, narrow: Boolean, showMenu: Boolean, - config: Object, - columns: Number, + hass: { + type: Object, + observer: '_hassChanged', + }, + config: { + type: Object, + observer: '_configChanged', + }, + columns: { + type: Number, + observer: '_columnsChanged', + }, _curView: { type: Number, @@ -86,8 +91,13 @@ class HUIRoot extends EventsMixin(PolymerElement) { }; } + ready() { + super.ready(); + this._selectView(0); + } + _computeTitle(config) { - return config.title || 'Experimental UI'; + return config.name || 'Home Assistant'; } _computeTabsHidden(views) { @@ -98,18 +108,47 @@ class HUIRoot extends EventsMixin(PolymerElement) { return view.tab_title || view.name || 'Unnamed View'; } - _computeViewConfig(views, _curView) { - return views[_curView]; - } - _handleRefresh() { this.fire('config-refresh'); } _handleViewSelected(ev) { - this._curView = ev.detail.selected; + this._selectView(ev.detail.selected); } + _selectView(viewIndex) { + this._curView = viewIndex; + + // Recreate a new element to clear the applied themes. + const root = this.$.view; + if (root.lastChild) { + root.removeChild(root.lastChild); + } + const view = document.createElement('hui-view'); + view.setProperties({ + hass: this.hass, + config: this.config.views[this._curView], + columns: this.columns, + }); + root.appendChild(view); + } + + _hassChanged(hass) { + if (!this.$.view.lastChild) return; + this.$.view.lastChild.hass = hass; + } + + _configChanged() { + // On config change, recreate the view from scratch. + this._selectView(this._curView); + } + + _columnsChanged(columns) { + if (!this.$.view.lastChild) return; + this.$.view.lastChild.columns = columns; + } + + /** * Scroll to a specific y coordinate. * diff --git a/src/panels/lovelace/hui-view.js b/src/panels/lovelace/hui-view.js index 38c122b18b..b0a03ef743 100644 --- a/src/panels/lovelace/hui-view.js +++ b/src/panels/lovelace/hui-view.js @@ -1,9 +1,10 @@ import { html } from '@polymer/polymer/lib/utils/html-tag.js'; import { PolymerElement } from '@polymer/polymer/polymer-element.js'; +import './hui-camera-preview-card.js'; import './hui-entities-card.js'; import './hui-entity-filter-card.js'; -import './hui-camera-preview-card.js'; +import './hui-glance-card'; import './hui-history-graph-card.js'; import './hui-media-control-card.js'; import './hui-plant-status-card.js'; @@ -16,6 +17,7 @@ const VALID_TYPES = [ 'camera-preview', 'entities', 'entity-filter', + 'glance', 'history-graph', 'media-control', 'plant-status',