mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-13 12:26:35 +00:00
Add addon store
This commit is contained in:
parent
ce95af99fe
commit
110f152e23
70
panels/hassio/addon-store/hassio-addon-repository.html
Normal file
70
panels/hassio/addon-store/hassio-addon-repository.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-item/paper-item-body.html">
|
||||||
|
|
||||||
|
<dom-module id="hassio-addon-repository">
|
||||||
|
<template>
|
||||||
|
<style include="iron-flex ha-style">
|
||||||
|
:host,
|
||||||
|
paper-card {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
paper-item {
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<paper-card heading='[[repo.name]]'>
|
||||||
|
<template is='dom-if' if='[[computeShowIntro(repo)]]'>
|
||||||
|
<div class='card-content'>
|
||||||
|
<template is='dom-if' if='[[repo.maintainer]]'>
|
||||||
|
Maintained by [[repo.maintainer]].
|
||||||
|
</template>
|
||||||
|
<template is='dom-if' if='[[repo.url]]'>
|
||||||
|
<a href='[[repo.url]]' target='_blank'>Visit repository website.</a>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template is='dom-repeat' items='[[addons]]' 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>
|
||||||
|
</paper-card>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'hassio-addon-repository',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
repo: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
addons: {
|
||||||
|
type: Array,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
computeShowIntro: function (repo) {
|
||||||
|
return repo.url || repo.maintainer;
|
||||||
|
},
|
||||||
|
|
||||||
|
computeInstallStatus: function (addon) {
|
||||||
|
return addon.installed || 'Not installed';
|
||||||
|
},
|
||||||
|
|
||||||
|
addonTapped: function (ev) {
|
||||||
|
this.fire('hassio-select-addon', { addon: this.addons[ev.model.index].slug });
|
||||||
|
ev.target.blur();
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
141
panels/hassio/addon-store/hassio-addon-store.html
Normal file
141
panels/hassio/addon-store/hassio-addon-store.html
Normal file
@ -0,0 +1,141 @@
|
|||||||
|
<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="../../../src/components/ha-menu-button.html">
|
||||||
|
|
||||||
|
<link rel="import" href="./hassio-repositories-editor.html">
|
||||||
|
<link rel="import" href="./hassio-addon-repository.html">
|
||||||
|
|
||||||
|
<dom-module id="hassio-addon-store">
|
||||||
|
<template>
|
||||||
|
<style include="iron-flex ha-style">
|
||||||
|
paper-card {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
.content {
|
||||||
|
padding: 24px 0 32px;
|
||||||
|
max-width: 600px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
hassio-addon-repository {
|
||||||
|
margin-top: 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>Hass.io Add-Ons</div>
|
||||||
|
<paper-icon-button
|
||||||
|
icon="mdi:refresh"
|
||||||
|
on-tap="refreshTapped"
|
||||||
|
></paper-icon-button>
|
||||||
|
</app-toolbar>
|
||||||
|
</app-header>
|
||||||
|
|
||||||
|
<div class='content'>
|
||||||
|
<hassio-repositories-editor
|
||||||
|
hass='[[hass]]'
|
||||||
|
repos='[[supervisorInfo.addons_repositories]]'
|
||||||
|
></hassio-repositories-editor>
|
||||||
|
<template is='dom-repeat' items='[[repos]]' as='repo'>
|
||||||
|
<hassio-addon-repository
|
||||||
|
repo='[[repo]]'
|
||||||
|
addons='[[computeAddOns(repo.slug)]]'
|
||||||
|
></hassio-addon-repository>
|
||||||
|
</template>
|
||||||
|
</div>
|
||||||
|
</app-header-layout>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
_coreRepos: [{
|
||||||
|
slug: 'core',
|
||||||
|
name: 'Built-in Add-Ons',
|
||||||
|
url: 'https://home-assistant.io/addons',
|
||||||
|
maintainer: 'Home Assistant authors',
|
||||||
|
}],
|
||||||
|
|
||||||
|
is: 'hassio-addon-store',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
narrow: {
|
||||||
|
type: Boolean,
|
||||||
|
},
|
||||||
|
|
||||||
|
showMenu: {
|
||||||
|
type: Boolean,
|
||||||
|
value: false,
|
||||||
|
},
|
||||||
|
|
||||||
|
addons: {
|
||||||
|
type: Array,
|
||||||
|
value: [],
|
||||||
|
},
|
||||||
|
|
||||||
|
repos: {
|
||||||
|
type: Array,
|
||||||
|
value: []
|
||||||
|
},
|
||||||
|
|
||||||
|
supervisorInfo: {
|
||||||
|
type: Object,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
listeners: {
|
||||||
|
'hass-api-called': 'apiCalled',
|
||||||
|
},
|
||||||
|
|
||||||
|
apiCalled: function (ev) {
|
||||||
|
if (ev.detail.success) {
|
||||||
|
this.loadData();
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
attached: function () {
|
||||||
|
this.loadData();
|
||||||
|
},
|
||||||
|
|
||||||
|
loadData: function () {
|
||||||
|
this.hass.callApi('get', 'hassio/supervisor/addons')
|
||||||
|
.then(function (info) {
|
||||||
|
this.addons = info.data.addons;
|
||||||
|
this.repos = this._coreRepos.concat(info.data.repositories);
|
||||||
|
}.bind(this), function () {
|
||||||
|
this.addons = [];
|
||||||
|
this.repos = [];
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
computeAddOns: function (repo) {
|
||||||
|
return this.addons.filter(function (addon) {
|
||||||
|
return addon.repository === repo;
|
||||||
|
});
|
||||||
|
},
|
||||||
|
|
||||||
|
refreshTapped: function () {
|
||||||
|
this.hass.callApi('post', 'hassio/supervisor/reload')
|
||||||
|
.then(function () {
|
||||||
|
this.loadData();
|
||||||
|
}.bind(this));
|
||||||
|
},
|
||||||
|
|
||||||
|
backTapped: function () {
|
||||||
|
this.fire('hassio-select-addon', { addon: null });
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
67
panels/hassio/addon-store/hassio-repositories-editor.html
Normal file
67
panels/hassio/addon-store/hassio-repositories-editor.html
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<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/iron-autogrow-textarea/iron-autogrow-textarea.html">
|
||||||
|
|
||||||
|
<link rel="import" href="../../../src/components/buttons/ha-call-api-button.html">
|
||||||
|
|
||||||
|
<dom-module id="hassio-repositories-editor">
|
||||||
|
<template>
|
||||||
|
<style include="ha-style">
|
||||||
|
:host {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
paper-card {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
iron-autogrow-textarea {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<paper-card heading='Add-On Repositories'>
|
||||||
|
<div class="card-content">
|
||||||
|
<p>Configure which add-on repositories to fetch data from. One repository per line.</p>
|
||||||
|
<iron-autogrow-textarea value="{{options}}"></iron-autogrow-textarea>
|
||||||
|
</div>
|
||||||
|
<div class="card-actions">
|
||||||
|
<ha-call-api-button
|
||||||
|
hass='[[hass]]'
|
||||||
|
data='[[computeOptionsData(options)]]'
|
||||||
|
path="hassio/supervisor/options"
|
||||||
|
>Save</ha-call-api-button>
|
||||||
|
</div>
|
||||||
|
</paper-card>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
Polymer({
|
||||||
|
is: 'hassio-repositories-editor',
|
||||||
|
|
||||||
|
properties: {
|
||||||
|
hass: {
|
||||||
|
type: Object,
|
||||||
|
},
|
||||||
|
|
||||||
|
options: {
|
||||||
|
type: String,
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
|
|
||||||
|
repos: {
|
||||||
|
type: Array,
|
||||||
|
value: [],
|
||||||
|
observer: 'reposChanged',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
|
||||||
|
reposChanged: function (repos) {
|
||||||
|
this.options = repos.join('\n');
|
||||||
|
},
|
||||||
|
|
||||||
|
computeOptionsData: function (options) {
|
||||||
|
return {
|
||||||
|
addons_repositories: options.split('\n'),
|
||||||
|
};
|
||||||
|
},
|
||||||
|
});
|
||||||
|
</script>
|
@ -24,7 +24,7 @@
|
|||||||
</style>
|
</style>
|
||||||
<paper-card heading='Info'>
|
<paper-card heading='Info'>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
<div>[[addonInfo.description]]</div>
|
<p>[[addonInfo.description]]</p>
|
||||||
<table class='info'>
|
<table class='info'>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Installed</td>
|
<td>Installed</td>
|
||||||
|
@ -17,17 +17,15 @@
|
|||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<paper-card heading="Installed Addons">
|
<paper-card heading="Installed Addons">
|
||||||
<div class="card-content">
|
<template is='dom-repeat' items='[[data]]' as='addon'>
|
||||||
<template is='dom-repeat' items='[[data]]' as='addon'>
|
<paper-item>
|
||||||
<paper-item>
|
<paper-item-body two-line on-tap='addonTapped'>
|
||||||
<paper-item-body two-line on-tap='addonTapped'>
|
<div>[[addon.name]]</div>
|
||||||
<div>[[addon.name]]</div>
|
<div secondary>[[addon.description]]</div>
|
||||||
<div secondary>[[addon.description]]</div>
|
</paper-item-body>
|
||||||
</paper-item-body>
|
[[addon.installed]]
|
||||||
[[computeInstallStatus(addon)]]
|
</paper-item>
|
||||||
</paper-item>
|
</template>
|
||||||
</template>
|
|
||||||
</div>
|
|
||||||
</paper-card>
|
</paper-card>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
@ -56,10 +54,6 @@ Polymer({
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
computeInstallStatus(addon) {
|
|
||||||
return addon.installed || 'Not installed';
|
|
||||||
},
|
|
||||||
|
|
||||||
addonTapped: function (ev) {
|
addonTapped: function (ev) {
|
||||||
this.fire('hassio-select-addon', { addon: this.data[ev.model.index].slug });
|
this.fire('hassio-select-addon', { addon: this.data[ev.model.index].slug });
|
||||||
ev.target.blur();
|
ev.target.blur();
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
<link rel="import" href="../../../bower_components/app-layout/app-header/app-header.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/app-layout/app-toolbar/app-toolbar.html">
|
||||||
<link rel="import" href="../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
<link rel="import" href="../../../bower_components/iron-flex-layout/iron-flex-layout-classes.html">
|
||||||
|
<link rel="import" href="../../../bower_components/paper-icon-button/paper-icon-button.html">
|
||||||
|
|
||||||
<link rel="import" href="../../../src/components/ha-menu-button.html">
|
<link rel="import" href="../../../src/components/ha-menu-button.html">
|
||||||
|
|
||||||
@ -36,6 +37,10 @@
|
|||||||
<app-toolbar>
|
<app-toolbar>
|
||||||
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
<ha-menu-button narrow='[[narrow]]' show-menu='[[showMenu]]'></ha-menu-button>
|
||||||
<div main-title>Hass.io</div>
|
<div main-title>Hass.io</div>
|
||||||
|
<paper-icon-button
|
||||||
|
icon="mdi:shopping"
|
||||||
|
on-tap="storeTapped"
|
||||||
|
></paper-icon-button>
|
||||||
</app-toolbar>
|
</app-toolbar>
|
||||||
</app-header>
|
</app-header>
|
||||||
|
|
||||||
@ -100,5 +105,9 @@ Polymer({
|
|||||||
value: {},
|
value: {},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
storeTapped: function () {
|
||||||
|
this.fire('hassio-show-store');
|
||||||
|
},
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
<link rel="import" href="./dashboard/hassio-dashboard.html">
|
<link rel="import" href="./dashboard/hassio-dashboard.html">
|
||||||
<link rel="import" href="./addon-view/hassio-addon-view.html">
|
<link rel="import" href="./addon-view/hassio-addon-view.html">
|
||||||
|
<link rel="import" href="./addon-store/hassio-addon-store.html">
|
||||||
<link rel="import" href="./hassio-loading.html">
|
<link rel="import" href="./hassio-loading.html">
|
||||||
<link rel="import" href="./hassio-data.html">
|
<link rel="import" href="./hassio-data.html">
|
||||||
|
|
||||||
@ -20,34 +21,42 @@
|
|||||||
host='{{hostInfo}}'
|
host='{{hostInfo}}'
|
||||||
></hassio-data>
|
></hassio-data>
|
||||||
|
|
||||||
<template is='dom-if' if='[[!loaded]]'>
|
<template is='dom-if' if='[[dashboardSelected(currentPage)]]'>
|
||||||
<hassio-loading
|
<template is='dom-if' if='[[!loaded]]'>
|
||||||
narrow='[[narrow]]'
|
<hassio-loading
|
||||||
hass='[[hass]]'
|
narrow='[[narrow]]'
|
||||||
show-menu='[[showMenu]]'
|
|
||||||
></hassio-loading>
|
|
||||||
</template>
|
|
||||||
<template is='dom-if' if='[[loaded]]' restamp>
|
|
||||||
<template is='dom-if' if='[[addon]]'>
|
|
||||||
<hassio-addon-view
|
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
supervisor-info='[[supervisorInfo]]'
|
show-menu='[[showMenu]]'
|
||||||
host-info='[[hostInfo]]'
|
></hassio-loading>
|
||||||
addon='[[addon]]'
|
|
||||||
></hassio-addon-view>
|
|
||||||
</template>
|
</template>
|
||||||
|
<template is='dom-if' if='[[loaded]]'>
|
||||||
<template is='dom-if' if='[[!addon]]'>
|
|
||||||
<hassio-dashboard
|
<hassio-dashboard
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
narrow='[[narrow]]'
|
narrow='[[narrow]]'
|
||||||
show-menu='[[showMenu]]'
|
show-menu='[[showMenu]]'
|
||||||
supervisor-info='{{supervisorInfo}}'
|
supervisor-info='[[supervisorInfo]]'
|
||||||
host-info='{{hostInfo}}'
|
host-info='[[hostInfo]]'
|
||||||
hass-info='[[hassInfo]]'
|
hass-info='[[hassInfo]]'
|
||||||
></hassio-dashboard>
|
></hassio-dashboard>
|
||||||
</template>
|
</template>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
<template is='dom-if' if='[[addonViewSelected(currentPage)]]' restamp>
|
||||||
|
<hassio-addon-view
|
||||||
|
hass='[[hass]]'
|
||||||
|
supervisor-info='[[supervisorInfo]]'
|
||||||
|
host-info='[[hostInfo]]'
|
||||||
|
addon='[[addon]]'
|
||||||
|
></hassio-addon-view>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<template is='dom-if' if='[[addonStoreSelected(currentPage)]]'>
|
||||||
|
<hassio-addon-store
|
||||||
|
id='addon-store'
|
||||||
|
hass='[[hass]]'
|
||||||
|
supervisor-info='[[supervisorInfo]]'
|
||||||
|
></hassio-addon-store>
|
||||||
|
</template>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
@ -97,16 +106,29 @@ Polymer({
|
|||||||
loaded: {
|
loaded: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo, forceLoading)',
|
computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo, forceLoading)',
|
||||||
}
|
},
|
||||||
|
|
||||||
|
currentPage: {
|
||||||
|
type: String,
|
||||||
|
value: 'dashboard',
|
||||||
|
},
|
||||||
|
|
||||||
|
lastPage: {
|
||||||
|
type: String,
|
||||||
|
value: 'dashboard',
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
listeners: {
|
listeners: {
|
||||||
'hassio-select-addon': 'addonSelected',
|
'hassio-select-addon': 'addonSelected',
|
||||||
|
'hassio-show-store': 'showStore',
|
||||||
'hass-api-called': 'apiCalled',
|
'hass-api-called': 'apiCalled',
|
||||||
},
|
},
|
||||||
|
|
||||||
apiCalled: function () {
|
apiCalled: function (ev) {
|
||||||
this.$.data.refresh();
|
if (ev.detail.success) {
|
||||||
|
this.$.data.refresh();
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
computeIsLoaded: function (supervisorInfo, hostInfo, hassInfo, forceLoading) {
|
computeIsLoaded: function (supervisorInfo, hostInfo, hassInfo, forceLoading) {
|
||||||
@ -117,11 +139,40 @@ Polymer({
|
|||||||
},
|
},
|
||||||
|
|
||||||
addonSelected: function (ev) {
|
addonSelected: function (ev) {
|
||||||
this.forceLoading = true;
|
var addon = ev.detail.addon;
|
||||||
setTimeout(function () {
|
|
||||||
this.addon = ev.detail.addon;
|
if (this.currentPage === this.lastPage) {
|
||||||
this.forceLoading = false;
|
this.lastPage = 'dashboard';
|
||||||
}.bind(this), 0);
|
}
|
||||||
|
|
||||||
|
if (addon) {
|
||||||
|
this.lastPage = this.currentPage;
|
||||||
|
this.currentPage = 'addon-view';
|
||||||
|
this.addon = addon;
|
||||||
|
} else {
|
||||||
|
this.currentPage = this.lastPage;
|
||||||
|
// Give time to cleanup the addon-view panel or it crashes
|
||||||
|
setTimeout(function () {
|
||||||
|
this.addon = addon;
|
||||||
|
}.bind(this), 0);
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
showStore: function () {
|
||||||
|
this.currentPage = 'addon-store';
|
||||||
|
},
|
||||||
|
|
||||||
|
dashboardSelected: function (currentPage) {
|
||||||
|
return currentPage === 'dashboard';
|
||||||
|
},
|
||||||
|
|
||||||
|
addonStoreSelected: function (currentPage) {
|
||||||
|
return currentPage === 'addon-store';
|
||||||
|
},
|
||||||
|
|
||||||
|
addonViewSelected: function (currentPage) {
|
||||||
|
return currentPage === 'addon-view';
|
||||||
|
},
|
||||||
|
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user