mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 09:16:38 +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/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/iron-icon/iron-icon.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-checkbox/paper-checkbox.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-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/buttons/ha-call-api-button.html">
|
||||||
|
<link rel='import' href='../../src/components/ha-markdown.html'>
|
||||||
|
|
||||||
<dom-module id="hassio-addon-info">
|
<dom-module id="hassio-addon-info">
|
||||||
<template>
|
<template>
|
||||||
<style include="ha-style">
|
<style include='ha-style'>
|
||||||
:host {
|
:host {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
paper-card {
|
paper-card {
|
||||||
display: block;
|
display: block;
|
||||||
|
margin-bottom: 16px;
|
||||||
}
|
}
|
||||||
td {
|
.addon-header {
|
||||||
padding-top: 5px;
|
@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);
|
color: var(--primary-color);
|
||||||
}
|
}
|
||||||
|
.right {
|
||||||
a.help {
|
float: right;
|
||||||
--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%;
|
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<paper-card heading='Info'>
|
<template is='dom-if' if='[[computeUpdateAvailable(addon)]]'>
|
||||||
<div class="card-content">
|
<paper-card heading='Update available! 🎉'>
|
||||||
<table class='info' cellspacing="0">
|
<div class='card-content'>
|
||||||
<template is='dom-if' if='[[addonState.logo]]'>
|
<hassio-item-info
|
||||||
<tr>
|
title='[[addon.name]] [[addon.last_version]] is available'
|
||||||
<td>Logo</td>
|
description='You are currently running version [[addon.version]]'
|
||||||
<td><img src='[[_pathLogo(addonInfo.slug)]]' class='logo'></td>
|
icon='mdi:arrow-up-bold-circle'
|
||||||
</tr>
|
classname='update'
|
||||||
</template>
|
></hassio-item-info>
|
||||||
<tr>
|
</div>
|
||||||
<td>Description</td>
|
<div class='card-actions'>
|
||||||
<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]]'>
|
|
||||||
<ha-call-api-button
|
<ha-call-api-button
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
path="[[_pathStart(addonInfo.slug)]]"
|
path='hassio/addons/[[addonSlug]]/update'
|
||||||
>Start</ha-call-api-button>
|
>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>
|
||||||
<template is='dom-if' if='[[_isRunning]]'>
|
<template is='dom-if' if='[[addon.version]]'>
|
||||||
<template is='dom-if' if='[[addonState.webui]]'>
|
<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
|
<a
|
||||||
href='[[_pathWebui(addonState.webui)]]'
|
href='[[pathWebui(addon.webui)]]'
|
||||||
tabindex="-1"
|
tabindex='-1'
|
||||||
target="_blank"
|
target='_blank'
|
||||||
|
class='right'
|
||||||
><paper-button>Open web UI</paper-button></a>
|
><paper-button>Open web UI</paper-button></a>
|
||||||
</template>
|
</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>
|
||||||
<template is='dom-if' if='[[addonState.build]]'>
|
<template is='dom-if' if='[[!addon.version]]'>
|
||||||
<ha-call-api-button
|
<ha-call-api-button
|
||||||
class='warning'
|
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
path="[[_pathRebuild(addonInfo.slug)]]"
|
path='hassio/addons/[[addonSlug]]/install'
|
||||||
>Rebuild</ha-call-api-button>
|
>Install</ha-call-api-button>
|
||||||
</template>
|
</template>
|
||||||
<ha-call-api-button
|
|
||||||
class='warning'
|
|
||||||
hass='[[hass]]'
|
|
||||||
path="[[_pathUninstall(addonInfo.slug)]]"
|
|
||||||
>Uninstall</ha-call-api-button>
|
|
||||||
</div>
|
</div>
|
||||||
</paper-card>
|
</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>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
@ -185,68 +195,44 @@ class HassioAddonInfo extends Polymer.Element {
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
addonInfo: Object,
|
addon: Object,
|
||||||
addonState: Object,
|
addonSlug: String,
|
||||||
|
isRunning: {
|
||||||
_isRunning: {
|
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
computed: '_computeIsRunning(addonState)',
|
computed: 'computeIsRunning(addon)',
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeIsRunning(addonState) {
|
computeIsRunning(addon) {
|
||||||
return addonState && addonState.state === 'started';
|
return addon && addon.state === 'started';
|
||||||
}
|
}
|
||||||
|
|
||||||
_computeUpdateAvailable(data) {
|
computeUpdateAvailable(addon) {
|
||||||
return data && !data.detached && data.version !== data.last_version;
|
return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
|
||||||
}
|
}
|
||||||
|
|
||||||
_pathStart(addon) {
|
pathWebui(webui) {
|
||||||
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) {
|
|
||||||
return webui && webui.replace('[HOST]', document.location.hostname);
|
return webui && webui.replace('[HOST]', document.location.hostname);
|
||||||
}
|
}
|
||||||
|
|
||||||
_pathLogo(addon) {
|
computeShowWebUI(webui, isRunning) {
|
||||||
return '/api/hassio/addons/' + addon + '/logo';
|
return webui && isRunning;
|
||||||
}
|
}
|
||||||
|
|
||||||
_dataToggleAutoUpdate(addon, addonState) {
|
computeStartOnBoot(state) {
|
||||||
return addonState && { auto_update: !addonState.auto_update };
|
return state === 'auto';
|
||||||
}
|
}
|
||||||
|
|
||||||
_dataToggleBoot(addon, addonState) {
|
startOnBootToggled() {
|
||||||
return addonState && { boot: addonState.boot === 'manual' ? 'auto' : 'manual' };
|
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);
|
customElements.define(HassioAddonInfo.is, HassioAddonInfo);
|
||||||
</script>
|
</script>
|
||||||
|
@ -10,9 +10,9 @@
|
|||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<paper-card heading='Logs'>
|
<paper-card heading='Log'>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<pre>[[addonLogs]]</pre>
|
<pre>[[log]]</pre>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<paper-button on-tap='refresh'>Refresh</paper-button>
|
<paper-button on-tap='refresh'>Refresh</paper-button>
|
||||||
@ -27,25 +27,18 @@ class HassioAddonLogs extends Polymer.Element {
|
|||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: {
|
hass: Object,
|
||||||
type: Object,
|
addonSlug: {
|
||||||
},
|
|
||||||
|
|
||||||
addon: {
|
|
||||||
type: String,
|
type: String,
|
||||||
observer: 'addonChanged',
|
observer: 'addonSlugChanged',
|
||||||
},
|
|
||||||
|
|
||||||
addonLogs: {
|
|
||||||
type: String,
|
|
||||||
value: '',
|
|
||||||
},
|
},
|
||||||
|
log: String,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
addonChanged(addon) {
|
addonSlugChanged(slug) {
|
||||||
if (!this.hass) {
|
if (!this.hass) {
|
||||||
setTimeout(function () { this.addonChanged(addon); }.bind(this), 0);
|
setTimeout(() => { this.addonChanged(slug); }, 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -53,10 +46,10 @@ class HassioAddonLogs extends Polymer.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
refresh() {
|
refresh() {
|
||||||
this.hass.callApi('get', 'hassio/addons/' + this.addon + '/logs')
|
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/logs`)
|
||||||
.then(function (info) {
|
.then((info) => {
|
||||||
this.addonLogs = info;
|
this.log = info;
|
||||||
}.bind(this));
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -26,8 +26,8 @@
|
|||||||
</style>
|
</style>
|
||||||
<paper-card heading='Network'>
|
<paper-card heading='Network'>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<template is='dom-if' if='[[errors]]'>
|
<template is='dom-if' if='[[error]]'>
|
||||||
<div class='errors'>[[errors]]</div>
|
<div class='errors'>[[error]]</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<table>
|
<table>
|
||||||
@ -37,7 +37,7 @@
|
|||||||
</tr>
|
</tr>
|
||||||
<template
|
<template
|
||||||
is='dom-repeat'
|
is='dom-repeat'
|
||||||
items='[[_data]]'
|
items='[[config]]'
|
||||||
>
|
>
|
||||||
<tr>
|
<tr>
|
||||||
<td>
|
<td>
|
||||||
@ -53,16 +53,16 @@
|
|||||||
</template>
|
</template>
|
||||||
</table>
|
</table>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<paper-button
|
|
||||||
on-tap='_saveTapped'
|
|
||||||
>Save</paper-button>
|
|
||||||
<ha-call-api-button
|
<ha-call-api-button
|
||||||
class='warning'
|
class='warning'
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
path="[[_pathAddonOptions(addon)]]"
|
path="hassio/addons/[[addonSlug]]/options"
|
||||||
data="[[_resetData]]"
|
data="[[resetData]]"
|
||||||
>Reset</ha-call-api-button>
|
>Reset to defaults</ha-call-api-button>
|
||||||
|
<paper-button
|
||||||
|
on-tap='saveTapped'
|
||||||
|
>Save</paper-button>
|
||||||
</div>
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
</template>
|
</template>
|
||||||
@ -75,23 +75,14 @@ class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element)
|
|||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: Object,
|
hass: Object,
|
||||||
addon: String,
|
addonSlug: String,
|
||||||
errors: {
|
config: Object,
|
||||||
type: String,
|
addon: {
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
_data: {
|
|
||||||
type: Object,
|
type: Object,
|
||||||
value: [],
|
observer: 'addonChanged',
|
||||||
},
|
},
|
||||||
|
error: String,
|
||||||
addonState: {
|
resetData: {
|
||||||
type: Object,
|
|
||||||
observer: '_addonStateChanged',
|
|
||||||
},
|
|
||||||
|
|
||||||
_resetData: {
|
|
||||||
type: Object,
|
type: Object,
|
||||||
value: {
|
value: {
|
||||||
network: null,
|
network: null,
|
||||||
@ -100,38 +91,32 @@ class HassioAddonNetwork extends window.hassMixins.EventsMixin(Polymer.Element)
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
_addonStateChanged(addonState) {
|
addonChanged(addon) {
|
||||||
if (!addonState) return;
|
if (!addon) return;
|
||||||
|
|
||||||
var network = addonState.network || {};
|
const network = addon.network || {};
|
||||||
var items = Object.keys(network).map(function (key) {
|
const items = Object.keys(network).map(key => ({
|
||||||
return {
|
container: key,
|
||||||
container: key,
|
host: network[key]
|
||||||
host: '' + network[key]
|
}));
|
||||||
};
|
this.config = items.sort(function (el1, el2) { return el1.host - el2.host; });
|
||||||
});
|
|
||||||
this._data = items.sort(function (el1, el2) { return el1.host - el2.host; });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_saveTapped() {
|
saveTapped() {
|
||||||
this.errors = null;
|
this.error = null;
|
||||||
var toSend = {};
|
const data = {};
|
||||||
this._data.forEach(function (item) {
|
this.config.forEach(function (item) {
|
||||||
toSend[item.container] = parseInt(item.host);
|
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, {
|
this.hass.callApi('post', path, {
|
||||||
network: toSend
|
network: data
|
||||||
}).then(function () {
|
}).then(() => {
|
||||||
this.fire('hass-api-called', { success: true, path: path });
|
this.fire('hass-api-called', { success: true, path: path });
|
||||||
}.bind(this), function (resp) {
|
}, (resp) => {
|
||||||
this.errors = resp.body.message;
|
this.error = resp.body.message;
|
||||||
}.bind(this));
|
});
|
||||||
}
|
|
||||||
|
|
||||||
_pathAddonOptions(addon) {
|
|
||||||
return 'hassio/addons/' + addon + '/options';
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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-layout/app-toolbar/app-toolbar.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="../../src/components/ha-menu-button.html">
|
|
||||||
|
|
||||||
<link rel="import" href="./hassio-addon-info.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-network.html">
|
||||||
<link rel="import" href="./hassio-addon-logs.html">
|
<link rel="import" href="./hassio-addon-logs.html">
|
||||||
|
|
||||||
@ -16,7 +14,7 @@
|
|||||||
<style include="iron-flex ha-style">
|
<style include="iron-flex ha-style">
|
||||||
hassio-addon-info,
|
hassio-addon-info,
|
||||||
hassio-addon-network,
|
hassio-addon-network,
|
||||||
hassio-addon-options {
|
hassio-addon-config {
|
||||||
margin-bottom: 24px;
|
margin-bottom: 24px;
|
||||||
}
|
}
|
||||||
.content {
|
.content {
|
||||||
@ -27,8 +25,9 @@
|
|||||||
</style>
|
</style>
|
||||||
<app-route
|
<app-route
|
||||||
route='[[route]]'
|
route='[[route]]'
|
||||||
pattern='/addon/:addon'
|
pattern='/addon/:slug'
|
||||||
data="{{_routeData}}"
|
data="{{routeData}}"
|
||||||
|
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 slot="header" fixed>
|
||||||
@ -37,33 +36,37 @@
|
|||||||
icon='mdi:arrow-left'
|
icon='mdi:arrow-left'
|
||||||
on-tap='backTapped'
|
on-tap='backTapped'
|
||||||
></paper-icon-button>
|
></paper-icon-button>
|
||||||
<div main-title>[[addonInfo.name]]</div>
|
<div main-title>[[addon.name]]</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]]'
|
||||||
addon-info='[[addonInfo]]'
|
addon='[[addon]]'
|
||||||
addon-state='[[addonState]]'
|
addon-slug='[[routeData.slug]]'
|
||||||
></hassio-addon-info>
|
></hassio-addon-info>
|
||||||
|
|
||||||
<hassio-addon-options
|
<template is='dom-if' if='[[addon.version]]'>
|
||||||
hass='[[hass]]'
|
<hassio-addon-config
|
||||||
addon='[[_routeData.addon]]'
|
hass='[[hass]]'
|
||||||
addon-state='[[addonState]]'
|
addon='[[addon]]'
|
||||||
></hassio-addon-options>
|
addon-slug='[[routeData.slug]]'
|
||||||
|
></hassio-addon-config>
|
||||||
|
|
||||||
<hassio-addon-network
|
<template is='dom-if' if='[[addon.network]]'>
|
||||||
hass='[[hass]]'
|
<hassio-addon-network
|
||||||
addon='[[_routeData.addon]]'
|
hass='[[hass]]'
|
||||||
addon-state='[[addonState]]'
|
addon='[[addon]]'
|
||||||
></hassio-addon-network>
|
addon-slug='[[routeData.slug]]'
|
||||||
|
></hassio-addon-network>
|
||||||
|
</template>
|
||||||
|
|
||||||
<hassio-addon-logs
|
<hassio-addon-logs
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
addon='[[_routeData.addon]]'
|
addon-slug='[[routeData.slug]]'
|
||||||
></hassio-addon-logs>
|
></hassio-addon-logs>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</app-header-layout>
|
</app-header-layout>
|
||||||
</template>
|
</template>
|
||||||
@ -75,34 +78,14 @@ class HassioAddonView extends Polymer.Element {
|
|||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
return {
|
return {
|
||||||
hass: {
|
hass: Object,
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
route: Object,
|
route: Object,
|
||||||
_routeData: {
|
routeData: {
|
||||||
type: Object,
|
type: Object,
|
||||||
observer: '_routeDataChanged',
|
observer: 'routeDataChanged',
|
||||||
},
|
|
||||||
|
|
||||||
supervisorInfo: {
|
|
||||||
type: Object,
|
|
||||||
},
|
|
||||||
|
|
||||||
addonInfo: {
|
|
||||||
type: Object,
|
|
||||||
computed: 'computeAddonInfo(supervisorInfo, _routeData.addon)',
|
|
||||||
},
|
|
||||||
|
|
||||||
addonState: {
|
|
||||||
type: Object,
|
|
||||||
value: null,
|
|
||||||
},
|
|
||||||
|
|
||||||
addonLogs: {
|
|
||||||
type: String,
|
|
||||||
value: '',
|
|
||||||
},
|
},
|
||||||
|
routeMatches: Boolean,
|
||||||
|
addon: Object,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -112,35 +95,25 @@ class HassioAddonView extends Polymer.Element {
|
|||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
var path = ev.detail.path;
|
const path = ev.detail.path;
|
||||||
|
|
||||||
if (!path) return;
|
if (!path) return;
|
||||||
|
|
||||||
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
|
||||||
this.backTapped();
|
this.backTapped();
|
||||||
} else {
|
} else {
|
||||||
this._routeDataChanged(this._routeData);
|
this.routeDataChanged(this.routeData);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
_routeDataChanged(routeData) {
|
routeDataChanged(routeData) {
|
||||||
if (!routeData || !routeData.addon) return;
|
if (!this.routeMatches || !routeData || !routeData.slug) return;
|
||||||
this.hass.callApi('get', 'hassio/addons/' + routeData.addon + '/info')
|
this.hass.callApi('get', `hassio/addons/${routeData.slug}/info`)
|
||||||
.then(function (info) {
|
.then((info) => {
|
||||||
this.addonState = info.data;
|
this.addon = info.data;
|
||||||
}.bind(this), function () {
|
}, () => {
|
||||||
this.addonState = null;
|
this.addon = 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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
backTapped() {
|
backTapped() {
|
||||||
|
@ -54,9 +54,6 @@
|
|||||||
page-name='addon'
|
page-name='addon'
|
||||||
route='[[route]]'
|
route='[[route]]'
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
supervisor-info='[[supervisorInfo]]'
|
|
||||||
host-info='[[hostInfo]]'
|
|
||||||
addon='[[addon]]'
|
|
||||||
></hassio-addon-view>
|
></hassio-addon-view>
|
||||||
|
|
||||||
<hassio-addon-store
|
<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