Hass.io switch to tab navigation (#879)

* Hass.io switch to tab navigation

* Fixes

* Changes based on feedback

* Fix main

* move header back to main

* Remove space

* Navigation as suggested, replaced iron-pages
This commit is contained in:
c727 2018-02-23 01:26:29 +01:00 committed by GitHub
parent c149ac735a
commit 0ffb31999e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
10 changed files with 299 additions and 509 deletions

View File

@ -1,8 +1,4 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel='import' href='../../src/util/hass-mixins.html'> <link rel='import' href='../../src/util/hass-mixins.html'>
@ -12,46 +8,21 @@
<dom-module id="hassio-addon-store"> <dom-module id="hassio-addon-store">
<template> <template>
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
paper-card {
display: block;
}
.content {
padding: 24px 0 32px;
max-width: 600px;
margin: 0 auto;
}
hassio-addon-repository { hassio-addon-repository {
margin-top: 24px; margin-top: 24px;
} }
</style> </style>
<app-header-layout has-scrolling-region> <hassio-repositories-editor
<app-header slot="header" fixed> hass='[[hass]]'
<app-toolbar> repos='[[repos]]'
<paper-icon-button ></hassio-repositories-editor>
icon='mdi:arrow-left'
on-tap='backTapped'
></paper-icon-button>
<div main-title>Add-on store</div>
<paper-icon-button
icon="mdi:refresh"
on-tap="refreshTapped"
></paper-icon-button>
</app-toolbar>
</app-header>
<hassio-repositories-editor <template is='dom-repeat' items='[[repos]]' as='repo' sort='sortRepos'>
hass='[[hass]]' <hassio-addon-repository
repos='[[repos]]' repo='[[repo]]'
></hassio-repositories-editor> addons='[[computeAddons(repo.slug)]]'
></hassio-addon-repository>
<template is='dom-repeat' items='[[repos]]' as='repo' sort='sortRepos'> </template>
<hassio-addon-repository
repo='[[repo]]'
addons='[[computeAddons(repo.slug)]]'
></hassio-addon-repository>
</template>
</app-header-layout>
</template> </template>
</dom-module> </dom-module>
@ -64,10 +35,6 @@ class HassioAddonStore extends Polymer.Element {
hass: Object, hass: Object,
addons: Array, addons: Array,
repos: Array, repos: Array,
visible: {
type: Boolean,
observer: 'visibleChanged',
},
}; };
} }
@ -75,6 +42,7 @@ class HassioAddonStore extends Polymer.Element {
super.ready(); super.ready();
this.addEventListener('hass-api-called', ev => this.apiCalled(ev)); this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
this.addEventListener('hassio-store-refresh', ev => this.refreshData(ev)); this.addEventListener('hassio-store-refresh', ev => this.refreshData(ev));
this.loadData();
} }
apiCalled(ev) { apiCalled(ev) {
@ -102,12 +70,6 @@ class HassioAddonStore extends Polymer.Element {
}); });
} }
visibleChanged(visible) {
if (visible) {
this.loadData();
}
}
loadData() { loadData() {
this.hass.callApi('get', 'hassio/addons') this.hass.callApi('get', 'hassio/addons')
.then((info) => { .then((info) => {
@ -126,14 +88,6 @@ class HassioAddonStore extends Polymer.Element {
this.loadData(); this.loadData();
}); });
} }
refreshTapped() {
this.fire('hassio-store-refresh');
}
backTapped() {
history.back();
}
} }
customElements.define(HassioAddonStore.is, HassioAddonStore); customElements.define(HassioAddonStore.is, HassioAddonStore);

View File

