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:
@@ -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>
|
||||
|
||||
@@ -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) : '';
|
||||
},
|
||||
});
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
}
|
||||
},
|
||||
|
||||
|
||||
@@ -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>
|
||||
@@ -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);
|
||||
},
|
||||
});
|
||||
@@ -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>
|
||||
Reference in New Issue
Block a user