1
0
mirror of https://github.com/home-assistant/frontend.git synced 2025-12-24 12:49:19 +00:00

Reorg into panels (#75)

This commit is contained in:
Paulus Schoutsen
2016-07-16 23:19:49 -07:00
committed by GitHub
parent 5e7f2fdbe8
commit 4029f16e97
45 changed files with 755 additions and 605 deletions

View File

@@ -1,5 +1,19 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="display-time">
<template>[[computeTime(dateObj)]]</template>
</dom-module>
<script>
Polymer({
is: 'display-time',
properties: {
dateObj: {
type: Object,
observer: 'timeChanged',
},
},
timeChanged: function (dateObj) {
var root = Polymer.dom(this);
root.innerHTML = window.moment(dateObj).format('LT');
},
});
</script>

View File

@@ -1,17 +0,0 @@
import Polymer from '../polymer';
import formatTime from '../util/format-time';
export default new Polymer({
is: 'display-time',
properties: {
dateObj: {
type: Object,
},
},
computeTime(dateObj) {
return dateObj ? formatTime(dateObj) : '';
},
});

View File

@@ -7,3 +7,25 @@
<iron-icon icon="[[computeIcon(domain, state)]]"></iron-icon>
</template>
</dom-module>
<script>
Polymer({
is: 'domain-icon',
properties: {
domain: {
type: String,
value: '',
},
state: {
type: String,
value: '',
},
},
computeIcon: function (domain, state) {
return window.domainIcon(domain, state);
},
});
</script>

View File

@@ -1,23 +0,0 @@
import Polymer from '../polymer';
import domainIcon from '../util/domain-icon';
export default new Polymer({
is: 'domain-icon',
properties: {
domain: {
type: String,
value: '',
},
state: {
type: String,
value: '',
},
},
computeIcon(domain, state) {
return domainIcon(domain, state);
},
});

View File

@@ -1,58 +0,0 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="entity-list">
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
line-height: 2em;
}
a {
color: var(--dark-primary-color);
}
</style>
<template>
<ul>
<template is='dom-repeat' items='[[entities]]' as='entity'>
<li><a href='#' on-click='entitySelected'>[[entity.entityId]]</a></li>
</template>
</ul>
</template>
</dom-module>
<script>
Polymer({
is: 'entity-list',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
entities: {
type: Array,
bindNuclear: function (hass) {
return [
hass.entityGetters.entityMap,
function (map) {
return map.valueSeq().sortBy(function (entity) { return entity.entityId; }).toArray();
},
];
},
},
},
entitySelected: function (ev) {
ev.preventDefault();
this.fire('entity-selected', { entityId: ev.model.entity.entityId });
},
});
</script>

View File

@@ -1,114 +0,0 @@
<link rel='import' href='../../../bower_components/polymer/polymer.html'>
<link rel='import' href='../../../bower_components/iron-image/iron-image.html'>
<link rel='import' href='../../../bower_components/iron-icon/iron-icon.html'>
<dom-module id='ha-entity-marker'>
<style is="custom-style" include="iron-positioning"></style>
<style>
.marker {
vertical-align: top;
position: relative;
display: block;
margin: 0 auto;
width: 2.5em;
text-align: center;
height: 2.5em;
line-height: 2.5em;
font-size: 1.5em;
border-radius: 50%;
border: 0.1em solid var(--ha-marker-color, --default-primary-color);
color: rgb(76, 76, 76);
background-color: white;
}
iron-image {
border-radius: 50%;
}
</style>
<template>
<div class='marker'>
<template is='dom-if' if='[[icon]]'>
<iron-icon icon='[[icon]]'></iron-icon>
</template>
<template is='dom-if' if='[[value]]'>[[value]]</template>
<template is='dom-if' if='[[image]]'>
<iron-image sizing='cover' class='fit' src='[[image]]'></iron-image>
</template>
</div>
</template>
</dom-module>
<script>
/*
Leaflet clones this element before adding it to the map. This messes up
our Poylmer object and we lose the reference to the `hass` object.
That's why we refer here to window.hass instead of the hass property.
*/
Polymer({
is: 'ha-entity-marker',
properties: {
hass: {
type: Object,
},
entityId: {
type: String,
value: '',
reflectToAttribute: true,
},
state: {
type: Object,
computed: 'computeState(entityId)',
},
icon: {
type: Object,
computed: 'computeIcon(state)',
},
image: {
type: Object,
computed: 'computeImage(state)',
},
value: {
type: String,
computed: 'computeValue(state)',
},
},
listeners: {
tap: 'badgeTap',
},
badgeTap: function (ev) {
ev.stopPropagation();
if (this.entityId) {
this.async(function () {
window.hass.moreInfoActions.selectEntity(this.entityId);
}, 1);
}
},
computeState: function (entityId) {
return entityId && window.hass.reactor.evaluate(window.hass.entityGetters.byId(entityId));
},
computeIcon: function (state) {
return !state && 'home';
},
computeImage: function (state) {
return state && state.attributes.entity_picture;
},
computeValue: function (state) {
return state &&
state.entityDisplay.split(' ').map(function (part) {
return part.substr(0, 1);
}).join('');
},
});
</script>