@ -1,8 +1,12 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel='import' href='../../bower_components/polymer/polymer-element.html'>
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html"> <link rel='import' href='../../bower_components/app-route/app-route.html'>
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html"> <link rel='import' href='../../bower_components/app-layout/app-header-layout/app-header-layout.html'>
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html"> <link rel='import' href='../../bower_components/app-layout/app-header/app-header.html'>
<link rel="import" href="../../bower_components/app-route/app-route.html"> <link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
<link rel='import' href='../../src/components/ha-menu-button.html'>
<link rel='import' href='../../src/resources/ha-style.html'>
<link rel="import" href="./hassio-addon-info.html"> <link rel="import" href="./hassio-addon-info.html">
<link rel="import" href="./hassio-addon-config.html"> <link rel="import" href="./hassio-addon-config.html">
@ -30,16 +34,16 @@
active='{{routeMatches}}' active='{{routeMatches}}'
></app-route> ></app-route>
<app-header-layout has-scrolling-region> <app-header-layout has-scrolling-region>
<app-header slot="header" fixed> <app-header fixed slot='header'>
<app-toolbar> <app-toolbar>
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
<paper-icon-button <paper-icon-button
icon='mdi:arrow-left' icon='mdi:arrow-left'
on-tap='backTapped' on-tap='backTapped'
></paper-icon-button> ></paper-icon-button>
<div main-title>[[addon.name]]</div> <div main-title>Hass.io: add-on details</div>
</app-toolbar> </app-toolbar>
</app-header> </app-header>
<div class='content'> <div class='content'>
<hassio-addon-info <hassio-addon-info
hass='[[hass]]' hass='[[hass]]'
@ -79,6 +83,8 @@ class HassioAddonView extends Polymer.Element {
static get properties() { static get properties() {
return { return {
hass: Object, hass: Object,
showMenu: Boolean,
narrow: Boolean,
route: Object, route: Object,
routeData: { routeData: {
type: Object, type: Object,

View File

@ -1,11 +1,5 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html"> <link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../src/components/ha-menu-button.html">
<link rel="import" href="./hassio-host-info.html"> <link rel="import" href="./hassio-host-info.html">
<link rel="import" href="./hassio-hass-info.html"> <link rel="import" href="./hassio-hass-info.html">
@ -31,38 +25,26 @@
margin-right: 24px; margin-right: 24px;
} }
</style> </style>
<app-header-layout has-scrolling-region> <div class='content'>
<app-header slot="header" fixed> <div class='status'>
<app-toolbar> <hassio-supervisor-info
<paper-icon-button hass='[[hass]]'
icon='mdi:arrow-left' data='[[supervisorInfo]]'
on-tap='backTapped' ></hassio-supervisor-info>
></paper-icon-button>
<div main-title>Advanced Settings</div>
</app-toolbar>
</app-header>
<div class='content'> <hassio-host-info
<div class='status'> hass='[[hass]]'
<hassio-supervisor-info data='[[hostInfo]]'
hass='[[hass]]' ></hassio-host-info>
data='[[supervisorInfo]]'
></hassio-supervisor-info>
<hassio-host-info
hass='[[hass]]'
data='[[hostInfo]]'
></hassio-host-info>
</div>
<div class='status'>
<hassio-hass-info
hass='[[hass]]'
data='[[hassInfo]]'
></hassio-hass-info>
<div></div>
</div>
</div> </div>
</app-header-layout> <div class='status'>
<hassio-hass-info
hass='[[hass]]'
data='[[hassInfo]]'
></hassio-hass-info>
<div></div>
</div>
</div>
</template> </template>
</dom-module> </dom-module>
@ -72,30 +54,12 @@ class HassioAdvanced extends Polymer.Element {
static get properties() { static get properties() {
return { return {
hass: { hass: Object,
type: Object, supervisorInfo: Object,
}, hostInfo: Object,
hassInfo: Object,
supervisorInfo: {
type: Object,
value: {},
},
hostInfo: {
type: Object,
value: {},
},
hassInfo: {
type: Object,
value: {},
},
}; };
} }
backTapped() {
history.back();
}
} }
customElements.define(HassioAdvanced.is, HassioAdvanced); customElements.define(HassioAdvanced.is, HassioAdvanced);

View File

@ -1,17 +1,4 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../bower_components/paper-dropdown-menu/paper-dropdown-menu-light.html">
<link rel="import" href="../../bower_components/paper-listbox/paper-listbox.html">
<link rel="import" href="../../bower_components/paper-menu-button/paper-menu-button.html">
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
<link rel='import' href='../../src/util/hass-mixins.html'>
<link rel="import" href="../../src/components/ha-menu-button.html">
<link rel="import" href="./hassio-addons.html"> <link rel="import" href="./hassio-addons.html">
<link rel="import" href="./hassio-hass-update.html"> <link rel="import" href="./hassio-hass-update.html">
@ -22,65 +9,17 @@
.content { .content {
margin: 0 auto; margin: 0 auto;
} }
.status {
@apply(--layout-horizontal);
margin-bottom: 24px;
}
.status > * {
@apply(--layout-flex);
}
.status > *:first-child {
margin-right: 24px;
}
paper-listbox paper-item {
cursor: pointer;
}
</style> </style>
<app-header-layout has-scrolling-region> <div class='content'>
<app-header slot="header" fixed> <hassio-hass-update
<app-toolbar> hass='[[hass]]'
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button> hass-info='[[hassInfo]]'
<div main-title>Hass.io</div> ></hassio-hass-update>
<paper-icon-button <hassio-addons
icon="mdi:shopping" hass='[[hass]]'
on-tap="_openStore" addons='[[supervisorInfo.addons]]'
></paper-icon-button> ></hassio-addons>
<paper-menu-button </div>
no-animations
horizontal-align="right"
>
<paper-icon-button
icon="mdi:dots-vertical"
slot="dropdown-trigger"
></paper-icon-button>
<paper-listbox slot="dropdown-content">
<paper-item
on-tap='_restartHomeAssistant'
>Restart Home Assistant</paper-item>
<paper-item
on-tap='_openSnapshot'
>Snapshots</paper-item>
<paper-item
on-tap='_openAdvanced'
>Advanced Settings</paper-item>
</paper-listbox>
</paper-menu-button>
</app-toolbar>
</app-header>
<div class='content'>
<hassio-hass-update
hass='[[hass]]'
hass-info='[[hassInfo]]'
></hassio-hass-update>
<hassio-addons
hass='[[hass]]'
addons='[[supervisorInfo.addons]]'
></hassio-addons>
</div>
</app-header-layout>
</template> </template>
</dom-module> </dom-module>
@ -90,56 +29,11 @@ class HassioDashboard extends window.hassMixins.EventsMixin(Polymer.Element) {
static get properties() { static get properties() {
return { return {
hass: { hass: Object,
type: Object, supervisorInfo: Object,
}, hassInfo: Object,
narrow: {
type: Boolean,
},
showMenu: {
type: Boolean,
value: false,
},
supervisorInfo: {
type: Object,
value: {},
},
hassInfo: {
type: Object,
value: {},
},
}; };
} }
_openStore(ev) {
history.pushState(null, null, '/hassio/store');
this.fire('location-changed');
ev.target.blur();
}
_openAdvanced(ev) {
history.pushState(null, null, '/hassio/advanced');
this.fire('location-changed');
ev.target.blur();
}
_openSnapshot(ev) {
history.pushState(null, null, '/hassio/snapshot');
this.fire('location-changed');
ev.target.blur();
}
_restartHomeAssistant(ev) {
ev.target.blur();
// eslint-disable-next-line no-alert
if (confirm('Are you sure you want to restart Home Assistant?')) {
this.hass.callApi('POST', 'hassio/homeassistant/restart');
}
}
} }
customElements.define(HassioDashboard.is, HassioDashboard); customElements.define(HassioDashboard.is, HassioDashboard);

View File

@ -8,19 +8,16 @@ class HassioData extends Polymer.Element {
return { return {
supervisor: { supervisor: {
type: Object, type: Object,
value: {},
notify: true, notify: true,
}, },
host: { host: {
type: Object, type: Object,
value: {},
notify: true, notify: true,
}, },
homeassistant: { homeassistant: {
type: Object, type: Object,
value: {},
notify: true, notify: true,
}, },
}; };
@ -41,23 +38,23 @@ class HassioData extends Polymer.Element {
fetchSupervisorInfo() { fetchSupervisorInfo() {
return this.hass.callApi('get', 'hassio/supervisor/info') return this.hass.callApi('get', 'hassio/supervisor/info')
.then(function (info) { .then((info) => {
this.supervisor = info.data; this.supervisor = info.data;
}.bind(this)); });
} }
fetchHostInfo() { fetchHostInfo() {
return this.hass.callApi('get', 'hassio/host/info') return this.hass.callApi('get', 'hassio/host/info')
.then(function (info) { .then((info) => {
this.host = info.data; this.host = info.data;
}.bind(this)); });
} }
fetchHassInfo() { fetchHassInfo() {
return this.hass.callApi('get', 'hassio/homeassistant/info') return this.hass.callApi('get', 'hassio/homeassistant/info')
.then(function (info) { .then((info) => {
this.homeassistant = info.data; this.homeassistant = info.data;
}.bind(this)); });
} }
} }

View File

@ -1,33 +1,19 @@
<link rel="import" href="../bower_components/polymer/polymer-element.html"> <link rel="import" href="../bower_components/polymer/polymer-element.html">
<link rel="import" href="../bower_components/app-route/app-route.html"> <link rel="import" href="../bower_components/app-route/app-route.html">
<link rel="import" href="../bower_components/iron-pages/iron-pages.html">
<link rel="import" href="../src/layouts/hass-loading-screen.html"> <link rel="import" href="../src/layouts/hass-loading-screen.html">
<link rel="import" href="../src/layouts/hass-error-screen.html">
<link rel='import' href='../src/util/hass-mixins.html'>
<link rel='import' href='../src/util/hass-util.html'> <link rel='import' href='../src/util/hass-util.html'>
<link rel='import' href='../src/resources/ha-style.html'>
<link rel="import" href="./dashboard/hassio-dashboard.html"> <link rel='import' href='./hassio-data.html'>
<link rel="import" href="./advanced/hassio-advanced.html"> <link rel='import' href='./hassio-pages-with-tabs.html'>
<link rel="import" href="./addon-view/hassio-addon-view.html"> <link rel='import' href='./addon-view/hassio-addon-view.html'>
<link rel="import" href="./addon-store/hassio-addon-store.html">
<link rel="import" href="./supervisor/hassio-supervisor.html">
<link rel="import" href="./snapshots/hassio-snapshots.html">
<link rel="import" href="./hassio-data.html">
<dom-module id="hassio-main"> <dom-module id="hassio-main">
<template> <template>
<style>
iron-pages {
height: 100%;
}
</style>
<app-route <app-route
route='[[route]]' route='[[route]]'
pattern='/:page' pattern='/:page'
data="{{_routeData}}" data="{{routeData}}"
tail="{{_routeTail}}"
></app-route> ></app-route>
<hassio-data <hassio-data
id='data' id='data'
@ -43,59 +29,27 @@
show-menu='[[showMenu]]' show-menu='[[showMenu]]'
></hass-loading-screen> ></hass-loading-screen>
</template> </template>
<template is='dom-if' if='[[loaded]]'> <template is='dom-if' if='[[loaded]]'>
<iron-pages <template is='dom-if' if='[[!equalsAddon(routeData.page)]]'>
selected='[[_routeData.page]]' <hassio-pages-with-tabs
attr-for-selected='page-name'
fallback-selection='not-found'
selected-attribute='visible'
>
<hassio-addon-view
page-name='addon'
route='[[route]]'
hass='[[hass]]'
></hassio-addon-view>
<hassio-addon-store
page-name='store'
hass='[[hass]]'
></hassio-addon-store>
<hassio-supervisor
page-name='supervisor'
hass='[[hass]]'
supervisor-info='[[supervisorInfo]]'
></hassio-supervisor>
<hassio-dashboard
page-name='dashboard'
hass='[[hass]]' hass='[[hass]]'
narrow='[[narrow]]' narrow='[[narrow]]'
show-menu='[[showMenu]]' show-menu='[[showMenu]]'
page='[[routeData.page]]'
supervisor-info='[[supervisorInfo]]' supervisor-info='[[supervisorInfo]]'
hass-info='[[hassInfo]]' hass-info='[[hassInfo]]'
></hassio-dashboard>
<hassio-advanced
page-name='advanced'
hass='[[hass]]'
supervisor-info='[[supervisorInfo]]'
host-info='[[hostInfo]]' host-info='[[hostInfo]]'
hass-info='[[hassInfo]]' ></hassio-pages-with-tabs>
></hassio-advanced> </template>
<template is='dom-if' if='[[equalsAddon(routeData.page)]]'>
<hassio-snapshots <hassio-addon-view
page-name='snapshot'
hass='[[hass]]' hass='[[hass]]'
installed-addons='[[supervisorInfo.addons]]' narrow='[[narrow]]'
></hassio-snapshots> show-menu='[[showMenu]]'
route='[[route]]'
<hass-error-screen ></hassio-addon-view>
page-name='not-found' </template>
error='Page not found.'
title='Hass.io'
></hass-error-screen>
</iron-pages>
</template> </template>
</template> </template>
</dom-module> </dom-module>
@ -117,34 +71,15 @@ class HassioMain extends window.hassMixins.EventsMixin(Polymer.Element) {
path: '/dashboard', path: '/dashboard',
__queryParams: {} __queryParams: {}
}, },
observer: '_routeChanged', observer: 'routeChanged',
}, },
_routeData: Object, routeData: Object,
_routeTail: Object, supervisorInfo: Object,
hostInfo: Object,
addon: { hassInfo: Object,
type: String,
value: '',
},
supervisorInfo: {
type: Object,
value: null,
},
hostInfo: {
type: Object,
value: null,
},
hassInfo: {
type: Object,
value: null,
},
loaded: { loaded: {
type: Boolean, type: Boolean,
computed: '_computeIsLoaded(supervisorInfo, hostInfo, hassInfo)', computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo)',
}, },
}; };
} }
@ -152,41 +87,45 @@ class HassioMain extends window.hassMixins.EventsMixin(Polymer.Element) {
ready() { ready() {
super.ready(); super.ready();
window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true); window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
this.addEventListener('hass-api-called', ev => this._apiCalled(ev)); this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
} }
connectedCallback() { connectedCallback() {
super.connectedCallback(); super.connectedCallback();
this._routeChanged(this.route); this.routeChanged(this.route);
} }
_apiCalled(ev) { apiCalled(ev) {
if (ev.detail.success) { if (ev.detail.success) {
var tries = 1; let tries = 1;
var tryUpdate = function () { const tryUpdate = () => {
this.$.data.refresh().catch(function () { this.$.data.refresh().catch(function () {
tries += 1; tries += 1;
setTimeout(tryUpdate, Math.min(tries, 5) * 1000); setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
}); });
}.bind(this); };
tryUpdate(); tryUpdate();
} }
} }
_computeIsLoaded(supervisorInfo, hostInfo, hassInfo) { computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
return (supervisorInfo !== null && return (supervisorInfo !== null &&
hostInfo !== null && hostInfo !== null &&
hassInfo !== null); hassInfo !== null);
} }
_routeChanged(route) { routeChanged(route) {
if (route.path === '' && route.prefix === '/hassio') { if (route.path === '' && route.prefix === '/hassio') {
history.replaceState(null, null, '/hassio/dashboard'); history.replaceState(null, null, '/hassio/dashboard');
this.fire('location-changed'); this.fire('location-changed');
} }
} }
equalsAddon(page) {
return page && page === 'addon';
}
} }
customElements.define(HassioMain.is, HassioMain); customElements.define(HassioMain.is, HassioMain);

