Polymer .9: sidebar

pull/132/head
Paulus Schoutsen 2015-05-17 13:31:48 -07:00
parent 8d6bbb8c1a
commit 313eb71b17
7 changed files with 313 additions and 244 deletions

View File

@ -37,7 +37,6 @@
"core-tooltip": "Polymer/core-tooltip#~0.9",
"core-item": "Polymer/core-item#~0.9",
"core-style": "polymer/core-style#~0.9",
"core-label": "polymer/core-label#~0.9",
"paper-dropdown": "PolymerElements/paper-dropdown#~0.9",
"color-picker-element": "~0.0.2",
"google-apis": "GoogleWebComponents/google-apis#~0.4.4",

View File

@ -1,11 +1,11 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/core-icons/notification-icons.html">
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../bower_components/paper-toggle-button/paper-toggle-button.html">
<polymer-element name="stream-status">
<template>
<link rel="import" href="../bower_components/iron-icons/notification-icons.html">
<dom-module is="stream-status">
<style>
:host {
display: inline-block;
@ -16,29 +16,31 @@
vertical-align: middle;
}
</style>
<core-style ref='ha-paper-toggle'></core-style>
<core-icon icon="warning" hidden?="{{!hasError}}"></core-icon>
<paper-toggle-button id="toggle" on-change={{toggleChanged}} hidden?="{{hasError}}"></paper-toggle-button>
<template>
<iron-icon icon="warning" hidden$="{{!hasError}}"></iron-icon>
<paper-toggle-button id="toggle" on-change='toggleChanged' hidden$="{{hasError}}"></paper-toggle-button>
</template>
</dom-module>
<script>
var streamActions = window.hass.streamActions;
var authStore = window.hass.authStore;
var storeListenerMixIn = window.hass.storeListenerMixIn;
Polymer(Polymer.mixin({
isStreaming: false,
hasError: false,
Polymer({
is: 'stream-status',
icon: "swap-vert-circle",
color: 'red',
behaviors: [StoreListenerBehavior],
attached: function() {
this.listenToStores(true);
properties: {
isStreaming: {
type: Boolean,
value: false,
},
detached: function() {
this.stopListeningToStores();
hasError: {
type: Boolean,
value: false,
},
},
streamStoreChanged: function(streamStore) {
@ -53,6 +55,5 @@
streamActions.start(authStore.authToken);
}
},
}, storeListenerMixIn));
});
</script>
</polymer-element>

View File

@ -1,15 +1,16 @@
<link rel="import" href="bower_components/polymer/polymer.html">
<link rel="import" href="bower_components/font-roboto/roboto.html">
<link rel="import" href="resources/home-assistant-style.html">
<link rel="import" href="resources/home-assistant-js.html">
<link rel="import" href="resources/home-assistant-icons.html">
<link rel="import" href="resources/store-listener-behavior.html">
<link rel="import" href="layouts/login-form.html">
<!-- <link rel="import" href="layouts/home-assistant-main.html"> -->
<link rel="import" href="layouts/home-assistant-main.html">
<link rel="import" href="resources/home-assistant-style.html">
<dom-module id="home-assistant">
<style>
:host {
font-family: RobotoDraft, 'Helvetica Neue', Helvetica, Arial;
@ -17,14 +18,16 @@
}
</style>
<home-assistant-icons></home-assistant-icons>
<template>
<template is="dom-if" if="[[!loaded]]">
<login-form></login-form>
</template>
<!-- <home-assistant-main></home-assistant-main> -->
<template is="dom-if" if="[[loaded]]">
Hello HA
<home-assistant-main></home-assistant-main>
</template>
</template>

View File

@ -1,64 +1,47 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/layout/layout.html">
<link rel="import" href="../bower_components/core-drawer-panel/core-drawer-panel.html">
<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-menu/core-menu.html">
<link rel="import" href="../bower_components/core-style/core-style.html">
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/paper-drawer-panel/paper-drawer-panel.html">
<link rel="import" href="../bower_components/paper-header-panel/paper-header-panel.html">
<link rel="import" href="../bower_components/paper-toolbar/paper-toolbar.html">
<link rel="import" href="../bower_components/paper-menu/paper-menu.html">
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../bower_components/paper-item/paper-item.html">
<link rel="import" href="../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../layouts/partial-states.html">
<!-- <link rel="import" href="../layouts/partial-states.html">
<link rel="import" href="../layouts/partial-history.html">
<link rel="import" href="../layouts/partial-logbook.html">
<link rel="import" href="../layouts/partial-dev-fire-event.html">
<link rel="import" href="../layouts/partial-dev-call-service.html">
<link rel="import" href="../layouts/partial-dev-set-state.html">
<link rel="import" href="../layouts/partial-dev-set-state.html"> -->
<link rel="import" href="../components/ha-notifications.html">
<link rel="import" href="../components/ha-modals.html">
<!-- <link rel="import" href="../components/ha-notifications.html">
<link rel="import" href="../components/ha-modals.html"> -->
<link rel="import" href="../components/stream-status.html">
<polymer-element name="home-assistant-main">
<template>
<core-style ref="ha-headers"></core-style>
<dom-module is="home-assistant-main">
<style>
.sidenav {
background: #fafafa;
box-shadow: 1px 0 1px rgba(0, 0, 0, 0.1);
color: #757575;
overflow: hidden;
}
core-toolbar {
font-weight: normal;
padding-left: 24px;
.sidenav paper-menu {
--paper-menu-color: #757575;
}
.sidenav-menu {
overflow: auto;
position: absolute;
top: 0px;
left: 0px;
right: 0px;
bottom: 0px;
}
.sidenav-menu core-icon {
.sidenav iron-icon {
margin-right: 24px;
}
.sidenav-menu > paper-item {
min-height: 53px;
.divider {
border-top: 1px solid #e0e0e0;
}
.text {
padding: 16px;
border-top: 1px solid #e0e0e0;
}
.label {
font-size: 14px;
}
@ -67,126 +50,204 @@
}
</style>
<ha-notifications></ha-notifications>
<ha-modals></ha-modals>
<core-drawer-panel id="drawer" on-core-responsive-change="{{responsiveChanged}}">
<core-header-panel mode="scroll" drawer class='sidenav'>
<core-toolbar>
<template>
<!-- <ha-notifications></ha-notifications> -->
<!-- <ha-modals></ha-modals> -->
<paper-drawer-panel id="drawer" on-paper-responsive-change="responsiveChanged">
<paper-header-panel mode="scroll" drawer class='sidenav layout fit'>
<paper-toolbar>
Home Assistant
</core-toolbar>
<core-menu id="menu" class="sidenav-menu"
selected="0" excludedLocalNames="div" on-core-select="{{menuSelect}}"
layout vertical>
</paper-toolbar>
<paper-menu id="menu" class="layout vertical fit"
selectable="[data-panel]" attr-for-selected="data-panel"
on-iron-select="menuSelect" selected="[[selected]]">
<paper-item data-panel="states">
<core-icon icon="apps"></core-icon>
States
<iron-icon icon="apps"></iron-icon> States
</paper-item>
<template repeat="{{activeFilters as filter}}">
<paper-item data-panel="states_{{filter}}">
<core-icon icon="{{filter | filterIcon}}"></core-icon>
{{filter | filterName}}
<!--
Disabling because data-panel attribute not persisted in dom-repeat
<template is="dom-repeat" items="{{activeFilters}}">
<paper-item data-panel="[[filterType(item)]]">
<iron-icon icon="[[filterIcon(item)]]"></iron-icon>
<span>[[filterName(item)]]</span>
</paper-item>
</template>
-->
<template is="dom-if" if="[[hasGroupFilter(activeFilters)]]">
<paper-item data-panel="states_group">
<iron-icon icon="homeassistant-24:group"></iron-icon>
<span>Groups</span>
</paper-item>
</template>
<template if="{{hasHistoryComponent}}">
<template is="dom-if" if="[[hasScriptFilter(activeFilters)]]">
<paper-item data-panel="states_script">
<iron-icon icon="description"></iron-icon>
<span>Scripts</span>
</paper-item>
</template>
<template is="dom-if" if="[[hasSceneFilter(activeFilters)]]">
<paper-item data-panel="states_scene">
<iron-icon icon="social:pages"></iron-icon>
<span>Scenes</span>
</paper-item>
</template>
<!-- /TEMP WORK AROUND -->
<template is="dom-if" if="[[hasHistoryComponent]]">
<paper-item data-panel="history">
<core-icon icon="assessment"></core-icon>
<iron-icon icon="assessment"></iron-icon>
History
</paper-item>
</template>
<template if="{{hasLogbookComponent}}">
<template is="dom-if" if="[[hasLogbookComponent]]">
<paper-item data-panel="logbook">
<core-icon icon="list"></core-icon>
<iron-icon icon="list"></iron-icon>
Logbook
</paper-item>
</template>
<div flex></div>
<div class='flex'></div>
<paper-item on-click="{{handleLogOutClick}}">
<core-icon icon="exit-to-app"></core-icon>
<paper-item data-panel='logout'>
<iron-icon icon="exit-to-app"></iron-icon>
Log Out
</paper-item>
<div class='text' horizontal layout center>
<div flex>Streaming updates</div>
<paper-item class='divider horizontal layout justified'>
<div>Streaming updates</div>
<stream-status></stream-status>
</div>
</paper-item>
<div class='text label'>Developer Tools</div>
<div class='dev-tools' layout horizontal justified>
<div class='text label divider'>Developer Tools</div>
<div class='dev-tools layout horizontal justified'>
<paper-icon-button
icon="settings-remote" data-panel='call-service'
on-click="{{handleDevClick}}"></paper-icon-button>
on-click="handleDevClick"></paper-icon-button>
<paper-icon-button
icon="settings-ethernet" data-panel='set-state'
on-click="{{handleDevClick}}"></paper-icon-button>
on-click="handleDevClick"></paper-icon-button>
<paper-icon-button
icon="settings-input-antenna" data-panel='fire-event'
on-click="{{handleDevClick}}"></paper-icon-button>
on-click="handleDevClick"></paper-icon-button>
</div>
</core-menu>
</core-header-panel>
</paper-menu>
</paper-header-panel>
<!--
This is the main partial, never remove it from the DOM but hide it
to speed up when people click on states.
-->
<partial-states hidden?="{{hideStates}}"
<!-- <partial-states hidden?="{{hideStates}}"
main narrow="{{narrow}}"
togglePanel="{{togglePanel}}"
filter="{{stateFilter}}">
</partial-states>
<template if="{{selected == 'history'}}">
<template is='dom-if' if="{{selected == 'history'}}">
<partial-history main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-history>
</template>
<template if="{{selected == 'logbook'}}">
<template is='dom-if' if="{{selected == 'logbook'}}">
<partial-logbook main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-logbook>
</template>
<template if="{{selected == 'fire-event'}}">
<template is='dom-if' if="{{selected == 'fire-event'}}">
<partial-dev-fire-event main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-fire-event>
</template>
<template if="{{selected == 'set-state'}}">
<template is='dom-if' if="{{selected == 'set-state'}}">
<partial-dev-set-state main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-set-state>
</template>
<template if="{{selected == 'call-service'}}">
<template is='dom-if' if="{{selected == 'call-service'}}">
<partial-dev-call-service main narrow="{{narrow}}" togglePanel="{{togglePanel}}"></partial-dev-call-service>
</template>
</core-drawer-panel>
</template>-->
<div main>
<p>Selected: <span>[[selected]]</span></p>
<p>Narrow: <span>[[narrow]]</span></p>
</div>
</paper-drawer-panel>
</template>
</dom-module>
<script>
(function() {
var storeListenerMixIn = window.hass.storeListenerMixIn;
var authActions = window.hass.authActions;
var uiUtil = window.hass.uiUtil;
var uiConstants = window.hass.uiConstants;
Polymer(Polymer.mixin({
selected: "states",
stateFilter: null,
narrow: false,
activeFilters: [],
hasHistoryComponent: false,
hasLogbookComponent: false,
Polymer({
is: 'home-assistant-main',
isStreaming: false,
hasStreamError: false,
behaviors: [StoreListenerBehavior],
hideStates: false,
properties: {
selected: {
type: String,
value: 'states',
},
stateFilter: {
type: String,
value: null,
},
narrow: {
type: Boolean,
value: false,
},
activeFilters: {
type: Array,
value: [],
},
hasHistoryComponent: {
type: Boolean,
value: false,
},
hasLogbookComponent: {
type: Boolean,
value: false,
},
isStreaming: {
type: Boolean,
value: false,
},
hasStreamError: {
type: Boolean,
value: false,
},
hideStates: {
type: Boolean,
value: false,
},
hasGroupStates: {
type: Boolean,
computed: '',
}
},
listeners: {
'menu.core-select': 'menuSelect',
},
attached: function() {
this.togglePanel = this.togglePanel.bind(this);
this.listenToStores(true);
},
detached: function() {
this.stopListeningToStores();
},
stateStoreChanged: function(stateStore) {
@ -200,35 +261,32 @@ Polymer(Polymer.mixin({
this.hasLogbookComponent = componentStore.isLoaded('logbook');
},
streamStoreChanged: function(streamStore) {
this.isStreaming = streamStore.isStreaming;
this.hasStreamError = streamStore.hasError;
},
menuSelect: function(ev, detail, sender) {
if (detail.isSelected) {
this.selectPanel(detail.item);
}
this.selectPanel(this.$.menu.selected);
},
handleDevClick: function(ev, detail, sender) {
this.$.menu.selected = -1;
this.selectPanel(ev.target);
// prevent it from highlighting first menu item
document.activeElement.blur();
this.selectPanel(ev.target.parentElement.dataset.panel);
},
selectPanel: function(element) {
var newChoice = element.dataset.panel;
if(newChoice !== this.selected) {
this.togglePanel();
this.selected = newChoice;
selectPanel: function(newChoice) {
if (newChoice == 'logout') {
this.handleLogOut();
return;
} else if(newChoice == this.selected) {
return;
}
if (this.selected.substr(0, 7) === 'states_') {
this.togglePanel();
this.selected = newChoice;
if (newChoice.substr(0, 7) === 'states_') {
this.hideStates = false;
this.stateFilter = this.selected.substr(7);
this.stateFilter = newChoice.substr(7);
} else {
this.hideStates = this.selected !== 'states';
this.hideStates = newChoice !== 'states';
this.stateFilter = null;
}
},
@ -241,10 +299,25 @@ Polymer(Polymer.mixin({
this.$.drawer.togglePanel();
},
handleLogOutClick: function() {
handleLogOut: function() {
authActions.logOut();
},
// temporary work around for dom-repeat weirdness
hasGroupFilter: function(activeFilters) {
return activeFilters.indexOf('group') !== -1;
},
hasScriptFilter: function(activeFilters) {
return activeFilters.indexOf('script') !== -1;
},
hasSceneFilter: function(activeFilters) {
return activeFilters.indexOf('scene') !== -1;
},
// /temp work around
filterIcon: function(filter) {
return uiUtil.domainIcon(filter);
},
@ -252,7 +325,10 @@ Polymer(Polymer.mixin({
filterName: function(filter) {
return uiConstants.STATE_FILTERS[filter];
},
}, storeListenerMixIn));
filterType: function(filter) {
return 'states_' + filter;
}
});
})();
</script>
</polymer-element>

View File

@ -1,5 +1,4 @@
<link rel="import" href="../bower_components/polymer/polymer.html">
<link rel="import" href="../bower_components/layout/layout.html">
<!-- WIP <link rel="import" href="../bower_components/core-label/core-label.html"> -->

View File

@ -1,13 +1,13 @@
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/core-iconset-svg/core-iconset-svg.html">
<link rel="import" href="../bower_components/iron-icon/iron-icon.html">
<link rel="import" href="../bower_components/iron-iconset-svg/iron-iconset-svg.html">
<link rel="import" href="../bower_components/core-icon/core-icon.html">
<link rel="import" href="../bower_components/core-icons/social-icons.html">
<link rel="import" href="../bower_components/core-icons/image-icons.html">
<link rel="import" href="../bower_components/core-icons/hardware-icons.html">
<link rel="import" href="../bower_components/core-icons/av-icons.html">
<link rel="import" href="../bower_components/iron-icons/iron-icons.html">
<link rel="import" href="../bower_components/iron-icons/social-icons.html">
<link rel="import" href="../bower_components/iron-icons/image-icons.html">
<link rel="import" href="../bower_components/iron-icons/hardware-icons.html">
<link rel="import" href="../bower_components/iron-icons/av-icons.html">
<core-iconset-svg id="homeassistant-100" iconSize="100">
<iron-iconset-svg name="homeassistant-100" iconSize="100">
<svg><defs>
<g id="thermostat">
<!--
@ -16,9 +16,9 @@
-->
<path d="M66.861,60.105V17.453c0-9.06-7.347-16.405-16.408-16.405c-9.06,0-16.404,7.345-16.404,16.405v42.711 c-4.04,4.14-6.533,9.795-6.533,16.035c0,12.684,10.283,22.967,22.967,22.967c12.682,0,22.964-10.283,22.964-22.967 C73.447,69.933,70.933,64.254,66.861,60.105z M60.331,20.38h-13.21v6.536h6.63v6.539h-6.63v6.713h6.63v6.538h-6.63v6.5h6.63v6.536 h-6.63v7.218c-3.775,1.373-6.471,4.993-6.471,9.24h-6.626c0-5.396,2.598-10.182,6.61-13.185V17.446c0-0.038,0.004-0.075,0.004-0.111 l-0.004-0.007c0-5.437,4.411-9.846,9.849-9.846c5.438,0,9.848,4.409,9.848,9.846V20.38z"/></g>
</defs></svg>
</core-iconset-svg>
</iron-iconset-svg>
<core-iconset-svg id="homeassistant-24" iconSize="24">
<iron-iconset-svg name="homeassistant-24" iconSize="24">
<svg><defs>
<!--
Copyright (c) 2014 The Polymer Project Authors. All rights reserved.
@ -31,7 +31,7 @@
<g id="group"><path d="M9 12c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2zm5-3c0-1.1-.9-2-2-2s-2 .9-2 2 .9 2 2 2 2-.9 2-2zm-2-7c-5.52 0-10 4.48-10 10s4.48 10 10 10 10-4.48 10-10-4.48-10-10-10zm0 18c-4.42 0-8-3.58-8-8s3.58-8 8-8 8 3.58 8 8-3.58 8-8 8zm3-8c-1.1 0-2 .9-2 2s.9 2 2 2 2-.9 2-2-.9-2-2-2z"/></g>
</defs></svg>
</core-iconset-svg>
</iron-iconset-svg>
<script>
window.hass.uiUtil.domainIcon = function(domain, state) {
@ -90,5 +90,5 @@ window.hass.uiUtil.domainIcon = function(domain, state) {
default:
return "bookmark-outline";
}
}
};
</script>

View File

@ -1,31 +1,22 @@
<!-- <link rel="import" href="../bower_components/core-style/core-style.html"> -->
<link rel="import" href="../bower_components/polymer/polymer.html">
<style is="custom-style">
* {
--dark-primary-color: #0288D1;
--default-primary-color: #03A9F4;
--light-primary-color: #B3E5FC;
--text-primary-color: #ffffff;
--accent-color: #FF9800;
--primary-background-color: #ffffff;
--primary-text-color: #212121;
--secondary-text-color: #727272;
--disabled-text-color: #bdbdbd;
--divider-color: #B6B6B6;
--paper-toggle-button-checked-ink-color: #039be5;
--paper-toggle-button-checked-button-color: #039be5;
--paper-toggle-button-checked-bar-color: #039be5;
}
</style>