View File

@@ -1,61 +0,0 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="events-list">
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
line-height: 2em;
}
a {
color: var(--dark-primary-color);
}
</style>
<template>
<ul>
<template is='dom-repeat' items='[[events]]' as='event'>
<li>
<a href='#' on-click='eventSelected'>{{event.event}}</a>
<span> (</span><span>{{event.listenerCount}}</span><span> listeners)</span>
</li>
</template>
</ul>
</template>
</dom-module>
<script>
Polymer({
is: 'events-list',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
events: {
type: Array,
bindNuclear: function (hass) {
return [
hass.eventGetters.entityMap,
function (map) {
return map.valueSeq().sortBy(function (event) { return event.event; }).toArray();
},
];
},
},
},
eventSelected: function (ev) {
ev.preventDefault();
this.fire('event-selected', { eventType: ev.model.event.event });
},
});
</script>

View File

@@ -1,41 +0,0 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="../components/logbook-entry.html">
<dom-module id="ha-logbook">
<style>
:host {
display: block;
padding: 16px;
}
</style>
<template>
<template is='dom-if' if='[[noEntries(entries)]]'>
No logbook entries found.
</template>
<template is='dom-repeat' items="[[entries]]">
<logbook-entry entry-obj="[[item]]" hass='[[hass]]'></logbook-entry>
</template>
</template>
</dom-module>
<script>
Polymer({
is: 'ha-logbook',
properties: {
hass: {
type: Object,
},
entries: {
type: Array,
value: [],
},
},
noEntries: function (entries) {
return !entries.length;
},
});
</script>

View File