View File

@ -0,0 +1,103 @@
<link rel='import' href='../bower_components/polymer/polymer-element.html'>
<link rel='import' href='../bower_components/app-layout/app-header-layout/app-header-layout.html'>
<link rel='import' href='../bower_components/app-layout/app-header/app-header.html'>
<link rel='import' href='../bower_components/app-layout/app-toolbar/app-toolbar.html'>
<link rel='import' href='../bower_components/paper-tabs/paper-tabs.html'>
<link rel='import' href='../bower_components/paper-tabs/paper-tab.html'>
<link rel='import' href='../src/components/ha-menu-button.html'>
<link rel='import' href='../src/util/hass-mixins.html'>
<link rel='import' href='../src/resources/ha-style.html'>
<link rel='import' href='./dashboard/hassio-dashboard.html'>
<link rel='import' href='./snapshots/hassio-snapshots.html'>
<link rel='import' href='./addon-store/hassio-addon-store.html'>
<link rel='import' href='./system/hassio-system.html'>
<dom-module id='hassio-pages-with-tabs'>
<template>
<style include='iron-flex iron-positioning ha-style'>
paper-tabs {
margin-left: 12px;
--paper-tabs-selection-bar-color: #FFF;
text-transform: uppercase;
}
</style>
<app-header-layout has-scrolling-region>
<app-header fixed slot='header'>
<app-toolbar>
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
<div main-title>Hass.io</div>
</app-toolbar>
<paper-tabs
scrollable
selected='[[page]]'
attr-for-selected='page-name'
on-iron-activate='handlePageSelected'
>
<paper-tab page-name='dashboard'>Dashboard</paper-tab>
<paper-tab page-name='snapshots'>Snapshots</paper-tab>
<paper-tab page-name='store'>Add-on store</paper-tab>
<paper-tab page-name='system'>System</paper-tab>
</paper-tabs>
</app-header>
<template is='dom-if' if='[[equals(page, "dashboard")]]'>
<hassio-dashboard
hass='[[hass]]'
supervisor-info='[[supervisorInfo]]'
hass-info='[[hassInfo]]'
></hassio-dashboard>
</template>
<template is='dom-if' if='[[equals(page, "snapshots")]]'>
<hassio-snapshots
hass='[[hass]]'
installed-addons='[[supervisorInfo.addons]]'
></hassio-snapshots>
</template>
<template is='dom-if' if='[[equals(page, "store")]]'>
<hassio-addon-store
hass='[[hass]]'
></hassio-addon-store>
</template>
<template is='dom-if' if='[[equals(page, "system")]]'>
<hassio-system
hass='[[hass]]'
supervisor-info='[[supervisorInfo]]'
host-info='[[hostInfo]]'
hass-info='[[hassInfo]]'
></hassio-system>
</template>
</app-header-layout>
</template>
</dom-module>
<script>
class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(Polymer.Element) {
static get is() { return 'hassio-pages-with-tabs'; }
static get properties() {
return {
hass: Object,
showMenu: Boolean,
narrow: Boolean,
page: String,
supervisorInfo: Object,
hostInfo: Object,
hassInfo: Object,
};
}
handlePageSelected(ev) {
const newPage = ev.detail.item.getAttribute('page-name');
if (newPage !== this.page) {
this.navigate(`/hassio/${newPage}`);
}
}
equals(a, b) {
return a === b;
}
}
customElements.define(HassioPagesWithTabs.is, HassioPagesWithTabs);
</script>

