mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-18 23:06:40 +00:00
Hassio: show hardware (#997)
* Hassio: list hardware * Hassio: show hardware * Remove debug * Travis * Concept * Lint * Raised button * Lint
This commit is contained in:
parent
421b9abc7d
commit
6bdf1c8b80
@ -11,8 +11,6 @@
|
|||||||
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
<link rel='import' href='../../src/components/hassio-card-content.html'>
|
||||||
<link rel='import' href='../../src/util/hass-mixins.html'>
|
<link rel='import' href='../../src/util/hass-mixins.html'>
|
||||||
|
|
||||||
<link rel='import' href='./hassio-addon-more-info.html'>
|
|
||||||
|
|
||||||
<dom-module id="hassio-addon-info">
|
<dom-module id="hassio-addon-info">
|
||||||
<template>
|
<template>
|
||||||
<style include='ha-style'>
|
<style include='ha-style'>
|
||||||
@ -83,10 +81,6 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
<hassio-addon-more-info
|
|
||||||
title='Changelog'
|
|
||||||
content='[[changelog]]'
|
|
||||||
></hassio-addon-more-info>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<paper-card>
|
<paper-card>
|
||||||
@ -208,7 +202,6 @@ class HassioAddonInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
|||||||
hass: Object,
|
hass: Object,
|
||||||
addon: Object,
|
addon: Object,
|
||||||
addonSlug: String,
|
addonSlug: String,
|
||||||
changelog: String,
|
|
||||||
isRunning: {
|
isRunning: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
computed: 'computeIsRunning(addon)',
|
computed: 'computeIsRunning(addon)',
|
||||||
@ -248,12 +241,15 @@ class HassioAddonInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
|||||||
|
|
||||||
openChangelog() {
|
openChangelog() {
|
||||||
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
|
this.hass.callApi('get', `hassio/addons/${this.addonSlug}/changelog`)
|
||||||
.then((data) => {
|
.then(
|
||||||
this.changelog = data;
|
resp => resp
|
||||||
}, () => {
|
, () => 'Error getting changelog'
|
||||||
this.changelog = 'Error getting changelog';
|
).then((content) => {
|
||||||
|
this.fire('hassio-markdown-dialog', {
|
||||||
|
title: 'Changelog',
|
||||||
|
content: content,
|
||||||
|
});
|
||||||
});
|
});
|
||||||
this.shadowRoot.querySelector('hassio-addon-more-info').openDialog();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_unistallClicked() {
|
_unistallClicked() {
|
||||||
|
@ -1,90 +0,0 @@
|
|||||||
<link rel='import' href='../../bower_components/polymer/polymer-element.html'>
|
|
||||||
<link rel='import' href='../../bower_components/paper-dialog/paper-dialog.html'>
|
|
||||||
<link rel='import' href='../../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
|
||||||
<link rel='import' href='../../bower_components/paper-icon-button/paper-icon-button.html'>
|
|
||||||
<link rel='import' href='../../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html'>
|
|
||||||
|
|
||||||
<link rel='import' href='../../src/components/ha-markdown.html'>
|
|
||||||
<link rel='import' href='../../src/resources/ha-style.html'>
|
|
||||||
|
|
||||||
<dom-module id='hassio-addon-more-info'>
|
|
||||||
<template>
|
|
||||||
<style include='ha-style-dialog'>
|
|
||||||
paper-dialog {
|
|
||||||
font-size: 14px;
|
|
||||||
border-radius: 2px;
|
|
||||||
--paper-dialog-scrollable: {
|
|
||||||
-webkit-overflow-scrolling: auto;
|
|
||||||
}
|
|
||||||
--more-info-header-background: var(--secondary-background-color);
|
|
||||||
--more-info-header-color: var(--primary-text-color);
|
|
||||||
}
|
|
||||||
/* overrule the ha-style-dialog max-height on small screens */
|
|
||||||
@media all and (max-width: 450px), all and (max-height: 500px) {
|
|
||||||
paper-dialog {
|
|
||||||
max-height: 100%;
|
|
||||||
height: 100%;
|
|
||||||
--more-info-header-background: var(--primary-color);
|
|
||||||
--more-info-header-color: var(--text-primary-color);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
app-toolbar {
|
|
||||||
margin-top: 0;
|
|
||||||
color: var(--more-info-header-color);
|
|
||||||
background-color: var(--more-info-header-background);
|
|
||||||
}
|
|
||||||
app-toolbar [main-title] {
|
|
||||||
/* Design guideline states 24px, changed to 16 to align with state info */
|
|
||||||
margin-left: 16px;
|
|
||||||
}
|
|
||||||
paper-dialog-scrollable {
|
|
||||||
margin-bottom: 16px;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
<paper-dialog
|
|
||||||
id='dialog'
|
|
||||||
with-backdrop
|
|
||||||
>
|
|
||||||
<app-toolbar>
|
|
||||||
<paper-icon-button
|
|
||||||
icon='mdi:close'
|
|
||||||
dialog-dismiss
|
|
||||||
></paper-icon-button>
|
|
||||||
<div main-title>[[title]]</div>
|
|
||||||
</app-toolbar>
|
|
||||||
<paper-dialog-scrollable>
|
|
||||||
<ha-markdown content='[[content]]'></ha-markdown>
|
|
||||||
</paper-dialog-scrollable>
|
|
||||||
</paper-dialog>
|
|
||||||
</template>
|
|
||||||
</dom-module>
|
|
||||||
|
|
||||||
<script>
|
|
||||||
class HassioAddonMoreInfo extends Polymer.Element {
|
|
||||||
static get is() { return 'hassio-addon-more-info'; }
|
|
||||||
|
|
||||||
static get properties() {
|
|
||||||
return {
|
|
||||||
title: String,
|
|
||||||
content: {
|
|
||||||
type: String,
|
|
||||||
value: '',
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
ready() {
|
|
||||||
super.ready();
|
|
||||||
this.$.dialog.addEventListener('iron-overlay-opened', (ev) => {
|
|
||||||
if (ev.target.withBackdrop) {
|
|
||||||
ev.target.parentNode.insertBefore(ev.target.backdropElement, ev.target);
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
openDialog() {
|
|
||||||
this.$.dialog.open();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
customElements.define(HassioAddonMoreInfo.is, HassioAddonMoreInfo);
|
|
||||||
</script>
|
|
@ -12,6 +12,7 @@
|
|||||||
<link rel="import" href="./hassio-addon-config.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">
|
||||||
|
<link rel='import' href='../hassio-markdown-dialog.html'>
|
||||||
|
|
||||||
<dom-module id="hassio-addon-view">
|
<dom-module id="hassio-addon-view">
|
||||||
<template>
|
<template>
|
||||||
@ -77,6 +78,11 @@
|
|||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</app-header-layout>
|
</app-header-layout>
|
||||||
|
|
||||||
|
<hassio-markdown-dialog
|
||||||
|
title='[[markdownTitle]]'
|
||||||
|
content='[[markdownContent]]'
|
||||||
|
></hassio-markdown-dialog>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
@ -96,12 +102,19 @@ class HassioAddonView extends Polymer.Element {
|
|||||||
},
|
},
|
||||||
routeMatches: Boolean,
|
routeMatches: Boolean,
|
||||||
addon: Object,
|
addon: Object,
|
||||||
|
|
||||||
|
markdownTitle: String,
|
||||||
|
markdownContent: {
|
||||||
|
type: String,
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
ready() {
|
ready() {
|
||||||
super.ready();
|
super.ready();
|
||||||
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
this.addEventListener('hass-api-called', ev => this.apiCalled(ev));
|
||||||
|
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||||
}
|
}
|
||||||
|
|
||||||
apiCalled(ev) {
|
apiCalled(ev) {
|
||||||
@ -129,6 +142,14 @@ class HassioAddonView extends Polymer.Element {
|
|||||||
backTapped() {
|
backTapped() {
|
||||||
history.back();
|
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);
|
customElements.define(HassioAddonView.is, HassioAddonView);
|
||||||
|
76
hassio/hassio-markdown-dialog.html
Normal file
76
hassio/hassio-markdown-dialog.html
Normal file
@ -0,0 +1,76 @@
|
|||||||
|
<link rel='import' href='../bower_components/polymer/polymer-element.html'>
|
||||||
|
<link rel='import' href='../bower_components/paper-dialog/paper-dialog.html'>
|
||||||
|
<link rel='import' href='../bower_components/app-layout/app-toolbar/app-toolbar.html'>
|
||||||
|
<link rel='import' href='../bower_components/paper-icon-button/paper-icon-button.html'>
|
||||||
|
<link rel='import' href='../bower_components/paper-dialog-scrollable/paper-dialog-scrollable.html'>
|
||||||
|
|
||||||
|
<link rel='import' href='../src/components/ha-markdown.html'>
|
||||||
|
<link rel='import' href='../src/resources/ha-style.html'>
|
||||||
|
|
||||||
|
<dom-module id='hassio-markdown-dialog'>
|
||||||
|
<template>
|
||||||
|
<style include='ha-style-dialog'>
|
||||||
|
paper-dialog {
|
||||||
|
min-width: 350px;
|
||||||
|
font-size: 14px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
app-toolbar {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0 16px;
|
||||||
|
color: var(--primary-text-color);
|
||||||
|
background-color: var(--secondary-background-color);
|
||||||
|
}
|
||||||
|
app-toolbar [main-title] {
|
||||||
|
margin-left: 16px;
|
||||||
|
}
|
||||||
|
paper-checkbox {
|
||||||
|
display: block;
|
||||||
|
margin: 4px;
|
||||||
|
}
|
||||||
|
@media all and (max-width: 450px), all and (max-height: 500px) {
|
||||||
|
paper-dialog {
|
||||||
|
max-height: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
app-toolbar {
|
||||||
|
color: var(--text-primary-color);
|
||||||
|
background-color: var(--primary-color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
<paper-dialog
|
||||||
|
id='dialog'
|
||||||
|
with-backdrop
|
||||||
|
>
|
||||||
|
<app-toolbar>
|
||||||
|
<paper-icon-button
|
||||||
|
icon='mdi:close'
|
||||||
|
dialog-dismiss
|
||||||
|
></paper-icon-button>
|
||||||
|
<div main-title>[[title]]</div>
|
||||||
|
</app-toolbar>
|
||||||
|
<paper-dialog-scrollable>
|
||||||
|
<ha-markdown content='[[content]]'></ha-markdown>
|
||||||
|
</paper-dialog-scrollable>
|
||||||
|
</paper-dialog>
|
||||||
|
</template>
|
||||||
|
</dom-module>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
class HassioMarkdownDialog extends Polymer.Element {
|
||||||
|
static get is() { return 'hassio-markdown-dialog'; }
|
||||||
|
|
||||||
|
static get properties() {
|
||||||
|
return {
|
||||||
|
title: String,
|
||||||
|
content: String,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
openDialog() {
|
||||||
|
this.$.dialog.open();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
customElements.define(HassioMarkdownDialog.is, HassioMarkdownDialog);
|
||||||
|
</script>
|
@ -15,6 +15,7 @@
|
|||||||
<link rel='import' href='./snapshots/hassio-snapshot.html'>
|
<link rel='import' href='./snapshots/hassio-snapshot.html'>
|
||||||
<link rel='import' href='./addon-store/hassio-addon-store.html'>
|
<link rel='import' href='./addon-store/hassio-addon-store.html'>
|
||||||
<link rel='import' href='./system/hassio-system.html'>
|
<link rel='import' href='./system/hassio-system.html'>
|
||||||
|
<link rel='import' href='./hassio-markdown-dialog.html'>
|
||||||
|
|
||||||
<dom-module id='hassio-pages-with-tabs'>
|
<dom-module id='hassio-pages-with-tabs'>
|
||||||
<template>
|
<template>
|
||||||
@ -81,6 +82,12 @@
|
|||||||
></hassio-system>
|
></hassio-system>
|
||||||
</template>
|
</template>
|
||||||
</app-header-layout>
|
</app-header-layout>
|
||||||
|
|
||||||
|
<hassio-markdown-dialog
|
||||||
|
title='[[markdownTitle]]'
|
||||||
|
content='[[markdownContent]]'
|
||||||
|
></hassio-markdown-dialog>
|
||||||
|
|
||||||
<template is='dom-if' if='[[equals(page, "snapshots")]]'>
|
<template is='dom-if' if='[[equals(page, "snapshots")]]'>
|
||||||
<hassio-snapshot
|
<hassio-snapshot
|
||||||
hass='[[hass]]'
|
hass='[[hass]]'
|
||||||
@ -106,9 +113,20 @@ class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(Polymer.Elemen
|
|||||||
hassInfo: Object,
|
hassInfo: Object,
|
||||||
snapshotSlug: String,
|
snapshotSlug: String,
|
||||||
snapshotDeleted: Boolean,
|
snapshotDeleted: Boolean,
|
||||||
|
|
||||||
|
markdownTitle: String,
|
||||||
|
markdownContent: {
|
||||||
|
type: String,
|
||||||
|
value: '',
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ready() {
|
||||||
|
super.ready();
|
||||||
|
this.addEventListener('hassio-markdown-dialog', ev => this.openMarkdown(ev));
|
||||||
|
}
|
||||||
|
|
||||||
handlePageSelected(ev) {
|
handlePageSelected(ev) {
|
||||||
const newPage = ev.detail.item.getAttribute('page-name');
|
const newPage = ev.detail.item.getAttribute('page-name');
|
||||||
if (newPage !== this.page) {
|
if (newPage !== this.page) {
|
||||||
@ -131,6 +149,14 @@ class HassioPagesWithTabs extends window.hassMixins.NavigateMixin(Polymer.Elemen
|
|||||||
this.shadowRoot.querySelector('hassio-addon-store').refreshData();
|
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);
|
customElements.define(HassioPagesWithTabs.is, HassioPagesWithTabs);
|
||||||
|
@ -1,6 +1,8 @@
|
|||||||
<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/paper-card/paper-card.html">
|
<link rel="import" href="../../bower_components/paper-card/paper-card.html">
|
||||||
|
<link rel="import" href="../../bower_components/paper-button/paper-button.html">
|
||||||
|
|
||||||
|
<link rel='import' href='../../src/util/hass-mixins.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">
|
||||||
|
|
||||||
<dom-module id="hassio-host-info">
|
<dom-module id="hassio-host-info">
|
||||||
@ -12,7 +14,7 @@
|
|||||||
margin-left: 8px;
|
margin-left: 8px;
|
||||||
}
|
}
|
||||||
.card-content {
|
.card-content {
|
||||||
height: 110px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 830px) {
|
@media screen and (max-width: 830px) {
|
||||||
paper-card {
|
paper-card {
|
||||||
@ -34,9 +36,13 @@
|
|||||||
color: var(--google-red-500);
|
color: var(--google-red-500);
|
||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
|
paper-button.info {
|
||||||
|
max-width: 50%;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
<paper-card heading="Host system">
|
<paper-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
<h2>Host system</h2>
|
||||||
<table class='info'>
|
<table class='info'>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Version</td>
|
<td>Version</td>
|
||||||
@ -51,17 +57,16 @@
|
|||||||
<td>[[data.type]] ([[data.os]])</td>
|
<td>[[data.type]] ([[data.os]])</td>
|
||||||
</tr>
|
</tr>
|
||||||
</table>
|
</table>
|
||||||
|
<paper-button
|
||||||
|
raised
|
||||||
|
on-click='_showHardware'
|
||||||
|
class='info'
|
||||||
|
>Show hardware</paper-button>
|
||||||
<template is='dom-if' if='[[errors]]'>
|
<template is='dom-if' if='[[errors]]'>
|
||||||
<div class='errors'>Error: [[errors]]</div>
|
<div class='errors'>Error: [[errors]]</div>
|
||||||
</template>
|
</template>
|
||||||
</div>
|
</div>
|
||||||
<div class="card-actions">
|
<div class="card-actions">
|
||||||
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
|
||||||
<ha-call-api-button
|
|
||||||
hass='[[hass]]'
|
|
||||||
path="hassio/host/update"
|
|
||||||
>Update</ha-call-api-button>
|
|
||||||
</template>
|
|
||||||
<template is='dom-if' if='[[computeRebootAvailable(data)]]'>
|
<template is='dom-if' if='[[computeRebootAvailable(data)]]'>
|
||||||
<ha-call-api-button
|
<ha-call-api-button
|
||||||
class='warning'
|
class='warning'
|
||||||
@ -76,13 +81,19 @@
|
|||||||
path="hassio/host/shutdown"
|
path="hassio/host/shutdown"
|
||||||
>Shutdown</ha-call-api-button>
|
>Shutdown</ha-call-api-button>
|
||||||
</template>
|
</template>
|
||||||
|
<template is='dom-if' if='[[computeUpdateAvailable(data)]]'>
|
||||||
|
<ha-call-api-button
|
||||||
|
hass='[[hass]]'
|
||||||
|
path="hassio/host/update"
|
||||||
|
>Update</ha-call-api-button>
|
||||||
|
</template>
|
||||||
</div>
|
</div>
|
||||||
</paper-card>
|
</paper-card>
|
||||||
</template>
|
</template>
|
||||||
</dom-module>
|
</dom-module>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
class HassioHostInfo extends Polymer.Element {
|
class HassioHostInfo extends window.hassMixins.EventsMixin(Polymer.Element) {
|
||||||
static get is() { return 'hassio-host-info'; }
|
static get is() { return 'hassio-host-info'; }
|
||||||
|
|
||||||
static get properties() {
|
static get properties() {
|
||||||
@ -124,6 +135,38 @@ class HassioHostInfo extends Polymer.Element {
|
|||||||
computeShutdownAvailable(data) {
|
computeShutdownAvailable(data) {
|
||||||
return data.features && data.features.includes('shutdown');
|
return data.features && data.features.includes('shutdown');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_showHardware() {
|
||||||
|
this.hass.callApi('get', 'hassio/host/hardware')
|
||||||
|
.then(
|
||||||
|
resp => this._objectToMarkdown(resp.data)
|
||||||
|
, () => 'Error getting hardware info'
|
||||||
|
).then((content) => {
|
||||||
|
this.fire('hassio-markdown-dialog', {
|
||||||
|
title: 'Hardware',
|
||||||
|
content: content,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_objectToMarkdown(obj, indent = '') {
|
||||||
|
let data = '';
|
||||||
|
Object.keys(obj).forEach((key) => {
|
||||||
|
if (typeof obj[key] !== 'object') {
|
||||||
|
data += `${indent}- ${key}: ${obj[key]}\n`;
|
||||||
|
} else {
|
||||||
|
data += `${indent}- ${key}:\n`;
|
||||||
|
if (Array.isArray(obj[key])) {
|
||||||
|
if (obj[key].length) {
|
||||||
|
data += `${indent} - ` + obj[key].join(`\n${indent} - `) + '\n';
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
data += this._objectToMarkdown(obj[key], ` ${indent}`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return data;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
customElements.define(HassioHostInfo.is, HassioHostInfo);
|
customElements.define(HassioHostInfo.is, HassioHostInfo);
|
||||||
|
@ -13,7 +13,7 @@
|
|||||||
width: 400px;
|
width: 400px;
|
||||||
}
|
}
|
||||||
.card-content {
|
.card-content {
|
||||||
height: 110px;
|
height: 200px;
|
||||||
}
|
}
|
||||||
@media screen and (max-width: 830px) {
|
@media screen and (max-width: 830px) {
|
||||||
paper-card {
|
paper-card {
|
||||||
@ -34,8 +34,9 @@
|
|||||||
margin-top: 16px;
|
margin-top: 16px;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
<paper-card heading="Hass.io supervisor">
|
<paper-card>
|
||||||
<div class="card-content">
|
<div class="card-content">
|
||||||
|
<h2>Hass.io supervisor</h2>
|
||||||
<table class='info'>
|
<table class='info'>
|
||||||
<tr>
|
<tr>
|
||||||
<td>Version</td>
|
<td>Version</td>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user