@@ -104,28 +104,17 @@
<div class="title">Home Assistant</div>
<paper-icon-button icon='mdi:chevron-left' hidden$='[[narrow]]' on-tap='toggleMenu'></paper-icon-button>
</paper-toolbar>
<paper-menu attr-for-selected='data-panel' selected='[[selected]]' on-iron-select='menuSelect'>
<paper-icon-item on-tap='menuClicked' data-panel='states'>
<iron-icon item-icon icon='mdi:apps'></iron-icon>
<span class='item-text'>States</span>
</paper-icon-item>
<paper-icon-item on-tap='menuClicked' data-panel='map'>
<iron-icon item-icon icon='mdi:account-location'></iron-icon>
<span class='item-text'>Map</span>
</paper-icon-item>
<template is='dom-if' if='[[hasHistoryComponent]]'>
<paper-icon-item on-tap='menuClicked' data-panel='history'>
<iron-icon item-icon icon='mdi:poll-box'></iron-icon>
<span class='item-text'>History</span>
</paper-icon-item>
</template>
<template is='dom-if' if='[[hasLogbookComponent]]'>
<paper-icon-item on-tap='menuClicked' data-panel='logbook'>
<iron-icon item-icon icon='mdi:format-list-bulleted-type'></iron-icon>
<span class='item-text'>Logbook</span>
<template is='dom-repeat' items='[[computePanels(panels)]]'>
<paper-icon-item on-tap='menuClicked' data-panel$='[[item.url_name]]'>
<iron-icon item-icon icon='[[item.icon]]'></iron-icon>
<span class='item-text'>[[item.title]]</span>
</paper-icon-item>
</template>
@@ -149,19 +138,19 @@
<div class='dev-tools layout horizontal justified'>
<paper-icon-button
icon='mdi:remote' data-panel='devService'
icon='mdi:remote' data-panel='dev-service'
on-tap='menuClicked'></paper-icon-button>
<paper-icon-button
icon='mdi:code-tags' data-panel='devState'
icon='mdi:code-tags' data-panel='dev-state'
on-tap='menuClicked'></paper-icon-button>
<paper-icon-button
icon='mdi:radio-tower' data-panel='devEvent'
icon='mdi:radio-tower' data-panel='dev-event'
on-tap='menuClicked'></paper-icon-button>
<paper-icon-button
icon='mdi:file-xml' data-panel='devTemplate'
icon='mdi:file-xml' data-panel='dev-template'
on-tap='menuClicked'></paper-icon-button>
<paper-icon-button
icon='mdi:information-outline' data-panel='devInfo'
icon='mdi:information-outline' data-panel='dev-info'
on-tap='menuClicked'></paper-icon-button>
</div>
</div>
@@ -195,17 +184,33 @@ Polymer({
selected: {
type: String,
bindNuclear: function (hass) { return hass.navigationGetters.activePane; },
bindNuclear: function (hass) {
return hass.navigationGetters.activePane;
},
},
hasHistoryComponent: {
type: Boolean,
bindNuclear: function (hass) { return hass.configGetters.isComponentLoaded('history'); },
bindNuclear: function (hass) {
return hass.configGetters.isComponentLoaded('history');
},
},
hasLogbookComponent: {
type: Boolean,
bindNuclear: function (hass) { return hass.configGetters.isComponentLoaded('logbook'); },
bindNuclear: function (hass) {
return hass.configGetters.isComponentLoaded('logbook');
},
},
panels: {
type: Array,
bindNuclear: function (hass) {
return [
hass.panelGetters.panels,
function (res) { return res.toJS(); },
];
},
},
},
@@ -213,6 +218,44 @@ Polymer({
this._boundUpdateStyles = this.updateStyles.bind(this);
},
computePanels: function (panels) {
var sortValue = {
map: 1,
logbook: 2,
history: 3,
};
var result = [];
Object.keys(panels).forEach(function (key) {
if (panels[key].title) {
result.push(panels[key]);
}
});
result.sort(function (a, b) {
var aBuiltIn = (a.component_name in sortValue);
var bBuiltIn = (b.component_name in sortValue);
if (aBuiltIn && bBuiltIn) {
return sortValue[a.component_name] - sortValue[b.component_name];
} else if (aBuiltIn) {
return -1;
} else if (bBuiltIn) {
return 1;
}
// both not built in, sort by title
if (a.title > b.title) {
return 1;
}
if (a.title < b.title) {
return -1;
}
return 0;
});
return result;
},
menuSelect: function () {
this.debounce('updateStyles', this._boundUpdateStyles, 1);
},
@@ -220,15 +263,17 @@ Polymer({
menuClicked: function (ev) {
var target = ev.target;
var checks = 5;
var attr = target.getAttribute('data-panel');
// find panel to select
while (checks && !target.getAttribute('data-panel')) {
while (checks && !attr) {
target = target.parentElement;
attr = target.getAttribute('data-panel');
checks--;
}
if (checks) {
this.selectPanel(target.getAttribute('data-panel'));
this.selectPanel(attr);
}
},

View File

@@ -1,56 +0,0 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<link rel="import" href="domain-icon.html">
<link rel="import" href="display-time.html">
<link rel="import" href="relative-ha-datetime.html">
<dom-module id="logbook-entry">
<style is="custom-style" include="iron-flex"></style>
<style>
:host {
@apply(--paper-font-body1);
display: block;
line-height: 2em;
}
display-time {
width: 55px;
font-size: .8em;
color: var(--secondary-text-color);
}
domain-icon {
margin: 0 8px 0 16px;
color: var(--primary-text-color);
}
.name {
text-transform: capitalize;
}
.message {
color: var(--primary-text-color);
}
a {
color: var(--primary-color);
}
</style>
<template>
<div class='horizontal layout'>
<display-time date-obj="[[entryObj.when]]"></display-time>
<domain-icon domain="[[entryObj.domain]]" class='icon'></domain-icon>
<div class='message' flex>
<template is='dom-if' if="[[!entryObj.entityId]]">
<span class='name'>[[entryObj.name]]</span>
</template>
<template is='dom-if' if="[[entryObj.entityId]]">
<a href='#' on-click="entityClicked" class='name'>[[entryObj.name]]</a>
</template>
<span> </span>
<span>[[entryObj.message]]</span>
</div>
</div>
</template>
</dom-module>

View File

@@ -1,19 +0,0 @@
import Polymer from '../polymer';
import './domain-icon';
import './display-time';
export default new Polymer({
is: 'logbook-entry',
properties: {
hass: {
type: Object,
},
},
entityClicked(ev) {
ev.preventDefault();
this.hass.moreInfoActions.selectEntity(this.entryObj.entityId);
},
});

View File

@@ -1,75 +0,0 @@
<link rel="import" href="../../bower_components/polymer/polymer.html">
<dom-module id="services-list">
<style>
ul {
margin: 0;
padding: 0;
}
li {
list-style: none;
line-height: 2em;
}
a {
color: var(--dark-primary-color);
}
</style>
<template>
<ul>
<template is='dom-repeat' items="[[computeDomains(serviceDomains)]]" as="domain">
<template is='dom-repeat' items="[[computeServices(serviceDomains, domain)]]" as="service">
<li><a href='#' on-click='serviceClicked'>
<span>[[domain]]</span>/<span>[[service]]</span>
</a></li>
</template>
</template>
</ul>
</template>
</dom-module>
<script>
Polymer({
is: 'services-list',
behaviors: [window.hassBehavior],
properties: {
hass: {
type: Object,
},
serviceDomains: {
type: Array,
bindNuclear: function (hass) {
return hass.serviceGetters.entityMap;
},
},
},
computeDomains: function (serviceDomains) {
return serviceDomains
.valueSeq()
.map(function (domain) { return domain.domain; })
.sort()
.toJS();
},
computeServices: function (serviceDomains, domain) {
return serviceDomains
.get(domain)
.get('services')
.keySeq()
.toArray();
},
serviceClicked: function (ev) {
ev.preventDefault();
this.fire(
'service-selected', { domain: ev.model.domain,
service: ev.model.service });
},
});
</script>