mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-22 16:56:35 +00:00
Hass.io improved add-on view (#874)
* Rename * Improvements * Travis * Feedback * Typo
This commit is contained in:
parent
1f703fbdda
commit
710c2f1094
112
hassio/addon-view/hassio-addon-config.html
Normal file
112
hassio/addon-view/hassio-addon-config.html
Normal file
@ -0,0 +1,112 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-addon-config">
|
||||
<template>
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
.card-actions {
|
||||
@apply(--layout);
|
||||
@apply(--layout-justified);
|
||||
}
|
||||
.errors {
|
||||
color: var(--google-red-500);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
width: 100%;
|
||||
font-family: monospace;
|
||||
background-color: var(--primary-text-color);
|
||||
color: var(--text-primary-color);
|
||||
}
|
||||
.syntaxerror {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Config'>
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='errors'>[[error]]</div>
|
||||
</template>
|
||||
<iron-autogrow-textarea id='config' value="{{config}}"></iron-autogrow-textarea>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="hassio/addons/[[addonSlug]]/options"
|
||||
data='[[resetData]]'
|
||||
>Reset to defaults</ha-call-api-button>
|
||||
<paper-button
|
||||
on-tap='saveTapped'
|
||||
disabled='[[!configParsed]]'
|
||||
>Save</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioAddonConfig extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-config'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
addon: {
|
||||
type: Object,
|
||||
observer: 'addonChanged',
|
||||
},
|
||||
addonSlug: String,
|
||||
config: {
|
||||
type: String,
|
||||
observer: 'configChanged',
|
||||
},
|
||||
configParsed: Object,
|
||||
error: String,
|
||||
resetData: {
|
||||
type: Object,
|
||||
value: {
|
||||
options: null,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
addonChanged(addon) {
|
||||
this.config = addon ? JSON.stringify(addon.options, null, 2) : '';
|
||||
}
|
||||
|
||||
configChanged(config) {
|
||||
try {
|
||||
this.$.config.classList.remove('syntaxerror');
|
||||
this.configParsed = JSON.parse(config);
|
||||
} catch (err) {
|
||||
this.$.config.classList.add('syntaxerror');
|
||||
this.configParsed = null;
|
||||
}
|
||||
}
|
||||
|
||||
saveTapped() {
|
||||
this.error = null;
|
||||
|
||||
this.hass.callApi('post', `hassio/addons/${this.addonSlug}/options`, {
|
||||
options: this.configParsed
|
||||
}).catch((resp) => {
|
||||
this.error = resp.body.message;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonConfig.is, HassioAddonConfig);
|
||||
</script>
|
@ -1,180 +1,190 @@
|
||||
<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/iron-icon/iron-icon.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/paper-checkbox/paper-checkbox.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
<link rel='import' href='../../bower_components/paper-card/paper-card.html'>
|
||||
<link rel='import' href='../../bower_components/paper-toggle-button/paper-toggle-button.html'>
|
||||
|
||||
|
||||
<link rel="import" href="../../src/components/ha-icon-check.html">
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
<link rel='import' href='../../src/components/ha-markdown.html'>
|
||||
|
||||
<dom-module id="hassio-addon-info">
|
||||
<template>
|
||||
<style include="ha-style">
|
||||
<style include='ha-style'>
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
td {
|
||||
padding-top: 5px;
|
||||
.addon-header {
|
||||
@apply --paper-font-headline;
|
||||
}
|
||||
td ha-call-api-button {
|
||||
.light-color {
|
||||
color: var(--secondary-text-color);
|
||||
}
|
||||
.addon-version {
|
||||
float: right;
|
||||
font-size: 15px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
.description {
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
.logo img {
|
||||
max-height: 60px;
|
||||
margin: 16px 0;
|
||||
display: block;
|
||||
}
|
||||
.state div{
|
||||
width: 150px;
|
||||
display: inline-block;
|
||||
}
|
||||
paper-toggle-button {
|
||||
display: inline;
|
||||
}
|
||||
iron-icon.running {
|
||||
color: var(--paper-green-400);
|
||||
}
|
||||
iron-icon.stopped {
|
||||
color: var(--google-red-300);
|
||||
}
|
||||
ha-call-api-button {
|
||||
font-weight: 500;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
a.help {
|
||||
--iron-icon-height: 16px;
|
||||
--iron-icon-width: 16px;
|
||||
color: var(--primary-color);
|
||||
}
|
||||
|
||||
.card-actions a {
|
||||
text-decoration: none;
|
||||
}
|
||||
.logo {
|
||||
max-height: 70px;
|
||||
max-width: 100%;
|
||||
}
|
||||
.right {
|
||||
float: right;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Info'>
|
||||
<div class="card-content">
|
||||
<table class='info' cellspacing="0">
|
||||
<template is='dom-if' if='[[addonState.logo]]'>
|
||||
<tr>
|
||||
<td>Logo</td>
|
||||
<td><img src='[[_pathLogo(addonInfo.slug)]]' class='logo'></td>
|
||||
</tr>
|
||||
</template>
|
||||
<tr>
|
||||
<td>Description</td>
|
||||
<td>[[addonInfo.description]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Version</td>
|
||||
<td>
|
||||
[[addonState.version]]
|
||||
|
||||
<template is='dom-if' if='[[_computeUpdateAvailable(addonState)]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[_pathUpdate(addonInfo.slug)]]"
|
||||
>Update</ha-call-api-button>
|
||||
</template>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>State</td>
|
||||
<td>[[addonState.state]]</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Boot</td>
|
||||
<td>
|
||||
[[addonState.boot]]
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[_pathAddonOptions(addonInfo.slug)]]"
|
||||
data="[[_dataToggleBoot(addonInfo.slug, addonState)]]"
|
||||
>Toggle</ha-call-api-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Auto update</td>
|
||||
<td>
|
||||
<ha-icon-check
|
||||
checked='[[addonState.auto_update]]'
|
||||
></ha-icon-check>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[_pathAddonOptions(addonInfo.slug)]]"
|
||||
data="[[_dataToggleAutoUpdate(addonInfo.slug, addonState)]]"
|
||||
>Toggle</ha-call-api-button>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Uses host network</td>
|
||||
<td>
|
||||
<ha-icon-check
|
||||
checked='[[addonState.host_network]]'
|
||||
></ha-icon-check>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
Builds locally
|
||||
<a
|
||||
class='help'
|
||||
href="https://home-assistant.io/hassio/addon_publishing/#locally-build-containers"
|
||||
target="_blank"
|
||||
>
|
||||
<iron-icon
|
||||
icon="mdi:help-circle"
|
||||
label="Learn more about locally build containers"
|
||||
></iron-icon>
|
||||
</a>
|
||||
</td>
|
||||
<td>
|
||||
<ha-icon-check
|
||||
checked='[[addonState.build]]'
|
||||
></ha-icon-check>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Detached</td>
|
||||
<td>
|
||||
<ha-icon-check
|
||||
checked='[[addonState.detached]]'
|
||||
></ha-icon-check>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<div class="card-actions">
|
||||
<template is='dom-if' if='[[!_isRunning]]'>
|
||||
<template is='dom-if' if='[[computeUpdateAvailable(addon)]]'>
|
||||
<paper-card heading='Update available! 🎉'>
|
||||
<div class='card-content'>
|
||||
<hassio-item-info
|
||||
title='[[addon.name]] [[addon.last_version]] is available'
|
||||
description='You are currently running version [[addon.version]]'
|
||||
icon='mdi:arrow-up-bold-circle'
|
||||
classname='update'
|
||||
></hassio-item-info>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path="[[_pathStart(addonInfo.slug)]]"
|
||||
>Start</ha-call-api-button>
|
||||
path='hassio/addons/[[addonSlug]]/update'
|
||||
>Update</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<div class='addon-header'>[[addon.name]]
|
||||
<div class='addon-version light-color'>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
[[addon.version]]
|
||||
<template is='dom-if' if='[[isRunning]]'>
|
||||
<iron-icon
|
||||
title='Add-on is running'
|
||||
class='running'
|
||||
icon='mdi:circle'
|
||||
></iron-icon>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!isRunning]]'>
|
||||
<iron-icon
|
||||
title='Add-on is stopped'
|
||||
class='stopped'
|
||||
icon='mdi:circle'
|
||||
></iron-icon>
|
||||
</template>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!addon.version]]'>
|
||||
[[addon.last_version]]
|
||||
</template>
|
||||
</div>
|
||||
</div>
|
||||
<div class='description light-color'>
|
||||
[[addon.description]].<br/>
|
||||
Visit <a href='[[addon.url]]' target='_blank'>[[addon.name]] page</a> for details.
|
||||
</div>
|
||||
<template is='dom-if' if='[[addon.logo]]'>
|
||||
<a href='[[addon.url]]' target='_blank' class='logo'>
|
||||
<img src='/api/hassio/addons/[[addonSlug]]/logo'/>
|
||||
</a>
|
||||
</template>
|
||||
<template is='dom-if' if='[[_isRunning]]'>
|
||||
<template is='dom-if' if='[[addonState.webui]]'>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<div class='state'>
|
||||
<div>Start on boot</div>
|
||||
<paper-toggle-button
|
||||
on-change='startOnBootToggled'
|
||||
checked='[[computeStartOnBoot(addon.boot)]]'
|
||||
></paper-toggle-button>
|
||||
</div>
|
||||
<div class='state'>
|
||||
<div>Auto update</div>
|
||||
<paper-toggle-button
|
||||
on-change='autoUpdateToggled'
|
||||
checked='[[addon.auto_update]]'
|
||||
></paper-toggle-button>
|
||||
</div>
|
||||
</template>
|
||||
</div>
|
||||
<div class='card-actions'>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/uninstall'
|
||||
>Uninstall</ha-call-api-button>
|
||||
<template is='dom-if' if='[[addon.build]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/rebuild'
|
||||
>Rebuild</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[isRunning]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/restart'
|
||||
>Restart</ha-call-api-button>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/stop'
|
||||
>Stop</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[!isRunning]]'>
|
||||
<ha-call-api-button
|
||||
hass='[[hass]]'
|
||||
path='hassio/addons/[[addonSlug]]/start'
|
||||
>Start</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[computeShowWebUI(addon.webui, isRunning)]]'>
|
||||
<a
|
||||
href='[[_pathWebui(addonState.webui)]]'
|
||||
tabindex="-1"
|
||||
target="_blank"
|
||||
href='[[pathWebui(addon.webui)]]'
|
||||
tabindex='-1'
|
||||
target='_blank'
|
||||
class='right'
|
||||
><paper-button>Open web UI</paper-button></a>
|
||||
</template>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[_pathRestart(addonInfo.slug)]]"
|
||||
>Restart</ha-call-api-button>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[_pathStop(addonInfo.slug)]]"
|
||||
>Stop</ha-call-api-button>
|
||||
</template>
|
||||
<template is='dom-if' if='[[addonState.build]]'>
|
||||
<template is='dom-if' if='[[!addon.version]]'>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[_pathRebuild(addonInfo.slug)]]"
|
||||
>Rebuild</ha-call-api-button>
|
||||
path='hassio/addons/[[addonSlug]]/install'
|
||||
>Install</ha-call-api-button>
|
||||
</template>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[_pathUninstall(addonInfo.slug)]]"
|
||||
>Uninstall</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
<template is='dom-if' if='[[addon.long_description]]'>
|
||||
<paper-card>
|
||||
<div class='card-content'>
|
||||
<ha-markdown content='[[addon.long_description]]'></ha-markdown>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
@ -185,68 +195,44 @@ class HassioAddonInfo extends Polymer.Element {
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
addonInfo: Object,
|
||||
addonState: Object,
|
||||
|
||||
_isRunning: {
|
||||
addon: Object,
|
||||
addonSlug: String,
|
||||
isRunning: {
|
||||
type: Boolean,
|
||||
computed: '_computeIsRunning(addonState)',
|
||||
computed: 'computeIsRunning(addon)',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
_computeIsRunning(addonState) {
|
||||
return addonState && addonState.state === 'started';
|
||||
computeIsRunning(addon) {
|
||||
return addon && addon.state === 'started';
|
||||
}
|
||||
|
||||
_computeUpdateAvailable(data) {
|
||||
return data && !data.detached && data.version !== data.last_version;
|
||||
computeUpdateAvailable(addon) {
|
||||
return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
|
||||
}
|
||||
|
||||
_pathStart(addon) {
|
||||
return 'hassio/addons/' + addon + '/start';
|
||||
}
|
||||
|
||||
_pathStop(addon) {
|
||||
return 'hassio/addons/' + addon + '/stop';
|
||||
}
|
||||
|
||||
_pathRestart(addon) {
|
||||
return 'hassio/addons/' + addon + '/restart';
|
||||
}
|
||||
|
||||
_pathRebuild(addon) {
|
||||
return 'hassio/addons/' + addon + '/rebuild';
|
||||
}
|
||||
|
||||
_pathUninstall(addon) {
|
||||
return 'hassio/addons/' + addon + '/uninstall';
|
||||
}
|
||||
|
||||
_pathUpdate(addon) {
|
||||
return 'hassio/addons/' + addon + '/update';
|
||||
}
|
||||
|
||||
_pathAddonOptions(addon) {
|
||||
return 'hassio/addons/' + addon + '/options';
|
||||
}
|
||||
|
||||
_pathWebui(webui) {
|
||||
pathWebui(webui) {
|
||||
return webui && webui.replace('[HOST]', document.location.hostname);
|
||||
}
|
||||
|
||||
_pathLogo(addon) {
|
||||
return '/api/hassio/addons/' + addon + '/logo';
|
||||
computeShowWebUI(webui, isRunning) {
|
||||
return webui && isRunning;
|
||||
}
|
||||
|
||||
_dataToggleAutoUpdate(addon, addonState) {
|
||||
return addonState && { auto_update: !addonState.auto_update };
|
||||
computeStartOnBoot(state) {
|
||||
return state === 'auto';
|
||||
}
|
||||
|
||||
_dataToggleBoot(addon, addonState) {
|
||||
return addonState && { boot: addonState.boot === 'manual' ? 'auto' : 'manual' };
|
||||
startOnBootToggled() {
|
||||
const data = { boot: this.addon.boot === 'auto' ? 'manual' : 'auto' };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
|
||||
autoUpdateToggled() {
|
||||
const data = { auto_update: !this.addon.auto_update };
|
||||
this.hass.callApi('POST', `hassio/addons/${this.addonSlug}/options`, data);
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonInfo.is, HassioAddonInfo);
|
||||
</script>
|
||||
|
@ -10,9 +10,9 @@
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Logs'>
|
||||
<paper-card heading='Log'>
|
||||
<div class="card-content">
|
||||
<pre>[[addonLogs]]</pre>
|
||||
<pre>[[log]]</pre>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button on-tap='refresh'>Refresh</paper-button>
|
||||
@ -27,25 +27,18 @@ class HassioAddonLogs extends Polymer.Element {
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
addon: {
|
||||
hass: Object,
|
||||
addonSlug: {
|
||||
type: String,
|
||||
observer: 'addonChanged',
|
||||
},
|
||||
|
||||
addonLogs: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer: 'addonSlugChanged',
|
||||
},
|
||||
log: String,
|
||||
};
|
||||
}
|
||||
|
||||
addonChanged(addon) {
|
||||
addonSlugChanged(slug) {
|
||||
if (!this.hass) {
|
||||
setTimeout(function () { this.addonChanged(addon); }.bind(this), 0);
|
||||
setTimeout(() => { this.addonChanged(slug); }, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
@ -53,10 +46,10 @@ class HassioAddonLogs extends Polymer.Element {
|
||||
}
|
||||
|
||||
refresh() {
|
||||
this.hass.callApi('get', 'hassio/addons/' + this.addon + '/logs')
|
||||
.then(function (info) {
|
||||
this.addonLogs = info;
|
||||
}.bind(this));
|
||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/logs`)
|
||||
.then((info) => {
|
||||
this.log = info;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -26,8 +26,8 @@
|
||||
</style>
|
||||
<paper-card heading='Network'>
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>[[errors]]</div>
|
||||
<template is='dom-if' if='[[error]]'>
|
||||
<div class='errors'>[[error]]</div>
|
||||
</template>
|
||||
|
||||
<table>
|
||||
@ -37,7 +37,7 @@
|
||||
</tr>
|
||||
<template
|
||||
is='dom-repeat'
|
||||
items='[[_data]]'
|
||||
items='[[config]]'
|
||||
>
|
||||
<tr>
|
||||
<td>
|
||||
@ -53,16 +53,16 @@
|
||||
</template>
|
||||
</table>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button
|
||||
on-tap='_saveTapped'
|
||||
>Save</paper-button>
|
||||
<div class="card-actions">
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[_pathAddonOptions(addon)]]"
|
||||
data="[[_resetData]]"
|
||||
>Reset</ha-call-api-button>
|
||||
path="hassio/addons/[[addonSlug]]/options"
|
||||
data="[[resetData]]"
|
||||
>Reset to defaults</ha-call-api-button>
|
||||
<paper-button
|
||||
on-tap='saveTapped'
|
||||
>Save</paper-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
@ -75,23 +75,14 @@ class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
static get properties() {
|
||||
return {
|
||||
hass: Object,
|
||||
addon: String,
|
||||
errors: {
|
||||
type: String,
|
||||
value: null,
|
||||
},
|
||||
|
||||
_data: {
|
||||
addonSlug: String,
|
||||
config: Object,
|
||||
addon: {
|
||||
type: Object,
|
||||
value: [],
|
||||
observer: 'addonChanged',
|
||||
},
|
||||
|
||||
addonState: {
|
||||
type: Object,
|
||||
observer: '_addonStateChanged',
|
||||
},
|
||||
|
||||
_resetData: {
|
||||
error: String,
|
||||
resetData: {
|
||||
type: Object,
|
||||
value: {
|
||||
network: null,
|
||||
@ -100,38 +91,32 @@ class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element)
|
||||
};
|
||||
}
|
||||
|
||||
_addonStateChanged(addonState) {
|
||||
if (!addonState) return;
|
||||
addonChanged(addon) {
|
||||
if (!addon) return;
|
||||
|
||||
var network = addonState.network || {};
|
||||
var items = Object.keys(network).map(function (key) {
|
||||
return {
|
||||
container: key,
|
||||
host: '' + network[key]
|
||||
};
|
||||
});
|
||||
this._data = items.sort(function (el1, el2) { return el1.host - el2.host; });
|
||||
const network = addon.network || {};
|
||||
const items = Object.keys(network).map(key => ({
|
||||
container: key,
|
||||
host: network[key]
|
||||
}));
|
||||
this.config = items.sort(function (el1, el2) { return el1.host - el2.host; });
|
||||
}
|
||||
|
||||
_saveTapped() {
|
||||
this.errors = null;
|
||||
var toSend = {};
|
||||
this._data.forEach(function (item) {
|
||||
toSend[item.container] = parseInt(item.host);
|
||||
saveTapped() {
|
||||
this.error = null;
|
||||
const data = {};
|
||||
this.config.forEach(function (item) {
|
||||
data[item.container] = parseInt(item.host);
|
||||
});
|
||||
var path = 'hassio/addons/' + this.addon + '/options';
|
||||
const path = `hassio/addons/${this.addonSlug}/options`;
|
||||
|
||||
this.hass.callApi('post', path, {
|
||||
network: toSend
|
||||
}).then(function () {
|
||||
network: data
|
||||
}).then(() => {
|
||||
this.fire('hass-api-called', { success: true, path: path });
|
||||
}.bind(this), function (resp) {
|
||||
this.errors = resp.body.message;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
_pathAddonOptions(addon) {
|
||||
return 'hassio/addons/' + addon + '/options';
|
||||
}, (resp) => {
|
||||
this.error = resp.body.message;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,129 +0,0 @@
|
||||
<link rel="import" href="../../bower_components/polymer/polymer-element.html">
|
||||
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||
<link rel="import" href="../../bower_components/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||
<link rel="import" href="../../bower_components/iron-flex-layout/iron-flex-layout.html">
|
||||
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||
|
||||
<link rel="import" href="../../src/components/buttons/ha-call-api-button.html">
|
||||
|
||||
<dom-module id="hassio-addon-options">
|
||||
<template>
|
||||
<style include="ha-style">
|
||||
:host {
|
||||
display: block;
|
||||
}
|
||||
paper-card {
|
||||
display: block;
|
||||
}
|
||||
.card-actions {
|
||||
@apply(--layout);
|
||||
@apply(--layout-justified);
|
||||
}
|
||||
.errors {
|
||||
color: var(--google-red-500);
|
||||
margin-bottom: 16px;
|
||||
}
|
||||
iron-autogrow-textarea {
|
||||
width: 100%;
|
||||
}
|
||||
</style>
|
||||
<paper-card heading='Options'>
|
||||
<div class="card-content">
|
||||
<template is='dom-if' if='[[errors]]'>
|
||||
<div class='errors'>[[errors]]</div>
|
||||
</template>
|
||||
<iron-autogrow-textarea value="{{options}}"></iron-autogrow-textarea>
|
||||
</div>
|
||||
<div class="card-actions">
|
||||
<paper-button
|
||||
on-tap='saveTapped'
|
||||
disabled='[[!optionsParsed]]'
|
||||
>Save</paper-button>
|
||||
<ha-call-api-button
|
||||
class='warning'
|
||||
hass='[[hass]]'
|
||||
path="[[pathOptions(addon)]]"
|
||||
data='[[_resetOptionsData]]'
|
||||
>Discard changes</ha-call-api-button>
|
||||
</div>
|
||||
</paper-card>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HassioAddonOptions extends Polymer.Element {
|
||||
static get is() { return 'hassio-addon-options'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
addon: {
|
||||
type: String,
|
||||
},
|
||||
|
||||
options: {
|
||||
type: String,
|
||||
value: '',
|
||||
},
|
||||
|
||||
optionsParsed: {
|
||||
type: Object,
|
||||
computed: 'parseOptions(options)',
|
||||
},
|
||||
|
||||
errors: {
|
||||
type: String,
|
||||
value: null,
|
||||
},
|
||||
|
||||
addonState: {
|
||||
type: Object,
|
||||
value: null,
|
||||
observer: 'addonStateChanged',
|
||||
},
|
||||
|
||||
_resetOptionsData: {
|
||||
type: Object,
|
||||
value: { options: {} },
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
addonStateChanged(addonState) {
|
||||
this.options = addonState ? JSON.stringify(addonState.options, null, 2) : '';
|
||||
}
|
||||
|
||||
parseOptions(options) {
|
||||
try {
|
||||
return JSON.parse(options);
|
||||
} catch (err) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
saveTapped() {
|
||||
this.errors = null;
|
||||
|
||||
this.hass.callApi('post', 'hassio/addons/' + this.addon + '/options', {
|
||||
options: this.optionsParsed
|
||||
}).catch(function (resp) {
|
||||
this.errors = resp.body.message;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
computeOptionsData(optionsParsed) {
|
||||
return {
|
||||
options: optionsParsed,
|
||||
};
|
||||
}
|
||||
|
||||
pathOptions(addon) {
|
||||
return 'hassio/addons/' + addon + '/options';
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HassioAddonOptions.is, HassioAddonOptions);
|
||||
</script>
|
@ -4,10 +4,8 @@
|
||||
<link rel="import" href="../../bower_components/app-layout/app-toolbar/app-toolbar.html">
|
||||
<link rel="import" href="../../bower_components/app-route/app-route.html">
|
||||
|
||||
<link rel="import" href="../../src/components/ha-menu-button.html">
|
||||
|
||||
<link rel="import" href="./hassio-addon-info.html">
|
||||
<link rel="import" href="./hassio-addon-options.html">
|
||||
<link rel="import" href="./hassio-addon-config.html">
|
||||
<link rel="import" href="./hassio-addon-network.html">
|
||||
<link rel="import" href="./hassio-addon-logs.html">
|
||||
|
||||
@ -16,7 +14,7 @@
|
||||
<style include="iron-flex ha-style">
|
||||
hassio-addon-info,
|
||||
hassio-addon-network,
|
||||
hassio-addon-options {
|
||||
hassio-addon-config {
|
||||
margin-bottom: 24px;
|
||||
}
|
||||
.content {
|
||||
@ -27,8 +25,9 @@
|
||||
</style>
|
||||
<app-route
|
||||
route='[[route]]'
|
||||
pattern='/addon/:addon'
|
||||
data="{{_routeData}}"
|
||||
pattern='/addon/:slug'
|
||||
data="{{routeData}}"
|
||||
active='{{routeMatches}}'
|
||||
></app-route>
|
||||
<app-header-layout has-scrolling-region>
|
||||
<app-header slot="header" fixed>
|
||||
@ -37,33 +36,37 @@
|
||||
icon='mdi:arrow-left'
|
||||
on-tap='backTapped'
|
||||
></paper-icon-button>
|
||||
<div main-title>[[addonInfo.name]]</div>
|
||||
<div main-title>[[addon.name]]</div>
|
||||
</app-toolbar>
|
||||
</app-header>
|
||||
|
||||
<div class='content'>
|
||||
<hassio-addon-info
|
||||
hass='[[hass]]'
|
||||
addon-info='[[addonInfo]]'
|
||||
addon-state='[[addonState]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-info>
|
||||
|
||||
<hassio-addon-options
|
||||
hass='[[hass]]'
|
||||
addon='[[_routeData.addon]]'
|
||||
addon-state='[[addonState]]'
|
||||
></hassio-addon-options>
|
||||
<template is='dom-if' if='[[addon.version]]'>
|
||||
<hassio-addon-config
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-config>
|
||||
|
||||
<hassio-addon-network
|
||||
hass='[[hass]]'
|
||||
addon='[[_routeData.addon]]'
|
||||
addon-state='[[addonState]]'
|
||||
></hassio-addon-network>
|
||||
<template is='dom-if' if='[[addon.network]]'>
|
||||
<hassio-addon-network
|
||||
hass='[[hass]]'
|
||||
addon='[[addon]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-network>
|
||||
</template>
|
||||
|
||||
<hassio-addon-logs
|
||||
hass='[[hass]]'
|
||||
addon='[[_routeData.addon]]'
|
||||
></hassio-addon-logs>
|
||||
<hassio-addon-logs
|
||||
hass='[[hass]]'
|
||||
addon-slug='[[routeData.slug]]'
|
||||
></hassio-addon-logs>
|
||||
</template>
|
||||
</div>
|
||||
</app-header-layout>
|
||||
</template>
|
||||
@ -75,34 +78,14 @@ class HassioAddonView extends Polymer.Element {
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
hass: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
hass: Object,
|
||||
route: Object,
|
||||
_routeData: {
|
||||
routeData: {
|
||||
type: Object,
|
||||
observer: '_routeDataChanged',
|
||||
},
|
||||
|
||||
supervisorInfo: {
|
||||
type: Object,
|
||||
},
|
||||
|
||||
addonInfo: {
|
||||
type: Object,
|
||||
computed: 'computeAddonInfo(supervisorInfo, _routeData.addon)',
|
||||
},
|
||||
|
||||
addonState: {
|
||||
type: Object,
|
||||
value: null,
|
||||
},
|
||||
|
||||
addonLogs: {
|
||||
type: String,
|
||||
value: '',
|
||||
observer: 'routeDataChanged',
|
||||
},
|
||||
routeMatches: Boolean,
|
||||
addon: Object,
|
||||
};
|
||||
}
|
||||
|
||||
@ -112,35 +95,25 @@ class HassioAddonView extends Polymer.Element {
|
||||
}
|
||||
|
||||
apiCalled(ev) {
|
||||
var path = ev.detail.path;
|
||||
const path = ev.detail.path;
|
||||
|
||||
if (!path) return;
|
||||
|
||||
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
||||
this.backTapped();
|
||||
} else {
|
||||
this._routeDataChanged(this._routeData);
|
||||
this.routeDataChanged(this.routeData);
|
||||
}
|
||||
}
|
||||
|
||||
_routeDataChanged(routeData) {
|
||||
if (!routeData || !routeData.addon) return;
|
||||
this.hass.callApi('get', 'hassio/addons/' + routeData.addon + '/info')
|
||||
.then(function (info) {
|
||||
this.addonState = info.data;
|
||||
}.bind(this), function () {
|
||||
this.addonState = null;
|
||||
}.bind(this));
|
||||
}
|
||||
|
||||
computeAddonInfo(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;
|
||||
routeDataChanged(routeData) {
|
||||
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
||||
this.hass.callApi('get', `hassio/addons/${routeData.slug}/info`)
|
||||
.then((info) => {
|
||||
this.addon = info.data;
|
||||
}, () => {
|
||||
this.addon = null;
|
||||
});
|
||||
}
|
||||
|
||||
backTapped() {
|
||||
|
@ -54,9 +54,6 @@
|
||||
page-name='addon'
|
||||
route='[[route]]'
|
||||
hass='[[hass]]'
|
||||
supervisor-info='[[supervisorInfo]]'
|
||||
host-info='[[hostInfo]]'
|
||||
addon='[[addon]]'
|
||||
></hassio-addon-view>
|
||||
|
||||
<hassio-addon-store
|
||||
|
@ -1,51 +0,0 @@
|
||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
||||
<link rel='import' href='../../bower_components/iron-icon/iron-icon.html'>
|
||||
|
||||
<dom-module id='ha-icon-check'>
|
||||
<template>
|
||||
<style>
|
||||
:host {
|
||||
--ha-label-badge-color: #dac90d;
|
||||
}
|
||||
|
||||
.pos {
|
||||
color: var(--google-green-500);
|
||||
}
|
||||
|
||||
.neg {
|
||||
color: var(--google-red-500);
|
||||
}
|
||||
|
||||
[hidden] {
|
||||
display: none;
|
||||
}
|
||||
</style>
|
||||
|
||||
<iron-icon
|
||||
class='pos'
|
||||
hidden='[[!checked]]'
|
||||
icon='mdi:check'
|
||||
label='True'
|
||||
></iron-icon>
|
||||
<iron-icon
|
||||
class='neg'
|
||||
hidden='[[checked]]'
|
||||
icon='mdi:window-close'
|
||||
label='False'
|
||||
></iron-icon>
|
||||
</template>
|
||||
</dom-module>
|
||||
|
||||
<script>
|
||||
class HaIconCheck extends Polymer.Element {
|
||||
static get is() { return 'ha-icon-check'; }
|
||||
|
||||
static get properties() {
|
||||
return {
|
||||
checked: Boolean,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define(HaIconCheck.is, HaIconCheck);
|
||||
</script>
|
Loading…
x
Reference in New Issue
Block a user