View File

@ -31,7 +31,7 @@
} }
} }
</style> </style>
<paper-dialog id='dialog' with-backdrop on-iron-overlay-closed='dialogClosed'> <paper-dialog id='dialog' on-iron-overlay-closed='dialogClosed'>
<h2>[[computeName(snapshot)]]</h2> <h2>[[computeName(snapshot)]]</h2>
<div> <div>
<div class='snapshot-details'> <div class='snapshot-details'>

View File

@ -1,8 +1,4 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../bower_components/paper-card/paper-card.html"> <link rel="import" href="../../bower_components/paper-card/paper-card.html">
<link rel="import" href="../../bower_components/paper-button/paper-button.html"> <link rel="import" href="../../bower_components/paper-button/paper-button.html">
<link rel="import" href="../../bower_components/paper-input/paper-input.html"> <link rel="import" href="../../bower_components/paper-input/paper-input.html">
@ -30,92 +26,76 @@
display: none; display: none;
} }
</style> </style>
<app-header-layout has-scrolling-region> <div class='content'>
<app-header slot="header" fixed> <div class='card-group'>
<app-toolbar> <div class='title'>
<paper-icon-button New snapshot
icon='mdi:arrow-left' <div class='description'>
on-tap='_backTapped' Snapshots allow you to easily backup and
></paper-icon-button> restore all data of your Hass.io instance.
<div main-title>Snapshots</div>
<paper-icon-button
icon="mdi:refresh"
on-tap="_refreshTapped"
></paper-icon-button>
</app-toolbar>
</app-header>
<div class='content'>
<div class='card-group'>
<div class='title'>
New snapshot
<div class='description'>
Snapshots allow you to easily backup and
restore all data of your Hass.io instance.
</div>
</div> </div>
<paper-card> </div>
<div class='card-content'> <paper-card>
<paper-input autofocus label='Name' value='{{snapshotName}}'> <div class='card-content'>
</paper-input> <paper-input autofocus label='Name' value='{{snapshotName}}'>
<label id='lbltype'>Type:</label> </paper-input>
<paper-radio-group selected='{{snapshotType}}' aria-labelledby='lbltype' on-paper-radio-group-changed='typeChanged'> <label id='lbltype'>Type:</label>
<paper-radio-button name='full'> <paper-radio-group selected='{{snapshotType}}' aria-labelledby='lbltype' on-paper-radio-group-changed='typeChanged'>
Full snapshot <paper-radio-button name='full'>
</paper-radio-button> Full snapshot
<paper-radio-button name='partial'> </paper-radio-button>
Partial snapshot <paper-radio-button name='partial'>
</paper-radio-button> Partial snapshot
</paper-radio-group> </paper-radio-button>
<div id='folders' class='hidden'> </paper-radio-group>
Folders: <div id='folders' class='hidden'>
<template is='dom-repeat' items='[[folderList]]'> Folders:
<paper-checkbox checked='{{item.checked}}'> <template is='dom-repeat' items='[[folderList]]'>
[[item.name]] <paper-checkbox checked='{{item.checked}}'>
</paper-checkbox> [[item.name]]
</template> </paper-checkbox>
</div>
<div id='addons' class='hidden'>
Add-ons:
<template is='dom-repeat' items='[[addonList]]' sort='sortAddons'>
<paper-checkbox checked='{{item.checked}}'>
[[item.name]]
</paper-checkbox>
</template>
</div>
</div>
<div class='card-actions'>
<paper-button disabled='[[creatingSnapshot]]' on-tap='createSnapshot'>Create</paper-button>
<template is='dom-if' if='[[error]]'>
<p class='error'>[[error]]</p>
</template> </template>
</div> </div>
</paper-card> <div id='addons' class='hidden'>
</div> Add-ons:
<template is='dom-repeat' items='[[addonList]]' sort='sortAddons'>
<div class='card-group'> <paper-checkbox checked='{{item.checked}}'>
<div class='title'>Available snapshots</div> [[item.name]]
<template is='dom-if' if='[[!snapshots.length]]'> </paper-checkbox>
<paper-card> </template>
<div class='card-content'>You don't have any snapshots yet.</div> </div>
</paper-card> </div>
</template> <div class='card-actions'>
<template is='dom-repeat' items='[[snapshots]]' as='snapshot' sort='sortSnapshots'> <paper-button disabled='[[creatingSnapshot]]' on-tap='createSnapshot'>Create</paper-button>
<paper-card class='pointer' on-click='snapshotTapped'> <template is='dom-if' if='[[error]]'>
<div class='card-content'> <p class='error'>[[error]]</p>
<hassio-card-content </template>
title='[[computeName(snapshot)]]' </div>
description='[[computeType(snapshot.type)]]' </paper-card>
datetime='[[snapshot.date]]+00:00'
icon='[[computeIcon(snapshot.type)]]'
icon-class='snapshot'
></hassio-card-content>
</div>
</paper-card>
</template>
</div>
</div> </div>
</app-header-layout>
<div class='card-group'>
<div class='title'>Available snapshots</div>
<template is='dom-if' if='[[!snapshots.length]]'>
<paper-card>
<div class='card-content'>You don't have any snapshots yet.</div>
</paper-card>
</template>
<template is='dom-repeat' items='[[snapshots]]' as='snapshot' sort='sortSnapshots'>
<paper-card class='pointer' on-click='snapshotTapped'>
<div class='card-content'>
<hassio-card-content
title='[[computeName(snapshot)]]'
description='[[computeType(snapshot.type)]]'
datetime='[[snapshot.date]]+00:00'
icon='[[computeIcon(snapshot.type)]]'
icon-class='snapshot'
></hassio-card-content>
</div>
</paper-card>
</template>
</div>
</div>
<hassio-snapshot <hassio-snapshot
hass='[[hass]]' hass='[[hass]]'
snapshot-slug='[[selectedSnapshot]]' snapshot-slug='[[selectedSnapshot]]'
@ -132,10 +112,6 @@ class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
static get properties() { static get properties() {
return { return {
hass: Object, hass: Object,
visible: {
type: Boolean,
observer: 'visibleChanged',
},
snapshotName: String, snapshotName: String,
snapshotType: { snapshotType: {
type: String, type: String,
@ -173,12 +149,7 @@ class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
ready() { ready() {
super.ready(); super.ready();
this.addEventListener('hass-api-called', ev => this.apiCalled(ev)); this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
} this.updateSnapshots();
visibleChanged(visible) {
if (visible) {
this.updateSnapshots();
}
} }
apiCalled(ev) { apiCalled(ev) {
@ -274,17 +245,6 @@ class HassioSnapshots extends window.hassMixins.EventsMixin(Polymer.Element) {
this.updateOverview = false; this.updateOverview = false;
} }
} }
backTapped() {
history.back();
}
refreshTapped() {
this.hass.callApi('post', 'hassio/snapshots/reload')
.then(() => {
this.updateSnapshots();
});
}
} }
customElements.define(HassioSnapshots.is, HassioSnapshots); customElements.define(HassioSnapshots.is, HassioSnapshots);

View File

@ -1,11 +1,6 @@
<link rel="import" href="../../bower_components/polymer/polymer-element.html"> <link rel="import" href="../../bower_components/polymer/polymer-element.html">
<link rel="import" href="../../bower_components/app-layout/app-header-layout/app-header-layout.html">
<link rel="import" href="../../bower_components/app-layout/app-header/app-header.html">
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
<link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html"> <link rel="import" href="../../bower_components/paper-icon-button/paper-icon-button.html">
<link rel="import" href="../../src/components/ha-menu-button.html">
<dom-module id="hassio-supervisor"> <dom-module id="hassio-supervisor">
<template> <template>
<style include="iron-flex ha-style"> <style include="iron-flex ha-style">
@ -14,24 +9,18 @@
margin: 0; margin: 0;
white-space: pre-wrap; white-space: pre-wrap;
} }
paper-icon-button {
color: var(--primary-color);
position: sticky;
top: 0;
float: right;
}
</style> </style>
<app-header-layout has-scrolling-region> <paper-icon-button
<app-header slot="header" fixed> icon='mdi:refresh'
<app-toolbar> on-tap='refreshTapped'
<paper-icon-button ></paper-icon-button>
icon='mdi:arrow-left' <pre class='content'>[[log]]</pre>
on-tap='_backTapped'
></paper-icon-button>
<div main-title>Supervisor Logs</div>
<paper-icon-button
icon="mdi:refresh"
on-tap="_refreshTapped"
></paper-icon-button>
</app-toolbar>
</app-header>
<pre class='content'>[[logs]]</pre>
</app-header-layout>
</template> </template>
</dom-module> </dom-module>
@ -41,43 +30,27 @@ class HassioSupervisor extends Polymer.Element {
static get properties() { static get properties() {
return { return {
hass: { hass: Object,
type: Object, log: String,
},
visible: {
type: Boolean,
observer: '_visibleChanged',
},
logs: {
type: String,
value: '',
},
}; };
} }
_visibleChanged(visible) { ready() {
if (visible) { super.ready();
this._loadData(); this.loadData();
}
} }
_loadData() { loadData() {
this.hass.callApi('get', 'hassio/supervisor/logs') this.hass.callApi('get', 'hassio/supervisor/logs')
.then(function (info) { .then((info) => {
this.logs = info; this.log = info;
}.bind(this), function () { }, () => {
this.logs = 'Error fetching logs'; this.log = 'Error fetching logs';
}.bind(this)); });
} }
_refreshTapped() { refreshTapped() {
this._loadData(); this.loadData();
}
_backTapped() {
history.back();
} }
} }