[[repo.name]]
-
-
-
-
-
-
+`;
+ }
-
diff --git a/hassio/addon-store/hassio-addon-store.html b/hassio/addon-store/hassio-addon-store.js
similarity index 65%
rename from hassio/addon-store/hassio-addon-store.html
rename to hassio/addon-store/hassio-addon-store.js
index af16f17be2..4ba6738e2c 100644
--- a/hassio/addon-store/hassio-addon-store.html
+++ b/hassio/addon-store/hassio-addon-store.js
@@ -1,33 +1,26 @@
-
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
+import '../../src/util/hass-mixins.js';
+import './hassio-addon-repository.js';
+import './hassio-repositories-editor.js';
-
-
-
-
-
+class HassioAddonStore extends PolymerElement {
+ static get template() {
+ return html`
-
+
-
-
+
+
-
-
+`;
+ }
-
diff --git a/hassio/addon-store/hassio-repositories-editor.html b/hassio/addon-store/hassio-repositories-editor.html
deleted file mode 100644
index 887d4fcbdc..0000000000
--- a/hassio/addon-store/hassio-repositories-editor.html
+++ /dev/null
@@ -1,108 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Repositories
-
- Configure which add-on repositories to fetch data from:
-
-
-
-
-
-
-
-
- Remove
-
-
-
-
-
-
- Add
-
-
-
-
-
-
-
diff --git a/hassio/addon-store/hassio-repositories-editor.js b/hassio/addon-store/hassio-repositories-editor.js
new file mode 100644
index 0000000000..caf902abd5
--- /dev/null
+++ b/hassio/addon-store/hassio-repositories-editor.js
@@ -0,0 +1,93 @@
+import '@polymer/iron-icon/iron-icon.js';
+import '@polymer/paper-card/paper-card.js';
+import '@polymer/paper-input/paper-input.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../src/components/buttons/ha-call-api-button.js';
+import '../../src/components/hassio-card-content.js';
+import '../../src/resources/hassio-style.js';
+
+class HassioRepositoriesEditor extends PolymerElement {
+ static get template() {
+ return html`
+
+
+
+ Repositories
+
+ Configure which add-on repositories to fetch data from:
+
+
+
+
+
+
+
+
+ Remove
+
+
+
+
+
+
+ Add
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-repositories-editor'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ repos: {
+ type: Array,
+ observer: 'reposChanged',
+ },
+ repoList: Array,
+ repoUrl: String,
+ };
+ }
+
+ reposChanged(repos) {
+ this.repoList = repos.filter(repo => repo.slug !== 'core' && repo.slug !== 'local');
+ this.repoUrl = '';
+ }
+
+ sortRepos(a, b) {
+ return a.name < b.name ? -1 : 1;
+ }
+
+ computeRemoveRepoData(repoList, url) {
+ const list = repoList.filter(repo => repo.url !== url).map(repo => repo.url);
+ return { addons_repositories: list };
+ }
+
+ computeAddRepoData(repoList, url) {
+ const list = repoList.map(repo => repo.url);
+ list.push(url);
+ return { addons_repositories: list };
+ }
+}
+
+customElements.define(HassioRepositoriesEditor.is, HassioRepositoriesEditor);
diff --git a/hassio/addon-view/hassio-addon-audio.html b/hassio/addon-view/hassio-addon-audio.js
similarity index 66%
rename from hassio/addon-view/hassio-addon-audio.html
rename to hassio/addon-view/hassio-addon-audio.js
index ca1d7a1d5c..892aa4e290 100644
--- a/hassio/addon-view/hassio-addon-audio.html
+++ b/hassio/addon-view/hassio-addon-audio.js
@@ -1,16 +1,19 @@
-
-
-
-
-
-
-
+import 'web-animations-js/web-animations-next-lite.min.js';
-
-
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-card/paper-card.js';
+import '@polymer/paper-dropdown-menu/paper-dropdown-menu.js';
+import '@polymer/paper-item/paper-item.js';
+import '@polymer/paper-listbox/paper-listbox.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
-
+import '../../src/resources/ha-style.js';
+import '../../src/util/hass-mixins.js';
+
+class HassioAddonAudio extends window.hassMixins.EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
-
+
-
- [[error]]
+
+ [[error]]
-
+
-
- [[item.name]]
+
+ [[item.name]]
-
- [[item.name]]
+
+ [[item.name]]
-
-
+`;
+ }
-
diff --git a/hassio/addon-view/hassio-addon-config.html b/hassio/addon-view/hassio-addon-config.js
similarity index 61%
rename from hassio/addon-view/hassio-addon-config.html
rename to hassio/addon-view/hassio-addon-config.js
index a168ae48a6..943ea18de3 100644
--- a/hassio/addon-view/hassio-addon-config.html
+++ b/hassio/addon-view/hassio-addon-config.js
@@ -1,12 +1,14 @@
-
-
-
-
+import '@polymer/iron-autogrow-textarea/iron-autogrow-textarea.js';
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
+import '../../src/components/buttons/ha-call-api-button.js';
-
-
+class HassioAddonConfig extends PolymerElement {
+ static get template() {
+ return html`
-
+
-
- [[error]]
+
+ [[error]]
-
+
-
Reset to defaults
-
Save
+
Reset to defaults
+
Save
-
-
+`;
+ }
-
diff --git a/hassio/addon-view/hassio-addon-info.html b/hassio/addon-view/hassio-addon-info.html
deleted file mode 100644
index bfb8b9e4ba..0000000000
--- a/hassio/addon-view/hassio-addon-info.html
+++ /dev/null
@@ -1,275 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Update
-
- Changelog
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Uninstall
-
- Rebuild
-
-
- Restart
- Stop
-
-
- Start
-
-
- Open web UI
-
-
-
- Install
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/addon-view/hassio-addon-info.js b/hassio/addon-view/hassio-addon-info.js
new file mode 100644
index 0000000000..2e185f9f3c
--- /dev/null
+++ b/hassio/addon-view/hassio-addon-info.js
@@ -0,0 +1,225 @@
+import '@polymer/iron-icon/iron-icon.js';
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-card/paper-card.js';
+import '@polymer/paper-toggle-button/paper-toggle-button.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../src/components/buttons/ha-call-api-button.js';
+import '../../src/components/ha-markdown.js';
+import '../../src/components/hassio-card-content.js';
+import '../../src/resources/ha-style.js';
+import '../../src/util/hass-mixins.js';
+
+class HassioAddonInfo extends window.hassMixins.EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
+
+
+
+
+
+
+
+
Update
+
+ Changelog
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ Uninstall
+
+ Rebuild
+
+
+ Restart
+ Stop
+
+
+ Start
+
+
+ Open web UI
+
+
+
+ Install
+
+
+
+
+
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-addon-info'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ addon: Object,
+ addonSlug: String,
+ isRunning: {
+ type: Boolean,
+ computed: 'computeIsRunning(addon)',
+ },
+ };
+ }
+
+ computeIsRunning(addon) {
+ return addon && addon.state === 'started';
+ }
+
+ computeUpdateAvailable(addon) {
+ return addon && !addon.detached && addon.version && addon.version !== addon.last_version;
+ }
+
+ pathWebui(webui) {
+ return webui && webui.replace('[HOST]', document.location.hostname);
+ }
+
+ computeShowWebUI(webui, isRunning) {
+ return webui && isRunning;
+ }
+
+ computeStartOnBoot(state) {
+ return state === 'auto';
+ }
+
+ 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);
+ }
+
+ openChangelog() {
+ this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
+ .then(
+ resp => resp
+ , () => 'Error getting changelog'
+ ).then((content) => {
+ this.fire('hassio-markdown-dialog', {
+ title: 'Changelog',
+ content: content,
+ });
+ });
+ }
+
+ _unistallClicked() {
+ if (!confirm('Are you sure you want to uninstall this add-on?')) {
+ return;
+ }
+ const path = `hassio/addons/${this.addonSlug}/uninstall`;
+ const eventData = {
+ path: path,
+ };
+ this.hass.callApi('post', path).then((resp) => {
+ eventData.success = true;
+ eventData.response = resp;
+ }, (resp) => {
+ eventData.success = false;
+ eventData.response = resp;
+ }).then(() => {
+ this.fire('hass-api-called', eventData);
+ });
+ }
+}
+customElements.define(HassioAddonInfo.is, HassioAddonInfo);
diff --git a/hassio/addon-view/hassio-addon-logs.html b/hassio/addon-view/hassio-addon-logs.js
similarity index 61%
rename from hassio/addon-view/hassio-addon-logs.html
rename to hassio/addon-view/hassio-addon-logs.js
index 40d8473dfe..c670237427 100644
--- a/hassio/addon-view/hassio-addon-logs.html
+++ b/hassio/addon-view/hassio-addon-logs.js
@@ -1,30 +1,30 @@
-
-
-
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
+import '../../src/resources/ha-style.js';
-
-
+class HassioAddonLogs extends PolymerElement {
+ static get template() {
+ return html`
-
+
-
-
+`;
+ }
-
diff --git a/hassio/addon-view/hassio-addon-network.html b/hassio/addon-view/hassio-addon-network.js
similarity index 61%
rename from hassio/addon-view/hassio-addon-network.html
rename to hassio/addon-view/hassio-addon-network.js
index 43afede6a4..37579a87db 100644
--- a/hassio/addon-view/hassio-addon-network.html
+++ b/hassio/addon-view/hassio-addon-network.js
@@ -1,14 +1,15 @@
-
-
-
+import '@polymer/paper-card/paper-card.js';
+import '@polymer/paper-input/paper-input.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
-
+import '../../src/components/buttons/ha-call-api-button.js';
+import '../../src/resources/ha-style.js';
+import '../../src/util/hass-mixins.js';
-
-
-
-
+class HassioAddonNetwork extends window.hassMixins.EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
-
+
-
- [[error]]
+
+ [[error]]
-
+
Container |
Host |
-
+
[[item.container]]
|
-
+
|
-
+
-
Reset to defaults
-
Save
+
Reset to defaults
+
Save
-
-
+`;
+ }
-
diff --git a/hassio/addon-view/hassio-addon-view.html b/hassio/addon-view/hassio-addon-view.html
deleted file mode 100644
index 75cc8a028c..0000000000
--- a/hassio/addon-view/hassio-addon-view.html
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Hass.io: add-on details
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/addon-view/hassio-addon-view.js b/hassio/addon-view/hassio-addon-view.js
new file mode 100644
index 0000000000..68e6792c94
--- /dev/null
+++ b/hassio/addon-view/hassio-addon-view.js
@@ -0,0 +1,134 @@
+import '@polymer/app-layout/app-header-layout/app-header-layout.js';
+import '@polymer/app-layout/app-header/app-header.js';
+import '@polymer/app-layout/app-toolbar/app-toolbar.js';
+import '@polymer/app-route/app-route.js';
+import '@polymer/paper-icon-button/paper-icon-button.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../src/components/ha-menu-button.js';
+import '../../src/resources/ha-style.js';
+import '../hassio-markdown-dialog.js';
+import './hassio-addon-audio.js';
+import './hassio-addon-config.js';
+import './hassio-addon-info.js';
+import './hassio-addon-logs.js';
+import './hassio-addon-network.js';
+
+class HassioAddonView extends PolymerElement {
+ static get template() {
+ return html`
+
+
+
+
+
+
+
+ Hass.io: add-on details
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-addon-view'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ showMenu: Boolean,
+ narrow: Boolean,
+ route: Object,
+ routeData: {
+ type: Object,
+ observer: 'routeDataChanged',
+ },
+ routeMatches: Boolean,
+ addon: Object,
+
+ markdownTitle: String,
+ markdownContent: {
+ type: String,
+ value: '',
+ },
+ };
+ }
+
+ ready() {
+ super.ready();
+ this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
+ this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
+ }
+
+ apiCalled(ev) {
+ const path = ev.detail.path;
+
+ if (!path) return;
+
+ if (path.substr(path.lastIndexOf('/') + 1) === 'uninstall') {
+ this.backTapped();
+ } else {
+ this.routeDataChanged(this.routeData);
+ }
+ }
+
+ 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() {
+ history.back();
+ }
+
+ openMarkdown(ev) {
+ this.setProperties({
+ markdownTitle: ev.detail.title,
+ markdownContent: ev.detail.content,
+ });
+ this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
+ }
+}
+
+customElements.define(HassioAddonView.is, HassioAddonView);
diff --git a/hassio/dashboard/hassio-addons.html b/hassio/dashboard/hassio-addons.js
similarity index 50%
rename from hassio/dashboard/hassio-addons.html
rename to hassio/dashboard/hassio-addons.js
index 51ae65ceb5..c120d7c30e 100644
--- a/hassio/dashboard/hassio-addons.html
+++ b/hassio/dashboard/hassio-addons.js
@@ -1,45 +1,39 @@
-
-
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
-
-
+import '../../src/components/hassio-card-content.js';
+import '../../src/resources/hassio-style.js';
+import '../../src/util/hass-mixins.js';
-
-
-
-
-
Add-ons
-
+
+
Add-ons
+
-
- You don't have any add-ons installed yet. Head over to
the add-on store to get started!
+
+ You don't have any add-ons installed yet. Head over to
the add-on store to get started!
-
-
-
-
-
+`;
+ }
-
diff --git a/hassio/dashboard/hassio-dashboard.html b/hassio/dashboard/hassio-dashboard.html
deleted file mode 100644
index 4aee9948ed..0000000000
--- a/hassio/dashboard/hassio-dashboard.html
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/dashboard/hassio-dashboard.js b/hassio/dashboard/hassio-dashboard.js
new file mode 100644
index 0000000000..0496d76266
--- /dev/null
+++ b/hassio/dashboard/hassio-dashboard.js
@@ -0,0 +1,33 @@
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import './hassio-addons.js';
+import './hassio-hass-update.js';
+
+class HassioDashboard extends window.hassMixins.EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-dashboard'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ supervisorInfo: Object,
+ hassInfo: Object,
+ };
+ }
+}
+
+customElements.define(HassioDashboard.is, HassioDashboard);
diff --git a/hassio/dashboard/hassio-hass-update.html b/hassio/dashboard/hassio-hass-update.html
deleted file mode 100644
index 9fb6874907..0000000000
--- a/hassio/dashboard/hassio-hass-update.html
+++ /dev/null
@@ -1,93 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
Update available! 🎉
-
-
-
-
- Error: [[error]]
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/dashboard/hassio-hass-update.js b/hassio/dashboard/hassio-hass-update.js
new file mode 100644
index 0000000000..a2ec355f0d
--- /dev/null
+++ b/hassio/dashboard/hassio-hass-update.js
@@ -0,0 +1,81 @@
+import '@polymer/paper-button/paper-button.js';
+import '@polymer/paper-card/paper-card.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../../src/components/buttons/ha-call-api-button.js';
+import '../../src/components/hassio-card-content.js';
+import '../../src/resources/hassio-style.js';
+
+class HassioHassUpdate extends PolymerElement {
+ static get template() {
+ return html`
+
+
+
+
+
Update available! 🎉
+
+
+
+
+ Error: [[error]]
+
+
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-hass-update'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ hassInfo: Object,
+ error: String,
+ };
+ }
+
+ ready() {
+ super.ready();
+ this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
+ }
+
+ apiCalled(ev) {
+ if (ev.detail.success) {
+ this.errors = null;
+ return;
+ }
+
+ const response = ev.detail.response;
+
+ if (typeof response.body === 'object') {
+ this.errors = response.body.message || 'Unknown error';
+ } else {
+ this.errors = response.body;
+ }
+ }
+
+ computeUpdateAvailable(hassInfo) {
+ return hassInfo.version !== hassInfo.last_version;
+ }
+}
+
+customElements.define(HassioHassUpdate.is, HassioHassUpdate);
diff --git a/hassio/hassio-app.html b/hassio/hassio-app.js
similarity index 65%
rename from hassio/hassio-app.html
rename to hassio/hassio-app.js
index 0d8c0e632d..b01ee3431c 100644
--- a/hassio/hassio-app.html
+++ b/hassio/hassio-app.js
@@ -1,21 +1,17 @@
-
-
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
-
-
-
+import './hassio-main.js';
+
+class HassioApp extends PolymerElement {
+ static get template() {
+ return html`
+
+
-
-
+`;
+ }
-
diff --git a/hassio/hassio-data.html b/hassio/hassio-data.js
similarity index 88%
rename from hassio/hassio-data.html
rename to hassio/hassio-data.js
index ab34405aa9..a324292f05 100644
--- a/hassio/hassio-data.html
+++ b/hassio/hassio-data.js
@@ -1,7 +1,6 @@
-
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
diff --git a/hassio/hassio-main.html b/hassio/hassio-main.html
deleted file mode 100644
index 746a0b44cf..0000000000
--- a/hassio/hassio-main.html
+++ /dev/null
@@ -1,132 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/hassio-main.js b/hassio/hassio-main.js
new file mode 100644
index 0000000000..760dc0f3fd
--- /dev/null
+++ b/hassio/hassio-main.js
@@ -0,0 +1,104 @@
+import '@polymer/app-route/app-route.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../src/layouts/hass-loading-screen.js';
+import '../src/util/hass-util.js';
+import './addon-view/hassio-addon-view.js';
+import './hassio-data.js';
+import './hassio-pages-with-tabs.js';
+
+class HassioMain extends window.hassMixins.EventsMixin(PolymerElement) {
+ static get template() {
+ return html`
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-main'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ narrow: Boolean,
+ showMenu: Boolean,
+ route: {
+ type: Object,
+ // Fake route object
+ value: {
+ prefix: '/hassio',
+ path: '/dashboard',
+ __queryParams: {}
+ },
+ observer: 'routeChanged',
+ },
+ routeData: Object,
+ supervisorInfo: Object,
+ hostInfo: Object,
+ hassInfo: Object,
+ loaded: {
+ type: Boolean,
+ computed: 'computeIsLoaded(supervisorInfo, hostInfo, hassInfo)',
+ },
+ };
+ }
+
+ ready() {
+ super.ready();
+ window.hassUtil.applyThemesOnElement(this, this.hass.themes, this.hass.selectedTheme, true);
+ this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
+ }
+
+ connectedCallback() {
+ super.connectedCallback();
+ this.routeChanged(this.route);
+ }
+
+ apiCalled(ev) {
+ if (ev.detail.success) {
+ let tries = 1;
+
+ const tryUpdate = () => {
+ this.$.data.refresh().catch(function () {
+ tries += 1;
+ setTimeout(tryUpdate, Math.min(tries, 5) * 1000);
+ });
+ };
+
+ tryUpdate();
+ }
+ }
+
+ computeIsLoaded(supervisorInfo, hostInfo, hassInfo) {
+ return (supervisorInfo !== null &&
+ hostInfo !== null &&
+ hassInfo !== null);
+ }
+
+ routeChanged(route) {
+ if (route.path === '' && route.prefix === '/hassio') {
+ history.replaceState(null, null, '/hassio/dashboard');
+ this.fire('location-changed');
+ }
+ }
+
+ equalsAddon(page) {
+ return page && page === 'addon';
+ }
+}
+
+customElements.define(HassioMain.is, HassioMain);
diff --git a/hassio/hassio-markdown-dialog.html b/hassio/hassio-markdown-dialog.js
similarity index 57%
rename from hassio/hassio-markdown-dialog.html
rename to hassio/hassio-markdown-dialog.js
index 92b3b0c8ff..396219c2ea 100644
--- a/hassio/hassio-markdown-dialog.html
+++ b/hassio/hassio-markdown-dialog.js
@@ -1,15 +1,17 @@
-
-
-
-
-
+import '@polymer/app-layout/app-toolbar/app-toolbar.js';
+import '@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js';
+import '@polymer/paper-dialog/paper-dialog.js';
+import '@polymer/paper-icon-button/paper-icon-button.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
-
-
+import '../src/components/ha-markdown.js';
+import '../src/resources/ha-style.js';
-
-
-
-
+
-
- [[title]]
+
+ [[title]]
-
+
-
-
+`;
+ }
-
diff --git a/hassio/hassio-pages-with-tabs.html b/hassio/hassio-pages-with-tabs.html
deleted file mode 100644
index 1b929df534..0000000000
--- a/hassio/hassio-pages-with-tabs.html
+++ /dev/null
@@ -1,163 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- Hass.io
-
-
-
-
-
- Dashboard
- Snapshots
- Add-on store
- System
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/hassio/hassio-pages-with-tabs.js b/hassio/hassio-pages-with-tabs.js
new file mode 100644
index 0000000000..68080bba62
--- /dev/null
+++ b/hassio/hassio-pages-with-tabs.js
@@ -0,0 +1,131 @@
+import '@polymer/app-layout/app-header-layout/app-header-layout.js';
+import '@polymer/app-layout/app-header/app-header.js';
+import '@polymer/app-layout/app-toolbar/app-toolbar.js';
+import '@polymer/paper-icon-button/paper-icon-button.js';
+import '@polymer/paper-tabs/paper-tab.js';
+import '@polymer/paper-tabs/paper-tabs.js';
+import { html } from '@polymer/polymer/lib/utils/html-tag.js';
+import { PolymerElement } from '@polymer/polymer/polymer-element.js';
+
+import '../src/components/ha-menu-button.js';
+import '../src/resources/ha-style.js';
+import '../src/util/hass-mixins.js';
+import './addon-store/hassio-addon-store.js';
+import './dashboard/hassio-dashboard.js';
+import './hassio-markdown-dialog.js';
+import './snapshots/hassio-snapshot.js';
+import './snapshots/hassio-snapshots.js';
+import './system/hassio-system.js';
+
+class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(PolymerElement) {
+ static get template() {
+ return html`
+
+
+
+
+
+ Hass.io
+
+
+
+
+
+ Dashboard
+ Snapshots
+ Add-on store
+ System
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+`;
+ }
+
+ static get is() { return 'hassio-pages-with-tabs'; }
+
+ static get properties() {
+ return {
+ hass: Object,
+ showMenu: Boolean,
+ narrow: Boolean,
+ page: String,
+ supervisorInfo: Object,
+ hostInfo: Object,
+ hassInfo: Object,
+ snapshotSlug: String,
+ snapshotDeleted: Boolean,
+
+ markdownTitle: String,
+ markdownContent: {
+ type: String,
+ value: '',
+ },
+ };
+ }
+
+ ready() {
+ super.ready();
+ this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
+ }
+
+ handlePageSelected(ev) {
+ const newPage = ev.detail.item.getAttribute('page-name');
+ if (newPage !== this.page) {
+ this.navigate(`/hassio/${newPage}`);
+ }
+ }
+
+ equals(a, b) {
+ return a === b;
+ }
+
+ showRefreshButton(page) {
+ return page === 'store' || page === 'snapshots';
+ }
+
+ refreshClicked() {
+ if (this.page === 'snapshots') {
+ this.shadowRoot.querySelector('hassio-snapshots').refreshData();
+ } else {
+ this.shadowRoot.querySelector('hassio-addon-store').refreshData();
+ }
+ }
+
+ openMarkdown(ev) {
+ this.setProperties({
+ markdownTitle: ev.detail.title,
+ markdownContent: ev.detail.content,
+ });
+ this.shadowRoot.querySelector('hassio-markdown-dialog').openDialog();
+ }
+}
+
+customElements.define(HassioPagesWithTabs.is, HassioPagesWithTabs);
diff --git a/hassio/index.html b/hassio/index.html
index 8e21a64064..d5a816c12a 100644
--- a/hassio/index.html
+++ b/hassio/index.html
@@ -16,20 +16,21 @@
-
+
+