mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 20:36:35 +00:00
Add HassIO panel (#267)
* Add HassIO panel * Add buttons * Update to new API * Add initial hassio addon view * Allow saving options * Not auto select smb_config addon * Add logs to addon * Add OS info to host * Wrap up panel for now * Lint * Fix menu button
This commit is contained in:
parent
4b38a16848
commit
863ccb5486
@ -10,7 +10,7 @@
|
||||
<link rel="import" href="../../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<link rel="import" href="../../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../../src/components/ha-call-service-button.html">
|
||||
<link rel="import" href="../../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../../src/resources/ha-style.html">
|
||||
|
||||
<link rel="import" href="../ha-config-section.html">
|
||||
@ -46,10 +46,6 @@
|
||||
.validate-log {
|
||||
white-space: pre-wrap;
|
||||
}
|
||||
|
||||
.card-actions.warning ha-call-service-button {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
</style>
|
||||
<ha-config-section
|
||||
is-wide='[[isWide]]'
|
||||
@ -120,11 +116,13 @@
|
||||
</div>
|
||||
<div class='card-actions warning'>
|
||||
<ha-call-service-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
domain='homeassistant'
|
||||
service='restart'
|
||||
>Restart</ha-call-service-button>
|
||||
<ha-call-service-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
domain='homeassistant'
|
||||
service='stop'
|
||||
|
120
panels/hassio/ha-panel-hassio.html
Normal file
120
panels/hassio/ha-panel-hassio.html
Normal file
@ -0,0 +1,120 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
|
||||
<link rel="import" href="./hassio-dashboard.html">
|
||||
<link rel="import" href="./hassio-addon-view.html">
|
||||
<link rel="import" href="./hassio-loading.html">
|
||||
|
||||
<dom-module id="ha-panel-hassio">
|
||||
<style>
|
||||
iron-pages {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<hassio-data
|
||||
hass='[[hass]]'
|
||||
supervisor='{{supervisorInfo}}'
|
||||
homeassistant='{{hassInfo}}'
|
||||
host='{{hostInfo}}'
|
||||
></hassio-data>
|
||||
|
||||
<template is='dom-if' if='[[!loaded]]'>
|
||||
<hassio-loading
|
||||
narrow='[[narrow]]'
|
||||
hass='[[hass]]'
|
||||
show-menu='[[showMenu]]'
|
||||
></hassio-loading>
|
||||
</template>
|
||||
<template is='dom-if' if='[[loaded]]' restamp>
|
||||
<template is='dom-if' if='[[addon]]'>
|
||||
<hassio-addon-view
|
||||
hass='[[hass]]'
|
||||
supervisor-info='[[supervisorInfo]]'
|
||||
host-info='[[hostInfo]]'
|
||||
addon='[[addon]]'
|
||||
></hassio-addon-view>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[!addon]]'>
|
||||
<hassio-dashboard
|
||||
hass='[[hass]]'
|
||||
narrow='[[narrow]]'
|
||||
show-menu='[[showMenu]]'
|
||||
supervisor-info='{{supervisorInfo}}'
|
||||
host-info='{{hostInfo}}'
|
||||
hass-info='[[hassInfo]]'
|
||||
></hassio-dashboard>
|
||||
</template>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'ha-panel-hassio',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
addon: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
|
||||
supervisorInfo: {
|
||||
type: Object,
|
||||
value: null,
|
||||
},
|
||||
|
||||
hostInfo: {
|
||||
type: Object,
|
||||
value: null,
|
||||
},
|
||||
|
||||
hassInfo: {
|
||||
type: Object,
|
||||
value: null,
|
||||
},
|
||||
|
||||
forceLoading: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
loaded: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo, forceLoading)',
|
||||
}
|
||||
},
|
||||
|
||||
listeners: {
|
||||
'hassio-select-addon': 'addonSelected',
|
||||
},
|
||||
|
||||
computeIsLoaded: function (supervisorInfo, hostInfo, hassInfo, forceLoading) {
|
||||
return (supervisorInfo !== null &&
|
||||
hostInfo !== null &&
|
||||
hassInfo !== null &&
|
||||
!forceLoading);
|
||||
},
|
||||
|
||||
addonSelected: function (ev) {
|
||||
this.forceLoading = true;
|
||||
setTimeout(function () {
|
||||
this.addon = ev.detail.addon;
|
||||
this.forceLoading = false;
|
||||
}.bind(this), 0);
|
||||
},
|
||||
});
|
||||
</script>
|
328
panels/hassio/hassio-addon-view.html
Normal file
328
panels/hassio/hassio-addon-view.html
Normal file
@ -0,0 +1,328 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.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-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
<link rel="import" href="../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
|
||||
<link rel="import" href="./hassio-data.html">
|
||||
<link rel="import" href="./hassio-host-info.html">
|
||||
<link rel="import" href="./hassio-supervisor-info.html">
|
||||
<link rel="import" href="./hassio-addons.html">
|
||||
|
||||
<dom-module id="hassio-addon-view">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
.controls paper-card {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
.content {
|
||||
padding: 24px 0 32px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.status {
|
||||
@apply(--layout-horizontal);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.status > * {
|
||||
@apply(--layout-flex);
|
||||
}
|
||||
.status > *:first-child {
|
||||
margin-right: 24px;
|
||||
}
|
||||
</style>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header fixed>
|
||||
<app-toolbar>
|
||||
<paper-icon-button
|
||||
icon='mdi:arrow-left'
|
||||
on-tap='backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[addonInfo.name]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class='content'>
|
||||
<div class='status'>
|
||||
<paper-card heading='Info'>
|
||||
<div class="card-content">
|
||||
<div>[[addonInfo.description]]</div>
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<td>Installed</td>
|
||||
<td>[[computeInstallStatus(addonInfo)]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>[[addonInfo.version]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Dedicated</td>
|
||||
<td>[[addonInfo.dedicated]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<template is='dom-if' if='[[!addonState]]'>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[pathInstall(addon)]]"
|
||||
>Install</ha-call-api-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
|
||||
<paper-card heading='Installed'>
|
||||
<template is='dom-if' if='[[!addonState]]'>
|
||||
<div class="card-content">
|
||||
<div>Add-on is not installed.</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<template is='dom-if' if='[[addonState]]'>
|
||||
<div class="card-content">
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>[[addonState.version]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>State</td>
|
||||
<td>[[addonState.state]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Boot</td>
|
||||
<td>[[addonState.boot]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<template is='dom-if' if='[[!isRunning]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[pathStart(addon)]]"
|
||||
>Start</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(addonInfo)]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[pathUpdate(addon)]]"
|
||||
>Update</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[isRunning]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[pathStop(addon)]]"
|
||||
>Stop</ha-call-api-button>
|
||||
</template>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[pathUninstall(addon)]]"
|
||||
>Uninstall</ha-call-api-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</div>
|
||||
|
||||
<template is='dom-if' if='[[addonState]]'>
|
||||
<div class='controls'>
|
||||
<paper-card heading='Options'>
|
||||
<div class="card-content">
|
||||
<iron-autogrow-textarea value="{{options}}"></iron-autogrow-textarea>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
disabled='[[!optionsParsed]]'
|
||||
data='[[computeOptionsData(optionsParsed)]]'
|
||||
path="[[pathOptions(addon)]]"
|
||||
>Save</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
|
||||
<paper-card heading='Logs'>
|
||||
<div class="card-content">
|
||||
<pre>[[addonLogs]]</pre>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button on-tap='refreshLogs'>Refresh</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-addon-view',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
addon: {
|
||||
type: String,
|
||||
observer: 'addonChanged',
|
||||
},
|
||||
|
||||
options: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
|
||||
optionsParsed: {
|
||||
type: Object,
|
||||
computed: 'parseOptions(options)',
|
||||
},
|
||||
|
||||
supervisorInfo: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
hostInfo: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
isRunning: {
|
||||
type: Boolean,
|
||||
computed: 'computeIsRunning(addonState)',
|
||||
},
|
||||
|
||||
addonInfo: {
|
||||
type: Object,
|
||||
computed: 'computeAddonInfo(supervisorInfo, addon)',
|
||||
},
|
||||
|
||||
addonState: {
|
||||
type: Object,
|
||||
value: null,
|
||||
observer: 'addonStateChanged',
|
||||
},
|
||||
|
||||
addonLogs: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
},
|
||||
|
||||
addonChanged: function (addon) {
|
||||
if (!this.hass) {
|
||||
setTimeout(function () { this.addonChanged(addon); }.bind(this), 0);
|
||||
return;
|
||||
}
|
||||
|
||||
this.hass.callApi('get', 'hassio/addons/' + addon + '/info')
|
||||
.then(function (info) {
|
||||
// Error if addon not installed.
|
||||
if (info.result !== 'error') {
|
||||
this.addonState = info.data;
|
||||
}
|
||||
}.bind(this));
|
||||
this.refreshLogs();
|
||||
},
|
||||
|
||||
refreshLogs: function () {
|
||||
this.hass.callApi('get', 'hassio/addons/' + this.addon + '/logs')
|
||||
.then(function (info) {
|
||||
this.addonLogs = info;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
addonStateChanged: function (addonState) {
|
||||
this.options = addonState ? JSON.stringify(addonState.options, null, 2) : '';
|
||||
},
|
||||
|
||||
computeAddonInfo: function (supervisorInfo, addon) {
|
||||
if (!supervisorInfo) return null;
|
||||
|
||||
for (var i = 0; i < supervisorInfo.addons.length; i++) {
|
||||
var addonInfo = supervisorInfo.addons[i];
|
||||
if (addonInfo.slug === addon) return addonInfo;
|
||||
}
|
||||
return null;
|
||||
},
|
||||
|
||||
computeIsRunning: function (addonState) {
|
||||
return addonState && addonState.state === 'started';
|
||||
},
|
||||
|
||||
computeInstallStatus(addon) {
|
||||
return addon.installed || 'Not installed';
|
||||
},
|
||||
|
||||
computeUpdateAvailable: function (data) {
|
||||
return data.version !== data.last_version;
|
||||
},
|
||||
|
||||
parseOptions: function (options) {
|
||||
try {
|
||||
return JSON.parse(options);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
},
|
||||
|
||||
computeOptionsData: function (optionsParsed) {
|
||||
return {
|
||||
options: optionsParsed,
|
||||
};
|
||||
},
|
||||
|
||||
backTapped: function () {
|
||||
this.fire('hassio-select-addon', { addon: null });
|
||||
},
|
||||
|
||||
pathStart: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/start';
|
||||
},
|
||||
|
||||
pathStop: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/stop';
|
||||
},
|
||||
|
||||
pathInstall: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/install';
|
||||
},
|
||||
|
||||
pathUninstall: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/uninstall';
|
||||
},
|
||||
|
||||
pathUpdate: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/update';
|
||||
},
|
||||
|
||||
pathOptions: function (addon) {
|
||||
return 'hassio/addons/' + addon + '/options';
|
||||
},
|
||||
});
|
||||
</script>
|
70
panels/hassio/hassio-addons.html
Normal file
70
panels/hassio/hassio-addons.html
Normal file
@ -0,0 +1,70 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<dom-module id="hassio-addons">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
padding-top: 16px;
|
||||
padding-right: 16px;
|
||||
}
|
||||
|
||||
paper-item {
|
||||
cursor: pointer;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading="Addons">
|
||||
<div class="card-content">
|
||||
<template is='dom-repeat' items='[[data]]' as='addon'>
|
||||
<paper-item>
|
||||
<paper-item-body two-line on-tap='addonTapped'>
|
||||
<div>[[addon.name]]</div>
|
||||
<div secondary>[[addon.description]]</div>
|
||||
</paper-item-body>
|
||||
[[computeInstallStatus(addon)]]
|
||||
</paper-item>
|
||||
</template>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-addons',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: [],
|
||||
},
|
||||
},
|
||||
|
||||
computeInstallStatus(addon) {
|
||||
return addon.installed || 'Not installed';
|
||||
},
|
||||
|
||||
addonTapped: function (ev) {
|
||||
this.fire('hassio-select-addon', { addon: this.data[ev.model.index].slug });
|
||||
ev.target.blur();
|
||||
},
|
||||
});
|
||||
</script>
|
109
panels/hassio/hassio-dashboard.html
Normal file
109
panels/hassio/hassio-dashboard.html
Normal file
@ -0,0 +1,109 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.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-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-item/paper-item-body.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
|
||||
<link rel="import" href="./hassio-data.html">
|
||||
<link rel="import" href="./hassio-host-info.html">
|
||||
<link rel="import" href="./hassio-hass-info.html">
|
||||
<link rel="import" href="./hassio-supervisor-info.html">
|
||||
<link rel="import" href="./hassio-addons.html">
|
||||
|
||||
<dom-module id="hassio-dashboard">
|
||||
<template>
|
||||
<style include="iron-flex ha-style">
|
||||
.content {
|
||||
padding: 24px 0 32px;
|
||||
max-width: 600px;
|
||||
margin: 0 auto;
|
||||
}
|
||||
.status {
|
||||
@apply(--layout-horizontal);
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.status > * {
|
||||
@apply(--layout-flex);
|
||||
}
|
||||
|
||||
.status > *:first-child {
|
||||
margin-right: 24px;
|
||||
}
|
||||
</style>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header fixed>
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||
<div main-title>Hass.io</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class='content'>
|
||||
<div class='status'>
|
||||
<hassio-supervisor-info
|
||||
hass='[[hass]]'
|
||||
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>
|
||||
<hassio-addons
|
||||
hass='[[hass]]'
|
||||
data='[[supervisorInfo.addons]]'
|
||||
></hassio-addons>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-dashboard',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
supervisorInfo: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
|
||||
hostInfo: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
|
||||
hassInfo: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
54
panels/hassio/hassio-data.html
Normal file
54
panels/hassio/hassio-data.html
Normal file
@ -0,0 +1,54 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-data',
|
||||
|
||||
properties: {
|
||||
supervisor: {
|
||||
type: Object,
|
||||
value: {},
|
||||
notify: true,
|
||||
},
|
||||
|
||||
host: {
|
||||
type: Object,
|
||||
value: {},
|
||||
notify: true,
|
||||
},
|
||||
|
||||
homeassistant: {
|
||||
type: Object,
|
||||
value: {},
|
||||
notify: true,
|
||||
},
|
||||
},
|
||||
|
||||
attached: function () {
|
||||
this.fetchSupervisorInfo();
|
||||
this.fetchHostInfo();
|
||||
this.fetchHassInfo();
|
||||
},
|
||||
|
||||
fetchSupervisorInfo: function () {
|
||||
this.hass.callApi('get', 'hassio/supervisor/info')
|
||||
.then(function (info) {
|
||||
this.supervisor = info.data;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
fetchHostInfo: function () {
|
||||
this.hass.callApi('get', 'hassio/host/info')
|
||||
.then(function (info) {
|
||||
this.host = info.data;
|
||||
}.bind(this));
|
||||
},
|
||||
|
||||
fetchHassInfo: function () {
|
||||
this.hass.callApi('get', 'hassio/homeassistant/info')
|
||||
.then(function (info) {
|
||||
this.homeassistant = info.data;
|
||||
}.bind(this));
|
||||
},
|
||||
});
|
||||
</script>
|
65
panels/hassio/hassio-hass-info.html
Normal file
65
panels/hassio/hassio-hass-info.html
Normal file
@ -0,0 +1,65 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-hass-info">
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
.info {
|
||||
width: 100%;
|
||||
}
|
||||
.info td:nth-child(2) {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<paper-card heading="Home Assistant">
|
||||
<div class="card-content">
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<td>Current version</td>
|
||||
<td>[[data.version]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Latest version</td>
|
||||
<td>[[data.last_version]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/homeassistant/update"
|
||||
>Update</ha-call-api-button>
|
||||
</div>
|
||||
</template>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-hass-info',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
|
||||
computeUpdateAvailable: function (data) {
|
||||
return data.version !== data.last_version;
|
||||
},
|
||||
});
|
||||
</script>
|
72
panels/hassio/hassio-host-info.html
Normal file
72
panels/hassio/hassio-host-info.html
Normal file
@ -0,0 +1,72 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-host-info">
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
.info {
|
||||
width: 100%;
|
||||
}
|
||||
.info td:nth-child(2) {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<paper-card heading="Host OS">
|
||||
<div class="card-content">
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<td>Hostname</td>
|
||||
<td>[[data.hostname]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Control version</td>
|
||||
<td>[[data.version]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Type</td>
|
||||
<td>[[data.type]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>OS</td>
|
||||
<td>[[data.os]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/host/update"
|
||||
>Update</ha-call-api-button>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/host/reboot"
|
||||
>Reboot</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-host-info',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
55
panels/hassio/hassio-loading.html
Normal file
55
panels/hassio/hassio-loading.html
Normal file
@ -0,0 +1,55 @@
|
||||
<link rel='import' href='../../bower_components/paper-spinner/paper-spinner.html'>
|
||||
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
|
||||
<dom-module id='hassio-loading'>
|
||||
<template>
|
||||
<style include='iron-flex ha-style'>
|
||||
[hidden] {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
.placeholder {
|
||||
height: 100%;
|
||||
}
|
||||
|
||||
.layout {
|
||||
height: calc(100% - 64px);
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class='placeholder'>
|
||||
<app-toolbar>
|
||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||
<div main-title>Hass.io</div>
|
||||
</app-toolbar>
|
||||
<div class='layout horizontal center-center'>
|
||||
<paper-spinner active></paper-spinner>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-loading',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
narrow: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
showMenu: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
});
|
||||
</script>
|
74
panels/hassio/hassio-supervisor-info.html
Normal file
74
panels/hassio/hassio-supervisor-info.html
Normal file
@ -0,0 +1,74 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-supervisor-info">
|
||||
<style include="iron-flex ha-style">
|
||||
paper-card {
|
||||
display: block;
|
||||
height: 100%;
|
||||
}
|
||||
.info {
|
||||
width: 100%;
|
||||
}
|
||||
.info td:nth-child(2) {
|
||||
text-align: right;
|
||||
}
|
||||
</style>
|
||||
<template>
|
||||
<paper-card heading="Supervisor">
|
||||
<div class="card-content">
|
||||
<table class='info'>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>[[data.version]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Beta channel</td>
|
||||
<td>[[data.beta_channel]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Latest available version</td>
|
||||
<td>[[data.last_version]]</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="hassio/supervisor/update"
|
||||
>Update</ha-call-api-button>
|
||||
</template>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/supervisor/reload"
|
||||
>Restart</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'hassio-supervisor-info',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
|
||||
computeUpdateAvailable: function (data) {
|
||||
return data.version !== data.last_version;
|
||||
},
|
||||
});
|
||||
</script>
|
19
panels/hassio/todo.md
Normal file
19
panels/hassio/todo.md
Normal file
@ -0,0 +1,19 @@
|
||||
General:
|
||||
- Refresh data after API call
|
||||
|
||||
Host:
|
||||
- Use feature detection
|
||||
|
||||
Supervisor:
|
||||
- logs
|
||||
- toggle beta channel (/options)
|
||||
|
||||
Addon View:
|
||||
- break up UI in smaller custom elements to organize code
|
||||
|
||||
Network:
|
||||
- show
|
||||
- update
|
||||
|
||||
Home Assistant:
|
||||
- Logs
|
@ -5,7 +5,7 @@
|
||||
<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="../../src/components/ha-call-service-button.html">
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-service-button.html">
|
||||
<link rel="import" href="../../src/resources/ha-style.html">
|
||||
|
||||
<dom-module id="ha-panel-zwave">
|
||||
|
63
src/components/buttons/ha-call-api-button.html
Normal file
63
src/components/buttons/ha-call-api-button.html
Normal file
@ -0,0 +1,63 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="./ha-progress-button.html">
|
||||
|
||||
<dom-module id='ha-call-api-button'>
|
||||
<template>
|
||||
<ha-progress-button
|
||||
id='progress'
|
||||
progress='[[progress]]'
|
||||
on-tap='buttonTapped'
|
||||
disabled='[[disabled]]'
|
||||
><slot></slot></ha-progress-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'ha-call-api-button',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
progress: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
path: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
method: {
|
||||
type: String,
|
||||
value: 'POST',
|
||||
},
|
||||
|
||||
data: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
|
||||
buttonTapped: function () {
|
||||
this.progress = true;
|
||||
var el = this;
|
||||
|
||||
this.hass.callApi(this.method, this.path, this.data)
|
||||
.then(function () {
|
||||
el.progress = false;
|
||||
el.$.progress.actionSuccess();
|
||||
}, function () {
|
||||
el.progress = false;
|
||||
el.$.progress.actionError();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
56
src/components/buttons/ha-call-service-button.html
Normal file
56
src/components/buttons/ha-call-service-button.html
Normal file
@ -0,0 +1,56 @@
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="./ha-progress-button.html">
|
||||
|
||||
<dom-module id='ha-call-service-button'>
|
||||
<template>
|
||||
<ha-progress-button
|
||||
id='progress'
|
||||
progress='[[progress]]'
|
||||
on-tap='buttonTapped'
|
||||
><slot></slot></ha-progress-button>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'ha-call-service-button',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
progress: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
|
||||
domain: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
service: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
serviceData: {
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
},
|
||||
|
||||
buttonTapped: function () {
|
||||
this.progress = true;
|
||||
var el = this;
|
||||
|
||||
this.hass.callService(this.domain, this.service, this.serviceData)
|
||||
.then(function () {
|
||||
el.progress = false;
|
||||
el.$.progress.actionSuccess();
|
||||
}, function () {
|
||||
el.progress = false;
|
||||
el.$.progress.actionError();
|
||||
});
|
||||
}
|
||||
});
|
||||
</script>
|
@ -1,8 +1,8 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../bower_components/paper-spinner/paper-spinner.html">
|
||||
<link rel="import" href="../../../bower_components/polymer/polymer.html">
|
||||
<link rel="import" href="../../../bower_components/paper-button/paper-button.html">
|
||||
<link rel="import" href="../../../bower_components/paper-spinner/paper-spinner.html">
|
||||
|
||||
<dom-module id='ha-call-service-button'>
|
||||
<dom-module id='ha-progress-button'>
|
||||
<template>
|
||||
<style>
|
||||
.container {
|
||||
@ -43,7 +43,7 @@
|
||||
<div class='container' id='container'>
|
||||
<paper-button
|
||||
id='button'
|
||||
disabled='[[progress]]'
|
||||
disabled='[[computeDisabled(disabled, progress)]]'
|
||||
on-tap='buttonTapped'
|
||||
>
|
||||
<slot></slot>
|
||||
@ -59,7 +59,7 @@
|
||||
|
||||
<script>
|
||||
Polymer({
|
||||
is: 'ha-call-service-button',
|
||||
is: 'ha-progress-button',
|
||||
|
||||
properties: {
|
||||
hass: {
|
||||
@ -83,6 +83,11 @@ Polymer({
|
||||
type: Object,
|
||||
value: {},
|
||||
},
|
||||
|
||||
disabled: {
|
||||
type: Boolean,
|
||||
value: false,
|
||||
},
|
||||
},
|
||||
|
||||
tempClass: function (className) {
|
||||
@ -93,18 +98,24 @@ Polymer({
|
||||
}, 1000);
|
||||
},
|
||||
|
||||
buttonTapped: function () {
|
||||
this.progress = true;
|
||||
var el = this;
|
||||
listeners: {
|
||||
tap: 'buttonTapped',
|
||||
},
|
||||
|
||||
this.hass.callService(this.domain, this.service, this.serviceData)
|
||||
.then(function () {
|
||||
el.tempClass('success');
|
||||
el.progress = false;
|
||||
}, function () {
|
||||
el.tempClass('error');
|
||||
el.progress = false;
|
||||
});
|
||||
}
|
||||
buttonTapped: function (ev) {
|
||||
if (this.progress) ev.stopPropagation();
|
||||
},
|
||||
|
||||
actionSuccess: function () {
|
||||
this.tempClass('success');
|
||||
},
|
||||
|
||||
actionError: function () {
|
||||
this.tempClass('error');
|
||||
},
|
||||
|
||||
computeDisabled: function (disabled, progress) {
|
||||
return disabled || progress;
|
||||
},
|
||||
});
|
||||
</script>
|
@ -86,12 +86,14 @@
|
||||
}
|
||||
|
||||
.card-actions > paper-button:not([disabled]),
|
||||
.card-actions > ha-call-api-button:not([disabled]),
|
||||
.card-actions > ha-call-service-button:not([disabled]) {
|
||||
color: var(--default-primary-color);
|
||||
font-weight: 500;
|
||||
}
|
||||
|
||||
.card-actions > paper-button.warning:not([disabled]),
|
||||
.card-actions > ha-call-api-button.warning:not([disabled]),
|
||||
.card-actions > ha-call-service-button.warning:not([disabled]) {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user