Use hass-tabs-subpage in add-on view (#5483)

This commit is contained in:
Joakim Sørensen 2020-05-01 11:34:52 +02:00 committed by GitHub
parent 2084ecc4c6
commit 6847830575
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
14 changed files with 389 additions and 114 deletions

View File

@ -28,7 +28,7 @@ const runDevServer = ({
open: true, open: true,
watchContentBase: true, watchContentBase: true,
contentBase, contentBase,
}).listen(port, listenHost, function(err) { }).listen(port, listenHost, function (err) {
if (err) { if (err) {
throw err; throw err;
} }

View File

@ -18,20 +18,20 @@ import {
HassioAddonDetails, HassioAddonDetails,
HassioAddonSetOptionParams, HassioAddonSetOptionParams,
setHassioAddonOption, setHassioAddonOption,
} from "../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { import {
fetchHassioHardwareAudio, fetchHassioHardwareAudio,
HassioHardwareAudioDevice, HassioHardwareAudioDevice,
} from "../../../src/data/hassio/hardware"; } from "../../../../src/data/hassio/hardware";
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types"; import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
@customElement("hassio-addon-audio") @customElement("hassio-addon-audio")
class HassioAddonAudio extends LitElement { class HassioAddonAudio extends LitElement {
@property() public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public addon!: HassioAddonDetails; @property({ attribute: false }) public addon!: HassioAddonDetails;
@property() private _error?: string; @property() private _error?: string;
@ -56,7 +56,7 @@ class HassioAddonAudio extends LitElement {
<paper-listbox <paper-listbox
slot="dropdown-content" slot="dropdown-content"
attr-for-selected="device" attr-for-selected="device"
.selected=${this._selectedInput} .selected=${this._selectedInput!}
> >
${this._inputDevices && ${this._inputDevices &&
this._inputDevices.map((item) => { this._inputDevices.map((item) => {
@ -75,7 +75,7 @@ class HassioAddonAudio extends LitElement {
<paper-listbox <paper-listbox
slot="dropdown-content" slot="dropdown-content"
attr-for-selected="device" attr-for-selected="device"
.selected=${this._selectedOutput} .selected=${this._selectedOutput!}
> >
${this._outputDevices && ${this._outputDevices &&
this._outputDevices.map((item) => { this._outputDevices.map((item) => {

View File

@ -0,0 +1,82 @@
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { HomeAssistant } from "../../../../src/types";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { hassioStyle } from "../../resources/hassio-style";
import { haStyle } from "../../../../src/resources/styles";
import "./hassio-addon-audio";
import "./hassio-addon-config";
import "./hassio-addon-network";
@customElement("hassio-addon-config-tab")
class HassioAddonConfigDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
if (!this.addon) {
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
return html`
<div class="content">
<hassio-addon-config
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-config>
${this.addon.network
? html`
<hassio-addon-network
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-network>
`
: ""}
${this.addon.audio
? html`
<hassio-addon-audio
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-audio>
`
: ""}
</div>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
@media screen and (min-width: 1024px) {
.content {
width: 50%;
margin: auto;
}
}
hassio-addon-network,
hassio-addon-audio,
hassio-addon-config {
margin-bottom: 24px;
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"hassio-addon-config-tab": HassioAddonConfigDashboard;
}
}

View File

@ -12,24 +12,24 @@ import {
query, query,
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { fireEvent } from "../../../src/common/dom/fire_event"; import { fireEvent } from "../../../../src/common/dom/fire_event";
import "../../../src/components/ha-yaml-editor"; import "../../../../src/components/ha-yaml-editor";
import type { HaYamlEditor } from "../../../src/components/ha-yaml-editor"; import type { HaYamlEditor } from "../../../../src/components/ha-yaml-editor";
import { import {
HassioAddonDetails, HassioAddonDetails,
HassioAddonSetOptionParams, HassioAddonSetOptionParams,
setHassioAddonOption, setHassioAddonOption,
} from "../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { showConfirmationDialog } from "../../../src/dialogs/generic/show-dialog-box"; import { showConfirmationDialog } from "../../../../src/dialogs/generic/show-dialog-box";
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../../src/resources/styles";
import type { HomeAssistant } from "../../../src/types"; import type { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
@customElement("hassio-addon-config") @customElement("hassio-addon-config")
class HassioAddonConfig extends LitElement { class HassioAddonConfig extends LitElement {
@property() public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public addon!: HassioAddonDetails; @property({ attribute: false }) public addon!: HassioAddonDetails;
@property() private _error?: string; @property() private _error?: string;

View File

@ -10,15 +10,15 @@ import {
PropertyValues, PropertyValues,
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { fireEvent } from "../../../src/common/dom/fire_event"; import { fireEvent } from "../../../../src/common/dom/fire_event";
import { import {
HassioAddonDetails, HassioAddonDetails,
HassioAddonSetOptionParams, HassioAddonSetOptionParams,
setHassioAddonOption, setHassioAddonOption,
} from "../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types"; import { HomeAssistant } from "../../../../src/types";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
interface NetworkItem { interface NetworkItem {
description: string; description: string;
@ -32,9 +32,9 @@ interface NetworkItemInput extends PaperInputElement {
@customElement("hassio-addon-network") @customElement("hassio-addon-network")
class HassioAddonNetwork extends LitElement { class HassioAddonNetwork extends LitElement {
@property() public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public addon!: HassioAddonDetails; @property({ attribute: false }) public addon!: HassioAddonDetails;
@property() private _error?: string; @property() private _error?: string;
@ -70,7 +70,7 @@ class HassioAddonNetwork extends LitElement {
<paper-input <paper-input
@value-changed=${this._configChanged} @value-changed=${this._configChanged}
placeholder="disabled" placeholder="disabled"
.value=${item.host} .value=${String(item.host)}
.container=${item.container} .container=${item.container}
no-label-float no-label-float
></paper-input> ></paper-input>

View File

@ -1,6 +1,3 @@
import "@polymer/app-layout/app-header-layout/app-header-layout";
import "@polymer/app-layout/app-header/app-header";
import "@polymer/app-layout/app-toolbar/app-toolbar";
import "@polymer/paper-icon-button/paper-icon-button"; import "@polymer/paper-icon-button/paper-icon-button";
import "@polymer/paper-spinner/paper-spinner-lite"; import "@polymer/paper-spinner/paper-spinner-lite";
import { import {
@ -12,6 +9,7 @@ import {
property, property,
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import memoizeOne from "memoize-one";
import { import {
fetchHassioAddonInfo, fetchHassioAddonInfo,
HassioAddonDetails, HassioAddonDetails,
@ -19,65 +17,86 @@ import {
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../src/resources/styles";
import { HomeAssistant, Route } from "../../../src/types"; import { HomeAssistant, Route } from "../../../src/types";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../resources/hassio-style";
import "./hassio-addon-audio"; import "./config/hassio-addon-audio";
import "./hassio-addon-config"; import "./config/hassio-addon-config";
import "./hassio-addon-info"; import "./info/hassio-addon-info";
import "./hassio-addon-logs"; import "./log/hassio-addon-logs";
import "./hassio-addon-network"; import "./config/hassio-addon-network";
import "../../../src/layouts/hass-subpage"; import type { PageNavigation } from "../../../src/layouts/hass-tabs-subpage";
import "../../../src/layouts/hass-tabs-subpage";
@customElement("hassio-addon-view") import "./hassio-addon-router";
class HassioAddonView extends LitElement {
@property() public hass!: HomeAssistant;
@property() public route!: Route; @customElement("hassio-addon-dashboard")
class HassioAddonDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property() public addon?: HassioAddonDetails; @property({ attribute: false }) public route!: Route;
@property({ attribute: false }) public addon?: HassioAddonDetails;
@property({ type: Boolean }) public narrow!: boolean;
private _computeTail = memoizeOne((route: Route) => {
const dividerPos = route.path.indexOf("/", 1);
return dividerPos === -1
? {
prefix: route.prefix + route.path,
path: "",
}
: {
prefix: route.prefix + route.path.substr(0, dividerPos),
path: route.path.substr(dividerPos),
};
});
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.addon) { if (!this.addon) {
return html` <paper-spinner-lite active></paper-spinner-lite> `; return html` <paper-spinner-lite active></paper-spinner-lite> `;
} }
const addonTabs: PageNavigation[] = [
{
name: "Info",
path: `/hassio/addon/${this.addon.slug}/info`,
icon: "mdi:information-variant",
},
];
if (this.addon.version) {
addonTabs.push(
{
name: "Configuration",
path: `/hassio/addon/${this.addon.slug}/config`,
icon: "mdi:cogs",
},
{
name: "Log",
path: `/hassio/addon/${this.addon.slug}/logs`,
icon: "mdi:math-log",
}
);
}
const route = this._computeTail(this.route);
return html` return html`
<hass-subpage header="Hass.io: add-on details" hassio> <hass-tabs-subpage
<div class="content"> .hass=${this.hass}
<hassio-addon-info .narrow=${this.narrow}
.hass=${this.hass} .backPath=${this.addon.version ? "/hassio/dashboard" : "/hassio/store"}
.addon=${this.addon} .route=${route}
></hassio-addon-info> .hassio=${true}
.tabs=${addonTabs}
${this.addon && this.addon.version >
? html` <span slot="header">${this.addon.name}</span>
<hassio-addon-config <hassio-addon-router
.hass=${this.hass} .route=${route}
.addon=${this.addon} .narrow=${this.narrow}
></hassio-addon-config> .hass=${this.hass}
.addon=${this.addon}
${this.addon.audio ></hassio-addon-router>
? html` </hass-tabs-subpage>
<hassio-addon-audio
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-audio>
`
: ""}
${this.addon.network
? html`
<hassio-addon-network
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-network>
`
: ""}
<hassio-addon-logs
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-logs>
`
: ""}
</div>
</hass-subpage>
`; `;
} }
@ -141,7 +160,7 @@ class HassioAddonView extends LitElement {
} }
private async _routeDataChanged(routeData: Route): Promise<void> { private async _routeDataChanged(routeData: Route): Promise<void> {
const addon = routeData.path.substr(1); const addon = routeData.path.split("/")[1];
try { try {
const addoninfo = await fetchHassioAddonInfo(this.hass, addon); const addoninfo = await fetchHassioAddonInfo(this.hass, addon);
this.addon = addoninfo; this.addon = addoninfo;
@ -153,6 +172,6 @@ class HassioAddonView extends LitElement {
declare global { declare global {
interface HTMLElementTagNameMap { interface HTMLElementTagNameMap {
"hassio-addon-view": HassioAddonView; "hassio-addon-dashboard": HassioAddonDashboard;
} }
} }

View File

@ -0,0 +1,49 @@
import {
HassRouterPage,
RouterOptions,
} from "../../../src/layouts/hass-router-page";
import { customElement, property } from "lit-element";
import { HomeAssistant } from "../../../src/types";
// Don't codesplit the others, because it breaks the UI when pushed to a Pi
import "./info/hassio-addon-info-tab";
import "./config/hassio-addon-config-tab";
import "./log/hassio-addon-log-tab";
import { HassioAddonDetails } from "../../../src/data/hassio/addon";
@customElement("hassio-addon-router")
class HassioAddonRouter extends HassRouterPage {
@property({ type: Boolean }) public narrow = false;
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon!: HassioAddonDetails;
protected routerOptions: RouterOptions = {
defaultPage: "info",
showLoading: true,
routes: {
info: {
tag: "hassio-addon-info-tab",
},
config: {
tag: "hassio-addon-config-tab",
},
logs: {
tag: "hassio-addon-log-tab",
},
},
};
protected updatePageEl(el) {
el.route = this.routeTail;
el.hass = this.hass;
el.addon = this.addon;
el.narrow = this.narrow;
}
}
declare global {
interface HTMLElementTagNameMap {
"hassio-addon-router": HassioAddonRouter;
}
}

View File

@ -0,0 +1,63 @@
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { HomeAssistant } from "../../../../src/types";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { hassioStyle } from "../../resources/hassio-style";
import { haStyle } from "../../../../src/resources/styles";
import "./hassio-addon-info";
@customElement("hassio-addon-info-tab")
class HassioAddonInfoDashboard extends LitElement {
@property({ type: Boolean }) public narrow!: boolean;
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
if (!this.addon) {
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
return html`
<div class="content">
<hassio-addon-info
.narrow=${this.narrow}
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-info>
</div>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
@media screen and (min-width: 1024px) {
.content {
width: 50%;
margin-left: 25%;
}
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"hassio-addon-info-tab": HassioAddonInfoDashboard;
}
}

View File

@ -12,14 +12,14 @@ import {
TemplateResult, TemplateResult,
} from "lit-element"; } from "lit-element";
import { classMap } from "lit-html/directives/class-map"; import { classMap } from "lit-html/directives/class-map";
import { atLeastVersion } from "../../../src/common/config/version"; import { atLeastVersion } from "../../../../src/common/config/version";
import { fireEvent } from "../../../src/common/dom/fire_event"; import { fireEvent } from "../../../../src/common/dom/fire_event";
import { navigate } from "../../../src/common/navigate"; import { navigate } from "../../../../src/common/navigate";
import "../../../src/components/buttons/ha-call-api-button"; import "../../../../src/components/buttons/ha-call-api-button";
import "../../../src/components/buttons/ha-progress-button"; import "../../../../src/components/buttons/ha-progress-button";
import "../../../src/components/ha-label-badge"; import "../../../../src/components/ha-label-badge";
import "../../../src/components/ha-markdown"; import "../../../../src/components/ha-markdown";
import "../../../src/components/ha-switch"; import "../../../../src/components/ha-switch";
import { import {
fetchHassioAddonChangelog, fetchHassioAddonChangelog,
HassioAddonDetails, HassioAddonDetails,
@ -29,12 +29,12 @@ import {
setHassioAddonOption, setHassioAddonOption,
setHassioAddonSecurity, setHassioAddonSecurity,
uninstallHassioAddon, uninstallHassioAddon,
} from "../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types"; import { HomeAssistant } from "../../../../src/types";
import "../components/hassio-card-content"; import "../../components/hassio-card-content";
import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown"; import { showHassioMarkdownDialog } from "../../dialogs/markdown/show-dialog-hassio-markdown";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
const PERMIS_DESC = { const PERMIS_DESC = {
rating: { rating: {
@ -91,9 +91,11 @@ const PERMIS_DESC = {
@customElement("hassio-addon-info") @customElement("hassio-addon-info")
class HassioAddonInfo extends LitElement { class HassioAddonInfo extends LitElement {
@property() public hass!: HomeAssistant; @property({ type: Boolean }) public narrow!: boolean;
@property() public addon!: HassioAddonDetails; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon!: HassioAddonDetails;
@property() private _error?: string; @property() private _error?: string;
@ -158,7 +160,7 @@ class HassioAddonInfo extends LitElement {
<paper-card> <paper-card>
<div class="card-content"> <div class="card-content">
<div class="addon-header"> <div class="addon-header">
${this.addon.name} ${!this.narrow ? this.addon.name : ""}
<div class="addon-version light-color"> <div class="addon-version light-color">
${this.addon.version ${this.addon.version
? html` ? html`
@ -185,7 +187,7 @@ class HassioAddonInfo extends LitElement {
<div class="description light-color"> <div class="description light-color">
${this.addon.description}.<br /> ${this.addon.description}.<br />
Visit Visit
<a href="${this.addon.url}" target="_blank" rel="noreferrer"> <a href="${this.addon.url!}" target="_blank" rel="noreferrer">
${this.addon.name} page</a ${this.addon.name} page</a
> >
for details. for details.
@ -193,7 +195,7 @@ class HassioAddonInfo extends LitElement {
${this.addon.logo ${this.addon.logo
? html` ? html`
<a <a
href="${this.addon.url}" href="${this.addon.url!}"
target="_blank" target="_blank"
class="logo" class="logo"
rel="noreferrer" rel="noreferrer"
@ -425,7 +427,7 @@ class HassioAddonInfo extends LitElement {
${this._computeShowWebUI ${this._computeShowWebUI
? html` ? html`
<a <a
.href=${this._pathWebui} href=${this._pathWebui!}
tabindex="-1" tabindex="-1"
target="_blank" target="_blank"
class="right" class="right"

View File

@ -0,0 +1,60 @@
import "@polymer/paper-spinner/paper-spinner-lite";
import {
css,
CSSResult,
customElement,
html,
LitElement,
property,
TemplateResult,
} from "lit-element";
import { HomeAssistant } from "../../../../src/types";
import { HassioAddonDetails } from "../../../../src/data/hassio/addon";
import { hassioStyle } from "../../resources/hassio-style";
import { haStyle } from "../../../../src/resources/styles";
import "./hassio-addon-logs";
@customElement("hassio-addon-log-tab")
class HassioAddonLogDashboard extends LitElement {
@property({ attribute: false }) public hass!: HomeAssistant;
@property({ attribute: false }) public addon?: HassioAddonDetails;
protected render(): TemplateResult {
if (!this.addon) {
return html` <paper-spinner-lite active></paper-spinner-lite> `;
}
return html`
<div class="content">
<hassio-addon-logs
.hass=${this.hass}
.addon=${this.addon}
></hassio-addon-logs>
</div>
`;
}
static get styles(): CSSResult[] {
return [
haStyle,
hassioStyle,
css`
@media screen and (min-width: 1024px) {
.content {
width: 50%;
margin-left: 25%;
}
}
`,
];
}
}
declare global {
interface HTMLElementTagNameMap {
"hassio-addon-log-tab": HassioAddonLogDashboard;
}
}

View File

@ -12,11 +12,11 @@ import {
import { import {
fetchHassioAddonLogs, fetchHassioAddonLogs,
HassioAddonDetails, HassioAddonDetails,
} from "../../../src/data/hassio/addon"; } from "../../../../src/data/hassio/addon";
import { haStyle } from "../../../src/resources/styles"; import { haStyle } from "../../../../src/resources/styles";
import { HomeAssistant } from "../../../src/types"; import { HomeAssistant } from "../../../../src/types";
import "../components/hassio-ansi-to-html"; import "../../components/hassio-ansi-to-html";
import { hassioStyle } from "../resources/hassio-style"; import { hassioStyle } from "../../resources/hassio-style";
@customElement("hassio-addon-logs") @customElement("hassio-addon-logs")
class HassioAddonLogs extends LitElement { class HassioAddonLogs extends LitElement {

View File

@ -96,7 +96,7 @@ class HassioAddons extends LitElement {
} }
private _addonTapped(ev: any): void { private _addonTapped(ev: any): void {
navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`); navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}/info`);
} }
private _openStore(): void { private _openStore(): void {

View File

@ -62,10 +62,10 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
store: "dashboard", store: "dashboard",
system: "dashboard", system: "dashboard",
addon: { addon: {
tag: "hassio-addon-view", tag: "hassio-addon-dashboard",
load: () => load: () =>
import( import(
/* webpackChunkName: "hassio-addon-view" */ "./addon-view/hassio-addon-view" /* webpackChunkName: "hassio-addon-dashboard" */ "./addon-view/hassio-addon-dashboard"
), ),
}, },
ingress: { ingress: {
@ -231,7 +231,7 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) {
text: "Add-on is not running. Please start it first", text: "Add-on is not running. Please start it first",
title: addon.name, title: addon.name,
}, },
() => navigate(this, `/hassio/addon/${addon.slug}`, true) () => navigate(this, `/hassio/addon/${addon.slug}/info`, true)
); );
return; return;

View File

@ -82,7 +82,7 @@ class HassTabsSubpage extends LitElement {
<span class="name" <span class="name"
>${page.translationKey >${page.translationKey
? this.hass.localize(page.translationKey) ? this.hass.localize(page.translationKey)
: name}</span : page.name}</span
> >
` `
: ""} : ""}
@ -97,7 +97,7 @@ class HassTabsSubpage extends LitElement {
super.updated(changedProperties); super.updated(changedProperties);
if (changedProperties.has("route")) { if (changedProperties.has("route")) {
this._activeTab = this.tabs.find((tab) => this._activeTab = this.tabs.find((tab) =>
this.route.prefix.includes(tab.path) `${this.route.prefix}${this.route.path}`.includes(tab.path)
); );
} }
} }