300 lines
7.6 KiB
HTML
300 lines
7.6 KiB
HTML
<link rel='import' href='../../bower_components/polymer/polymer.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-item/paper-icon-item.html'>
|
|
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
|
|
|
<link rel='import' href='../components/stream-status.html'>
|
|
|
|
<dom-module id='ha-sidebar'>
|
|
<template>
|
|
<style is="custom-style" include="iron-flex iron-flex-alignment iron-positioning"></style>
|
|
<style>
|
|
:host {
|
|
--sidebar-text: {
|
|
opacity: var(--dark-primary-opacity);
|
|
font-weight: 500;
|
|
font-size: 14px;
|
|
}
|
|
}
|
|
|
|
.sidenav {
|
|
-ms-user-select: none;
|
|
-webkit-user-select: none;
|
|
-moz-user-select: none;
|
|
}
|
|
|
|
paper-toolbar {
|
|
--paper-toolbar-title: {
|
|
text-align: left;
|
|
margin-left: 0px !important;
|
|
};
|
|
|
|
--paper-toolbar-background: #fff;
|
|
--paper-toolbar-color: #000;
|
|
opacity: var(--dark-primary-opacity);
|
|
border-bottom: 1px solid #e0e0e0;
|
|
}
|
|
|
|
paper-menu {
|
|
padding-bottom: 0;
|
|
}
|
|
|
|
paper-icon-item {
|
|
--paper-icon-item: {
|
|
cursor: pointer;
|
|
}
|
|
|
|
--paper-item-icon: {
|
|
color: #000;
|
|
opacity: var(--dark-secondary-opacity);
|
|
};
|
|
|
|
--paper-item-selected: {
|
|
color: var(--default-primary-color);
|
|
background-color: #e8e8e8;
|
|
opacity: 1;
|
|
}
|
|
}
|
|
paper-icon-item.iron-selected {
|
|
--paper-item-icon: {
|
|
color: var(--default-primary-color);
|
|
opacity: 1;
|
|
};
|
|
}
|
|
|
|
paper-icon-item .item-text {
|
|
@apply(--sidebar-text);
|
|
}
|
|
paper-icon-item.iron-selected .item-text {
|
|
opacity: 1;
|
|
}
|
|
|
|
paper-icon-item.logout {
|
|
margin-top: 16px;
|
|
}
|
|
|
|
.divider {
|
|
height: 1px;
|
|
background-color: #000;
|
|
margin: 4px 0;
|
|
opacity: var(--dark-divider-opacity)
|
|
}
|
|
|
|
.streaming {
|
|
@apply(--sidebar-text);
|
|
}
|
|
|
|
.subheader {
|
|
@apply(--sidebar-text);
|
|
padding: 16px;
|
|
}
|
|
|
|
.dev-tools {
|
|
padding: 0 8px;
|
|
opacity: var(--dark-secondary-opacity);
|
|
}
|
|
</style>
|
|
|
|
<paper-header-panel mode='scroll' class='sidenav fit'>
|
|
<paper-toolbar>
|
|
<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>
|
|
|
|
<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>
|
|
|
|
<paper-icon-item on-tap='menuClicked' data-panel='logout' class='logout'>
|
|
<iron-icon item-icon icon='mdi:exit-to-app'></iron-icon>
|
|
<span class='item-text'>Log Out</span>
|
|
</paper-icon-item>
|
|
</paper-menu>
|
|
|
|
<div>
|
|
<div class='divider'></div>
|
|
|
|
<paper-item class='horizontal layout justified'>
|
|
<div class='streaming'>Streaming updates</div>
|
|
<stream-status hass='[[hass]]'></stream-status>
|
|
</paper-item>
|
|
|
|
<div class='divider'></div>
|
|
|
|
<div class='subheader'>Developer Tools</div>
|
|
|
|
<div class='dev-tools layout horizontal justified'>
|
|
<paper-icon-button
|
|
icon='mdi:remote' data-panel='dev-service'
|
|
on-tap='menuClicked'></paper-icon-button>
|
|
<paper-icon-button
|
|
icon='mdi:code-tags' data-panel='dev-state'
|
|
on-tap='menuClicked'></paper-icon-button>
|
|
<paper-icon-button
|
|
icon='mdi:radio-tower' data-panel='dev-event'
|
|
on-tap='menuClicked'></paper-icon-button>
|
|
<paper-icon-button
|
|
icon='mdi:file-xml' data-panel='dev-template'
|
|
on-tap='menuClicked'></paper-icon-button>
|
|
<paper-icon-button
|
|
icon='mdi:information-outline' data-panel='dev-info'
|
|
on-tap='menuClicked'></paper-icon-button>
|
|
</div>
|
|
</div>
|
|
</paper-header-panel>
|
|
|
|
</template>
|
|
</dom-module>
|
|
|
|
<script>
|
|
Polymer({
|
|
is: 'ha-sidebar',
|
|
|
|
behaviors: [window.hassBehavior],
|
|
|
|
properties: {
|
|
hass: {
|
|
type: Object,
|
|
},
|
|
|
|
menuShown: {
|
|
type: Boolean,
|
|
},
|
|
|
|
menuSelected: {
|
|
type: String,
|
|
},
|
|
|
|
narrow: {
|
|
type: Boolean,
|
|
},
|
|
|
|
selected: {
|
|
type: String,
|
|
bindNuclear: function (hass) {
|
|
return hass.navigationGetters.activePane;
|
|
},
|
|
},
|
|
|
|
hasHistoryComponent: {
|
|
type: Boolean,
|
|
bindNuclear: function (hass) {
|
|
return hass.configGetters.isComponentLoaded('history');
|
|
},
|
|
},
|
|
|
|
hasLogbookComponent: {
|
|
type: Boolean,
|
|
bindNuclear: function (hass) {
|
|
return hass.configGetters.isComponentLoaded('logbook');
|
|
},
|
|
},
|
|
|
|
panels: {
|
|
type: Array,
|
|
bindNuclear: function (hass) {
|
|
return [
|
|
hass.panelGetters.panels,
|
|
function (res) { return res.toJS(); },
|
|
];
|
|
},
|
|
},
|
|
},
|
|
|
|
created: function () {
|
|
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);
|
|
},
|
|
|
|
menuClicked: function (ev) {
|
|
var target = ev.target;
|
|
var checks = 5;
|
|
var attr = target.getAttribute('data-panel');
|
|
|
|
// find panel to select
|
|
while (checks && !attr) {
|
|
target = target.parentElement;
|
|
attr = target.getAttribute('data-panel');
|
|
checks--;
|
|
}
|
|
|
|
if (checks) {
|
|
this.selectPanel(attr);
|
|
}
|
|
},
|
|
|
|
toggleMenu: function () {
|
|
this.fire('close-menu');
|
|
},
|
|
|
|
selectPanel: function (newChoice) {
|
|
if (newChoice === this.selected) {
|
|
return;
|
|
} else if (newChoice === 'logout') {
|
|
this.handleLogOut();
|
|
return;
|
|
}
|
|
this.hass.navigationActions.navigate.apply(null, newChoice.split('/'));
|
|
this.debounce('updateStyles', this._boundUpdateStyles, 1);
|
|
},
|
|
|
|
handleLogOut: function () {
|
|
this.hass.authActions.logOut();
|
|
},
|
|
});
|
|
</script>
|