mirror of
https://github.com/home-assistant/core.git
synced 2025-04-23 16:57:53 +00:00
Major cleanup frontend
This commit is contained in:
parent
990ac057db
commit
b686f04121
@ -356,14 +356,15 @@ class RequestHandler(SimpleHTTPRequestHandler):
|
||||
"<link rel='shortcut icon' href='/static/favicon.ico' />"
|
||||
"<link rel='icon' type='image/png' "
|
||||
" href='/static/favicon-192x192.png' sizes='192x192'>"
|
||||
"<script"
|
||||
" src='/static/polymer_platform.js'></script>"
|
||||
"<link rel='import' href='/static/{}' />"
|
||||
"<meta name='viewport' content='width=device-width, "
|
||||
" user-scalable=no, initial-scale=1.0, "
|
||||
" minimum-scale=1.0, maximum-scale=1.0' />"
|
||||
"</head>"
|
||||
"<body fullbleed>"
|
||||
"<h3 id='init' align='center'>Initializing Home Assistant</h3>"
|
||||
"<script"
|
||||
" src='/static/polymer_platform.js'></script>"
|
||||
"<link rel='import' href='/static/{}' />"
|
||||
"<splash-login auth='{}'></splash-login>"
|
||||
"</body></html>").format(app_url, data.get('api_password', '')))
|
||||
|
||||
|
@ -1,2 +1,2 @@
|
||||
""" DO NOT MODIFY. Auto-generated by build_polymer script """
|
||||
VERSION = "5ae474d6905e074fa2a6aa0cfa2941be"
|
||||
VERSION = "835922d1958738763525d6670c11bfb5"
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -19,8 +19,6 @@
|
||||
"font-roboto": "Polymer/font-roboto#~0.4.2",
|
||||
"core-header-panel": "Polymer/core-header-panel#~0.4.2",
|
||||
"core-toolbar": "Polymer/core-toolbar#~0.4.2",
|
||||
"core-icon-button": "Polymer/core-icon-button#~0.4.2",
|
||||
"paper-fab": "Polymer/paper-fab#~0.4.2",
|
||||
"paper-toast": "Polymer/paper-toast#~0.4.2",
|
||||
"paper-dialog": "Polymer/paper-dialog#~0.4.2",
|
||||
"paper-button": "Polymer/paper-button#~0.4.2",
|
||||
@ -31,6 +29,9 @@
|
||||
"core-item": "Polymer/core-item#~0.4.2",
|
||||
"core-icons": "polymer/core-icons#~0.4.2",
|
||||
"paper-toggle-button": "polymer/paper-toggle-button#~0.4.2",
|
||||
"paper-tabs": "polymer/paper-tabs#~0.4.2"
|
||||
"paper-tabs": "polymer/paper-tabs#~0.4.2",
|
||||
"paper-icon-button": "polymer/paper-icon-button#~0.4.2",
|
||||
"paper-menu-button": "polymer/paper-menu-button#~0.4.2",
|
||||
"paper-item": "polymer/paper-item#~0.4.2"
|
||||
}
|
||||
}
|
||||
|
@ -6,15 +6,19 @@
|
||||
<link rel="import" href="bower_components/core-icons/image-icons.html">
|
||||
<link rel="import" href="bower_components/core-icons/hardware-icons.html">
|
||||
|
||||
<polymer-element name="domain-icon" attributes="domain">
|
||||
<polymer-element name="domain-icon"
|
||||
attributes="domain state" constructor="DomainIcon">
|
||||
<template>
|
||||
<core-icon icon="{{icon(domain)}}"></core-icon>
|
||||
<core-icon icon="{{icon(domain, state)}}"></core-icon>
|
||||
</template>
|
||||
<script>
|
||||
Polymer({
|
||||
|
||||
icon: function() {
|
||||
switch(this.domain) {
|
||||
icon: function(domain, state) {
|
||||
switch(domain) {
|
||||
case "homeassistant":
|
||||
return "home";
|
||||
|
||||
case "group":
|
||||
return "social:communities";
|
||||
|
||||
@ -25,8 +29,11 @@
|
||||
return "settings-input-svideo";
|
||||
|
||||
case "chromecast":
|
||||
// hardware:cast-connected
|
||||
return "hardware:cast";
|
||||
if(state && state != "idle") {
|
||||
return "hardware:cast-connected";
|
||||
} else {
|
||||
return "hardware:cast";
|
||||
}
|
||||
|
||||
case "process":
|
||||
return "hardware:memory"
|
||||
|
@ -58,7 +58,7 @@
|
||||
},
|
||||
|
||||
_sortStates: function(states) {
|
||||
return states.sort(function(one, two) {
|
||||
states.sort(function(one, two) {
|
||||
if (one.entity_id > two.entity_id) {
|
||||
return 1;
|
||||
} else if (one.entity_id < two.entity_id) {
|
||||
@ -86,6 +86,7 @@
|
||||
}
|
||||
|
||||
if(!stateFound) {
|
||||
this._enhanceState(state);
|
||||
this.states.push(new_state);
|
||||
this._sortStates(this.states);
|
||||
}
|
||||
@ -93,6 +94,14 @@
|
||||
this.fire('states-updated')
|
||||
},
|
||||
|
||||
_enhanceState: function(state) {
|
||||
var parts = state.entity_id.split(".");
|
||||
state.domain = parts[0];
|
||||
state.entity = parts[1];
|
||||
state.entityDisplay = state.entity.replace(/_/g, " ");
|
||||
state.stateDisplay = state.state.replace(/_/g, " ");
|
||||
},
|
||||
|
||||
// call api methods
|
||||
fetchState: function(entityId) {
|
||||
var successStateUpdate = function(new_state) {
|
||||
@ -104,7 +113,9 @@
|
||||
|
||||
fetchStates: function(onSuccess, onError) {
|
||||
var successStatesUpdate = function(newStates) {
|
||||
this.states = this._sortStates(newStates);
|
||||
this._sortStates(newStates);
|
||||
newStates.map(this._enhanceState);
|
||||
this.states = newStates;
|
||||
|
||||
this.fire('states-updated')
|
||||
|
||||
@ -155,7 +166,7 @@
|
||||
}
|
||||
|
||||
var successToast = function(new_state) {
|
||||
this.showToast("State of "+entity_id+" successful set to "+state+".");
|
||||
this.showToast("State of "+entity_id+" set to "+state+".");
|
||||
this._pushNewState(new_state);
|
||||
}
|
||||
|
||||
@ -165,7 +176,13 @@
|
||||
|
||||
call_service: function(domain, service, parameters) {
|
||||
var successToast = function() {
|
||||
this.showToast("Service "+domain+"/"+service+" successful called.");
|
||||
if(service == "turn_on" && parameters.entity_id) {
|
||||
this.showToast("Turned on " + parameters.entity_id + '.');
|
||||
} else if(service == "turn_off") {
|
||||
this.showToast("Turned off " + parameters.entity_id + '.');
|
||||
} else {
|
||||
this.showToast("Service "+domain+"/"+service+" called.");
|
||||
}
|
||||
|
||||
// if we call a service on an entity_id, update the state
|
||||
if(parameters && parameters.entity_id) {
|
||||
@ -197,7 +214,7 @@
|
||||
eventData = eventData ? JSON.parse(eventData) : "";
|
||||
|
||||
var successToast = function() {
|
||||
this.showToast("Event "+eventType+" successful fired.");
|
||||
this.showToast("Event "+eventType+" fired.");
|
||||
}
|
||||
|
||||
this.call_api("POST", "events/" + eventType,
|
||||
@ -267,6 +284,10 @@
|
||||
showToast: function(message) {
|
||||
this.$.toast.text = message;
|
||||
this.$.toast.show();
|
||||
},
|
||||
|
||||
logOut: function() {
|
||||
this.auth = "";
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -1,7 +1,8 @@
|
||||
<link rel="import" href="bower_components/core-header-panel/core-header-panel.html">
|
||||
<link rel="import" href="bower_components/core-toolbar/core-toolbar.html">
|
||||
<link rel="import" href="bower_components/core-icon-button/core-icon-button.html">
|
||||
<link rel="import" href="bower_components/paper-fab/paper-fab.html">
|
||||
<link rel="import" href="bower_components/paper-icon-button/paper-icon-button.html">
|
||||
<link rel="import" href="bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="bower_components/paper-menu-button/paper-menu-button.html">
|
||||
<link rel="import" href="bower_components/paper-tabs/paper-tabs.html">
|
||||
<link rel="import" href="bower_components/paper-tabs/paper-tab.html">
|
||||
|
||||
@ -24,33 +25,41 @@
|
||||
|
||||
core-toolbar {
|
||||
background: #03a9f4;
|
||||
font-size: 1.4rem;
|
||||
font-size: 1.3rem;
|
||||
color: white;
|
||||
}
|
||||
|
||||
.content {
|
||||
padding-bottom: 75px;
|
||||
padding-right: 10px;
|
||||
paper-tab {
|
||||
text-transform: uppercase;
|
||||
}
|
||||
|
||||
paper-fab {
|
||||
position: fixed;
|
||||
bottom: 10px;
|
||||
right: 10px;
|
||||
.content {
|
||||
padding-bottom: 10px;
|
||||
padding-right: 10px;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
<core-header-panel unresolved fullbleed>
|
||||
<core-header-panel fullbleed>
|
||||
|
||||
<core-toolbar class='medium-tall'>
|
||||
<div flex>
|
||||
Home Assistant
|
||||
</div>
|
||||
<core-icon-button icon="refresh" on-click="{{handleRefreshClick}}"></core-icon-button>
|
||||
<core-icon-button icon="developer-mode-tv" on-click="{{handleEventClick}}"></core-icon-button>
|
||||
<core-icon-button icon="settings-remote" on-click="{{handleServiceClick}}"></core-icon-button>
|
||||
<paper-icon-button icon="refresh" on-click="{{handleRefreshClick}}"></paper-icon-button>
|
||||
<paper-icon-button icon="settings-remote"
|
||||
on-click="{{handleServiceClick}}"></paper-icon-button>
|
||||
<paper-menu-button icon="more-vert" halign="right">
|
||||
<paper-item label="Set State">
|
||||
<a on-click={{handleAddStateClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Trigger Event">
|
||||
<a on-click={{handleEventClick}}></a>
|
||||
</paper-item>
|
||||
<paper-item label="Log Out">
|
||||
<a on-click={{handleLogOutClick}}></a>
|
||||
</paper-item>
|
||||
</paper-menu-button>
|
||||
|
||||
<div class="bottom fit" horizontal layout>
|
||||
<paper-tabs id="tabsHolder" noink flex
|
||||
@ -59,8 +68,10 @@
|
||||
<paper-tab>ALL</paper-tab>
|
||||
|
||||
<template repeat="{{state in api.states}}">
|
||||
<template if="{{isCustomGroup(state)}}">
|
||||
<paper-tab data-entity="{{state.entity_id}}">{{state.entity_id | groupName}}</paper-tab>
|
||||
<template if="{{state.domain == 'group' && !state.attributes.auto}}">
|
||||
<paper-tab data-entity="{{state.entity_id}}">
|
||||
{{state.entityDisplay}}
|
||||
</paper-tab>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
@ -70,7 +81,6 @@
|
||||
|
||||
<div class="content" flex>
|
||||
<states-cards api="{{api}}" filter="{{selectedTab}}"></states-cards>
|
||||
<paper-fab icon="add" on-click={{handleAddStateClick}}></paper-fab>
|
||||
</div>
|
||||
|
||||
</core-header-panel>
|
||||
@ -80,15 +90,6 @@
|
||||
Polymer({
|
||||
selectedTab: null,
|
||||
|
||||
isCustomGroup: function(state) {
|
||||
return (state.entity_id.lastIndexOf('group.') == 0 &&
|
||||
!state.attributes.auto);
|
||||
},
|
||||
|
||||
groupName: function(entity_id) {
|
||||
return entity_id.substring(6).toUpperCase().replace(/_/g, " ");
|
||||
},
|
||||
|
||||
tabClicked: function(ev) {
|
||||
if(ev.detail.isSelected) {
|
||||
// will be null for ALL tab
|
||||
@ -110,6 +111,10 @@
|
||||
|
||||
handleAddStateClick: function() {
|
||||
this.api.showSetStateDialog();
|
||||
},
|
||||
|
||||
handleLogOutClick: function() {
|
||||
this.api.logOut();
|
||||
}
|
||||
|
||||
});
|
||||
|
@ -3,6 +3,8 @@
|
||||
<link rel="import" href="bower_components/core-menu/core-submenu.html">
|
||||
<link rel="import" href="bower_components/core-item/core-item.html">
|
||||
|
||||
<link rel="import" href="domain-icon.html">
|
||||
|
||||
<polymer-element name="services-list" attributes="api cbServiceClicked">
|
||||
<template>
|
||||
<style>
|
||||
@ -22,7 +24,7 @@
|
||||
|
||||
<template if={{cbServiceClicked}}>
|
||||
<style>
|
||||
a {
|
||||
a, core-submenu {
|
||||
text-decoration: underline;
|
||||
cursor: pointer;
|
||||
}
|
||||
@ -33,7 +35,7 @@
|
||||
<core-menu selected="0">
|
||||
|
||||
<template repeat="{{serv in services}}">
|
||||
<core-submenu icon="settings" label="{{serv.domain}}">
|
||||
<core-submenu icon="{{serv.domain | getIcon}}" label="{{serv.domain}}">
|
||||
<template repeat="{{service in serv.services}}">
|
||||
<a on-click={{serviceClicked}} data-domain={{serv.domain}}>{{service}}</a>
|
||||
</template>
|
||||
@ -55,6 +57,10 @@
|
||||
this.api.addEventListener('services-updated', this.servicesUpdated.bind(this))
|
||||
},
|
||||
|
||||
getIcon: function(domain) {
|
||||
return (new DomainIcon).icon(domain);
|
||||
},
|
||||
|
||||
servicesUpdated: function() {
|
||||
this.services = this.api.services;
|
||||
},
|
||||
|
@ -64,11 +64,20 @@
|
||||
},
|
||||
|
||||
domReady: function() {
|
||||
document.getElementById('init').remove();
|
||||
|
||||
if(this.auth) {
|
||||
this.validatePassword();
|
||||
}
|
||||
},
|
||||
|
||||
authChanged: function(oldVal, newVal) {
|
||||
// log out functionality
|
||||
if(newVal == "" && this.state == "valid_auth") {
|
||||
this.state = "no_auth";
|
||||
}
|
||||
},
|
||||
|
||||
passwordKeyup: function(ev) {
|
||||
if(ev.keyCode == 13) {
|
||||
this.validatePassword();
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
<link rel="import" href="domain-icon.html">
|
||||
|
||||
<polymer-element name="state-badge" attributes="domain state">
|
||||
<polymer-element name="state-badge" attributes="stateObj" noscript>
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
@ -12,6 +12,7 @@
|
||||
color: white;
|
||||
border-radius: 23px;
|
||||
}
|
||||
|
||||
div {
|
||||
height: 45px;
|
||||
text-align: center;
|
||||
@ -23,12 +24,9 @@
|
||||
</style>
|
||||
|
||||
<div horizontal layout center>
|
||||
<domain-icon domain="{{domain}}"></domain-icon>
|
||||
<domain-icon domain="{{stateObj.domain}}" state="{{stateObj.state}}">
|
||||
</domain-icon>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
<script>
|
||||
Polymer({
|
||||
});
|
||||
</script>
|
||||
</polymer-element>
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="import" href="state-badge.html">
|
||||
|
||||
<polymer-element name="state-card"
|
||||
attributes="entity state last_changed state_attr cb_turn_on, cb_turn_off cb_edit">
|
||||
attributes="stateObj cb_turn_on, cb_turn_off cb_edit">
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
@ -79,44 +79,45 @@
|
||||
|
||||
<div class="entity">
|
||||
<state-badge
|
||||
id="badge"
|
||||
domain="{{domain}}"
|
||||
state="{{state}}"
|
||||
data-domain="{{domain}}"
|
||||
data-state="{{state}}"
|
||||
id="badge"
|
||||
stateObj="{{stateObj}}"
|
||||
data-domain="{{stateObj.domain}}"
|
||||
data-state="{{stateObj.state}}"
|
||||
on-click="{{editClicked}}">
|
||||
</state-badge>
|
||||
|
||||
<div class='info'>
|
||||
<div class='name'>
|
||||
<template if="{{state_attr['friendly_name']}}">{{state_attr['friendly_name']}}</template>
|
||||
<template if="{{!state_attr['friendly_name']}}">{{entity_id | makeReadable}}</template>
|
||||
<template if="{{state_attr['friendly_name']}}">
|
||||
{{state_attr['friendly_name']}}
|
||||
</template>
|
||||
<template if="{{!state_attr['friendly_name']}}">
|
||||
{{stateObj.entityDisplay}}
|
||||
</template>
|
||||
</div>
|
||||
|
||||
<div class="time-ago">
|
||||
<core-tooltip label="{{last_changed}}" position="bottom">
|
||||
{{last_changed_from_now}}
|
||||
{{lastChangedFromNow}}
|
||||
</core-tooltip>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<template if="{{!state_unknown}}">
|
||||
<template if="{{state == 'on' || state == 'off'}}">
|
||||
<template if="{{!stateUnknown}}">
|
||||
<template if="{{stateObj.state == 'on' || stateObj.state == 'off'}}">
|
||||
<div class='state toggle' self-center flex>
|
||||
<paper-toggle-button checked="{{toggleChecked}}">
|
||||
</paper-toggle-button>
|
||||
</div>
|
||||
</template>
|
||||
<template if="{{state != 'on' && state != 'off'}}">
|
||||
<div class='state text'>
|
||||
{{state | makeReadable}}
|
||||
</div>
|
||||
<template if="{{stateObj.state != 'on' && stateObj.state != 'off'}}">
|
||||
<div class='state text'>{{stateObj.stateDisplay}}</div>
|
||||
</template>
|
||||
</template>
|
||||
|
||||
<template if="{{state_unknown}}">
|
||||
<template if="{{stateUnknown}}">
|
||||
<div class="state" self-center flex>Updating..</div>
|
||||
</template>
|
||||
|
||||
@ -126,28 +127,20 @@
|
||||
<script>
|
||||
Polymer({
|
||||
// attributes
|
||||
entity: "",
|
||||
state: "",
|
||||
last_changed: "never",
|
||||
state_attr: {},
|
||||
stateObj: {},
|
||||
|
||||
cb_turn_on: null,
|
||||
cb_turn_off: null,
|
||||
cb_edit: null,
|
||||
state_unknown: false,
|
||||
stateUnknown: false,
|
||||
toggleChecked: -1,
|
||||
|
||||
computed: {
|
||||
domain: "entity | parseDomain",
|
||||
entity_id: "entity | parseEntityId",
|
||||
last_changed_from_now: "last_changed | parseLastChangedFromNow"
|
||||
lastChangedFromNow: "stateObj.last_changed | parseLastChangedFromNow",
|
||||
},
|
||||
|
||||
parseDomain: function(entity) {
|
||||
return entity.split('.')[0];
|
||||
},
|
||||
|
||||
parseEntityId: function(entity) {
|
||||
return entity.split('.')[1];
|
||||
observe: {
|
||||
'stateObj.state': 'stateChanged'
|
||||
},
|
||||
|
||||
parseLastChangedFromNow: function(lastChanged) {
|
||||
@ -160,24 +153,26 @@
|
||||
return;
|
||||
}
|
||||
|
||||
if(newVal && this.state == "off") {
|
||||
if(newVal && this.stateObj.state == "off") {
|
||||
this.turn_on();
|
||||
} else if(!newVal && this.state == "on") {
|
||||
} else if(!newVal && this.stateObj.state == "on") {
|
||||
this.turn_off();
|
||||
}
|
||||
},
|
||||
|
||||
stateChanged: function(oldVal, newVal) {
|
||||
this.state_unknown = newVal == null;
|
||||
this.stateUnknown = newVal == null;
|
||||
this.toggleChecked = newVal == "on"
|
||||
|
||||
// for domain light, set color of icon to light color if available
|
||||
if(this.domain == "light" && newVal == "on" &&
|
||||
this.state_attr.brightness && this.state_attr.xy_color) {
|
||||
var state = this.stateObj;
|
||||
|
||||
var rgb = this.xyBriToRgb(this.state_attr.xy_color[0],
|
||||
this.state_attr.xy_color[1],
|
||||
this.state_attr.brightness);
|
||||
// for domain light, set color of icon to light color if available
|
||||
if(state.domain == "light" && newVal == "on" &&
|
||||
state.attributes.brightness && state.attributes.xy_color) {
|
||||
|
||||
var rgb = this.xyBriToRgb(state.attributes.xy_color[0],
|
||||
state.attributes.xy_color[1],
|
||||
state.attributes.brightness);
|
||||
this.$.badge.style.color = "rgb(" + rgb.map(Math.floor).join(",") + ")";
|
||||
} else {
|
||||
this.$.badge.style.color = null;
|
||||
@ -186,11 +181,11 @@
|
||||
|
||||
turn_on: function() {
|
||||
if(this.cb_turn_on) {
|
||||
this.cb_turn_on(this.entity);
|
||||
this.cb_turn_on(this.stateObj.entity_id);
|
||||
|
||||
// unset state while we wait for an update
|
||||
var delayUnsetSate = function() {
|
||||
this.state = null;
|
||||
this.stateObj.state = null;
|
||||
}
|
||||
setTimeout(delayUnsetSate.bind(this), 500);
|
||||
}
|
||||
@ -198,11 +193,11 @@
|
||||
|
||||
turn_off: function() {
|
||||
if(this.cb_turn_off) {
|
||||
this.cb_turn_off(this.entity);
|
||||
this.cb_turn_off(this.stateObj.entity_id);
|
||||
|
||||
// unset state while we wait for an update
|
||||
var delayUnsetSate = function() {
|
||||
this.state = null;
|
||||
this.stateObj.state = null;
|
||||
}
|
||||
setTimeout(delayUnsetSate.bind(this), 500);
|
||||
}
|
||||
@ -210,20 +205,7 @@
|
||||
|
||||
editClicked: function() {
|
||||
if(this.cb_edit) {
|
||||
this.cb_edit(this.entity);
|
||||
}
|
||||
},
|
||||
|
||||
// used as filter
|
||||
makeReadable: function(value) {
|
||||
if(typeof value == "string") {
|
||||
return value.replace(/_/g, " ");
|
||||
|
||||
} else if(Array.isArray(value)) {
|
||||
return value.join(", ");
|
||||
|
||||
} else {
|
||||
return value;
|
||||
this.cb_edit(this.stateObj.entity_id);
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -24,10 +24,7 @@
|
||||
<div horizontal layout wrap>
|
||||
<template repeat="{{state in states}}">
|
||||
<state-card
|
||||
entity="{{state.entity_id}}"
|
||||
state="{{state.state}}"
|
||||
last_changed="{{state.last_changed}}"
|
||||
state_attr="{{state.attributes}}"
|
||||
stateObj="{{state}}"
|
||||
cb_turn_on="{{api.turn_on}}"
|
||||
cb_turn_off="{{api.turn_off}}"
|
||||
cb_edit={{editCallback}}>
|
||||
|
Loading…
x
Reference in New Issue
Block a user