Exp. UI: Add glance card (#1305)

* Exp. UI: Add vertical entities card

* Remove iron-icon import

* Add light

* Change name

* Flex

* Fix CSS

* Rebuild view to work with themes

* Lint

* Default title Home Assistant

* Tweaks
This commit is contained in:
c727 2018-06-20 21:08:01 +02:00 committed by Paulus Schoutsen
parent 1f8f6f52bc
commit 92111cd5be
4 changed files with 200 additions and 24 deletions

View File

@ -16,9 +16,16 @@ import './hui-root.js';
class Lovelace extends PolymerElement {
static get template() {
return html`
<template is='dom-if' if='[[_equal(_state, "loaded")]]' restamp>
<hui-root
hass='[[hass]]'
config='[[_config]]'
columns='[[_columns]]'
on-config-refresh='_fetchConfig'
></hui-root>
</template>
<template is='dom-if' if='[[_equal(_state, "loading")]]' restamp>
<hass-loading-screen
title='Lovelace'
narrow="[[narrow]]"
show-menu="[[showMenu]]"
></hass-loading-screen>
@ -31,14 +38,6 @@ class Lovelace extends PolymerElement {
show-menu="[[showMenu]]"
></hass-error-screen>
</template>
<template is='dom-if' if='[[_equal(_state, "loaded")]]' restamp>
<hui-root
hass='[[hass]]'
config='[[_config]]'
columns='[[_columns]]'
on-config-refresh='_fetchConfig'
></hui-root>
</template>
`;
}

View File

@ -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`
<style>
ha-card {
padding: 16px;
}
.header {
@apply --paper-font-headline;
/* overwriting line-height +8 because entity-toggle can be 40px height,
compensating this with reduced padding */
line-height: 40px;
color: var(--primary-text-color);
padding: 4px 0 12px;
}
.header .name {
@apply --paper-font-common-nowrap;
}
.entities {
padding: 4px 0;
display: flex;
margin-bottom: -12px;
flex-wrap: wrap;
}
.entity {
box-sizing: border-box;
padding: 0 4px;
display: flex;
flex-direction: column;
cursor: pointer;
margin-bottom: 12px;
width: 20%;
}
.entity div, .entity state-badge {
width: 100%;
text-align: center;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.error {
background-color: red;
color: white;
text-align: center;
}
</style>
<ha-card>
<div class="header">
<div class="name">[[_computeTitle(config)]]</div>
</div>
<div class="entities">
<template is="dom-repeat" items="[[_entities]]">
<template is="dom-if" if="[[_showEntity(item, hass.states)]]">
<div class="entity" on-click="_openDialog">
<div>[[_computeName(item, hass.states)]]</div>
<state-badge state-obj="[[_computeStateObj(item, hass.states)]]"></state-badge>
<div>[[_computeState(item, hass.states)]]</div>
</div>
</template>
</template>
</div>
<template is="dom-if" if="[[_error]]">
<div class="error">[[_error]]</div>
</template>
</ha-card>
`;
}
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);

View File

@ -62,22 +62,27 @@ class HUIRoot extends EventsMixin(PolymerElement) {
</div>
</app-header>
<hui-view
hass='[[hass]]'
config='[[_computeViewConfig(config.views, _curView)]]'
columns='[[columns]]'
></hui-view>
<span id='view'></span>
</app-header-layout>
`;
}
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.
*

View File

@ -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',