diff --git a/hassio/src/addon-view/data/hassio-addon-sections.ts b/hassio/src/addon-view/data/hassio-addon-sections.ts new file mode 100644 index 000000000000..a6f03fa2607e --- /dev/null +++ b/hassio/src/addon-view/data/hassio-addon-sections.ts @@ -0,0 +1,64 @@ +import memoizeOne from "memoize-one"; + +import { HassioAddonDetails } from "../../../../src/data/hassio/addon"; +import { PageNavigation } from "../../../../src/layouts/hass-tabs-subpage"; + +export const getAddonSections = memoizeOne( + (addon: HassioAddonDetails): PageNavigation[] => { + const sections: PageNavigation[] = [ + { + component: "hassio-addon-info", + name: "Details", + path: `/hassio/addon/${addon.slug}/info`, + icon: "hassio:information-outline", + core: true, + }, + ]; + + if (addon && addon.version) { + if (addon.documentation) { + sections.push({ + component: "hassio-addon-docs", + name: "Documentation", + path: `/hassio/addon/${addon.slug}/docs`, + icon: "hassio:book-outline", + core: true, + }); + } + sections.push({ + component: "hassio-addon-config", + name: "Configuration", + path: `/hassio/addon/${addon.slug}/config`, + icon: "hassio:settings-outline", + core: true, + }); + if (addon.audio) { + sections.push({ + component: "hassio-addon-audio", + name: "Audio", + path: `/hassio/addon/${addon.slug}/audio`, + icon: "hassio:speaker", + core: true, + }); + } + if (addon.network) { + sections.push({ + component: "hassio-addon-network", + name: "Network", + path: `/hassio/addon/${addon.slug}/network`, + icon: "hassio:lan", + core: true, + }); + } + sections.push({ + component: "hassio-addon-logs", + name: "Logs", + path: `/hassio/addon/${addon.slug}/logs`, + icon: "hassio:text", + core: true, + }); + } + + return sections; + } +); diff --git a/hassio/src/addon-view/hassio-addon-audio.ts b/hassio/src/addon-view/hassio-addon-audio.ts index eeda1084a5a2..ef4c8cfec0b9 100644 --- a/hassio/src/addon-view/hassio-addon-audio.ts +++ b/hassio/src/addon-view/hassio-addon-audio.ts @@ -16,7 +16,7 @@ import { TemplateResult, } from "lit-element"; -import { HomeAssistant } from "../../../src/types"; +import { HomeAssistant, Route } from "../../../src/types"; import { HassioAddonDetails, setHassioAddonOption, @@ -28,11 +28,19 @@ import { } from "../../../src/data/hassio/hardware"; import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; @customElement("hassio-addon-audio") class HassioAddonAudio extends LitElement { @property() public hass!: HomeAssistant; @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; @property() private _error?: string; @property() private _inputDevices?: HassioHardwareAudioDevice[]; @property() private _outputDevices?: HassioHardwareAudioDevice[]; @@ -41,57 +49,69 @@ class HassioAddonAudio extends LitElement { protected render(): TemplateResult { return html` - -
- ${this._error - ? html` -
${this._error}
- ` - : ""} - - - - ${this._inputDevices && - this._inputDevices.map((item) => { - return html` - ${item.name} - `; - })} - - - - - ${this._outputDevices && - this._outputDevices.map((item) => { - return html` - ${item.name} - `; - })} - - -
-
- Save + +
+
+ +
+ ${this._error + ? html` +
${this._error}
+ ` + : ""} + + + + ${this._inputDevices && + this._inputDevices.map((item) => { + return html` + ${item.name} + `; + })} + + + + + ${this._outputDevices && + this._outputDevices.map((item) => { + return html` + ${item.name} + `; + })} + + +
+
+ Save +
+
+
- +
`; } @@ -100,7 +120,24 @@ class HassioAddonAudio extends LitElement { haStyle, hassioStyle, css` - :host, + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + width: 600px; + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } + } paper-card, paper-dropdown-menu { display: block; diff --git a/hassio/src/addon-view/hassio-addon-config.ts b/hassio/src/addon-view/hassio-addon-config.ts index 1a91052163b2..ac76b1c0936c 100644 --- a/hassio/src/addon-view/hassio-addon-config.ts +++ b/hassio/src/addon-view/hassio-addon-config.ts @@ -13,7 +13,7 @@ import { query, } from "lit-element"; -import { HomeAssistant } from "../../../src/types"; +import { HomeAssistant, Route } from "../../../src/types"; import { HassioAddonDetails, setHassioAddonOption, @@ -26,11 +26,19 @@ import "../../../src/components/ha-yaml-editor"; // tslint:disable-next-line: no-duplicate-imports import { HaYamlEditor } from "../../../src/components/ha-yaml-editor"; import { showConfirmationDialog } from "../../../src/dialogs/generic/show-dialog-box"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; @customElement("hassio-addon-config") class HassioAddonConfig extends LitElement { @property() public hass!: HomeAssistant; @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; @property() private _error?: string; @property({ type: Boolean }) private _configHasChanged = false; @@ -42,34 +50,46 @@ class HassioAddonConfig extends LitElement { const valid = editor ? editor.isValid : true; return html` - -
- - ${this._error - ? html` -
${this._error}
- ` - : ""} - ${valid - ? "" - : html` -
Invalid YAML
- `} -
-
- - Reset to defaults - - - Save - + +
+
+ +
+ + ${this._error + ? html` +
${this._error}
+ ` + : ""} + ${valid + ? "" + : html` +
Invalid YAML
+ `} +
+
+ + Reset to defaults + + + Save + +
+
+
- +
`; } @@ -78,8 +98,23 @@ class HassioAddonConfig extends LitElement { haStyle, hassioStyle, css` - :host { - display: block; + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + width: 600px; + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } } paper-card { display: block; diff --git a/hassio/src/addon-view/hassio-addon-docs.ts b/hassio/src/addon-view/hassio-addon-docs.ts new file mode 100644 index 000000000000..2495f3b8435e --- /dev/null +++ b/hassio/src/addon-view/hassio-addon-docs.ts @@ -0,0 +1,121 @@ +import "@material/mwc-button"; +import "@polymer/iron-icon/iron-icon"; +import "@polymer/paper-card/paper-card"; +import "@polymer/paper-tooltip/paper-tooltip"; +import { + css, + CSSResult, + customElement, + html, + LitElement, + property, + TemplateResult, +} from "lit-element"; + +import { + HassioAddonDetails, + fetchHassioAddonDocumentation, +} from "../../../src/data/hassio/addon"; +import { hassioStyle } from "../resources/hassio-style"; +import { haStyle } from "../../../src/resources/styles"; +import { HomeAssistant, Route } from "../../../src/types"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; +import "../../../src/components/ha-markdown"; + +@customElement("hassio-addon-docs") +class HassioAddonDocs extends LitElement { + @property() public hass!: HomeAssistant; + @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; + + private _documentation?: string; + + protected render(): TemplateResult { + return html` + +
+
+ ${this._documentation + ? html` + +
+ +
+
+ ` + : ""} +
+
+
+ `; + } + + static get styles(): CSSResult[] { + return [ + haStyle, + hassioStyle, + css` + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + width: 600px; + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } + } + .card-content { + padding: 0 16px 16px; + } + paper-card { + display: block; + margin-bottom: 16px; + } + `, + ]; + } + + protected firstUpdated(changedProps) { + super.firstUpdated(changedProps); + this._loadDocumentation(); + } + + private async _loadDocumentation(): Promise { + if (this.addon.documentation) { + const documentation = await fetchHassioAddonDocumentation( + this.hass, + this.addon.slug + ); + this._documentation = String(documentation); + this.requestUpdate(); + } + } +} +declare global { + interface HTMLElementTagNameMap { + "hassio-addon-docs": HassioAddonDocs; + } +} diff --git a/hassio/src/addon-view/hassio-addon-info.ts b/hassio/src/addon-view/hassio-addon-info.ts index 04b736f34f7f..78bb44863246 100644 --- a/hassio/src/addon-view/hassio-addon-info.ts +++ b/hassio/src/addon-view/hassio-addon-info.ts @@ -13,30 +13,32 @@ import { } from "lit-element"; import { classMap } from "lit-html/directives/class-map"; -import "../../../src/components/buttons/ha-call-api-button"; -import "../../../src/components/buttons/ha-progress-button"; -import "../../../src/components/ha-label-badge"; -import "../../../src/components/ha-markdown"; -import "../../../src/components/ha-switch"; -import "../components/hassio-card-content"; - import { fireEvent } from "../../../src/common/dom/fire_event"; import { HassioAddonDetails, HassioAddonSetOptionParams, HassioAddonSetSecurityParams, + fetchHassioAddonChangelog, + installHassioAddon, setHassioAddonOption, setHassioAddonSecurity, uninstallHassioAddon, - installHassioAddon, - fetchHassioAddonChangelog, } from "../../../src/data/hassio/addon"; import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; -import { HomeAssistant } from "../../../src/types"; +import { HomeAssistant, Route } from "../../../src/types"; import { navigate } from "../../../src/common/navigate"; import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio-markdown"; import { atLeastVersion } from "../../../src/common/config/version"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; +import "../../../src/components/buttons/ha-call-api-button"; +import "../../../src/components/buttons/ha-progress-button"; +import "../../../src/components/ha-label-badge"; +import "../../../src/components/ha-markdown"; +import "../../../src/components/ha-switch"; +import "../components/hassio-card-content"; const PERMIS_DESC = { rating: { @@ -95,53 +97,68 @@ const PERMIS_DESC = { class HassioAddonInfo extends LitElement { @property() public hass!: HomeAssistant; @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; @property() private _error?: string; @property({ type: Boolean }) private _installing = false; protected render(): TemplateResult { return html` - ${this._computeUpdateAvailable - ? html` - -
- - ${!this.addon.available - ? html` -

- This update is no longer compatible with your system. -

- ` - : ""} -
-
- - Update - - ${this.addon.changelog - ? html` - - Changelog - - ` - : ""} -
-
- ` - : ""} - ${!this.addon.protected - ? html` + +
+
+ ${this._computeUpdateAvailable + ? html` + +
+ + ${!this.addon.available + ? html` +

+ This update is no longer compatible with your + system. +

+ ` + : ""} +
+
+ + Update + + ${this.addon.changelog + ? html` + + Changelog + + ` + : ""} +
+
+ ` + : ""} + ${!this.addon.protected + ? html`
Protection mode on this add-on is disabled! This gives the add-on full access to the entire system, which adds security risks, and could damage your system when used incorrectly. Only disable the protection mode if you know, need AND trust the source of this add-on. @@ -152,334 +169,344 @@ class HassioAddonInfo extends LitElement {
` - : ""} - - -
-
- ${this.addon.name} -
- ${this.addon.version - ? html` - ${this.addon.version} - ${this._computeIsRunning + : ""} + +
+
+ ${this.addon.name} +
+ ${this.addon.version ? html` - + ${this.addon.version} + ${this._computeIsRunning + ? html` + + ` + : html` + + `} ` : html` - + ${this.addon.version_latest} `} - ` - : html` - ${this.addon.version_latest} - `} -
-
-
- ${this.addon.description}.
- Visit - - ${this.addon.name} page - for details. -
- ${this.addon.logo - ? html` - - ` - : ""} -
- - ${this.addon.host_network - ? html` - - ` - : ""} - ${this.addon.full_access - ? html` - - ` - : ""} - ${this.addon.homeassistant_api - ? html` - - ` - : ""} - ${this._computeHassioApi - ? html` - - ` - : ""} - ${this.addon.docker_api - ? html` - - ` - : ""} - ${this.addon.host_pid - ? html` - - ` - : ""} - ${this.addon.apparmor - ? html` - - ` - : ""} - ${this.addon.auth_api - ? html` - - ` - : ""} - ${this.addon.ingress - ? html` +
+
+
+ ${this.addon.description}.
+ Visit + + ${this.addon.name} page + for details. +
+ ${this.addon.logo + ? html` + + ` + : ""} +
- ` - : ""} -
- - ${this.addon.version - ? html` -
-
Start on boot
- + ${this.addon.host_network + ? html` + + ` + : ""} + ${this.addon.full_access + ? html` + + ` + : ""} + ${this.addon.homeassistant_api + ? html` + + ` + : ""} + ${this._computeHassioApi + ? html` + + ` + : ""} + ${this.addon.docker_api + ? html` + + ` + : ""} + ${this.addon.host_pid + ? html` + + ` + : ""} + ${this.addon.apparmor + ? html` + + ` + : ""} + ${this.addon.auth_api + ? html` + + ` + : ""} + ${this.addon.ingress + ? html` + + ` + : ""}
-
-
Auto update
- -
- ${this.addon.ingress + + ${this.addon.version ? html`
-
Show in sidebar
+
Start on boot
- ${this._computeCannotIngressSidebar - ? html` - - This option requires Home Assistant 0.92 or - later. - - ` - : ""}
- ` - : ""} - ${this._computeUsesProtectedOptions - ? html`
-
- Protection mode - - - - Grant the add-on elevated system access. - - -
+
Auto update
+ ${this.addon.ingress + ? html` +
+
Show in sidebar
+ + ${this._computeCannotIngressSidebar + ? html` + + This option requires Home Assistant 0.92 + or later. + + ` + : ""} +
+ ` + : ""} + ${this._computeUsesProtectedOptions + ? html` +
+
+ Protection mode + + + + Grant the add-on elevated system access. + + +
+ +
+ ` + : ""} ` : ""} - ` - : ""} - ${this._error - ? html` -
${this._error}
- ` - : ""} -
-
- ${this.addon.version - ? html` - - Uninstall - - ${this.addon.build + ${this._error ? html` - - Rebuild - +
${this._error}
` : ""} - ${this._computeIsRunning +
+
+ ${this.addon.version ? html` - - Restart - - - Stop - + Uninstall + + ${this.addon.build + ? html` + + Rebuild + + ` + : ""} + ${this._computeIsRunning + ? html` + + Restart + + + Stop + + ` + : html` + + Start + + `} + ${this._computeShowWebUI + ? html` + + + Open Web UI + + + ` + : ""} + ${this._computeShowIngressUI + ? html` + + Open Web UI + + ` + : ""} ` : html` - + This add-on is not available on your system. +

+ ` + : ""} + - Start -
+ Install + `} - ${this._computeShowWebUI - ? html` - - - Open web UI - - - ` - : ""} - ${this._computeShowIngressUI - ? html` - - Open web UI - - ` - : ""} - ` - : html` - ${!this.addon.available - ? html` -

- This add-on is not available on your system. -

- ` - : ""} - - Install - - `} -
- - - ${this.addon.long_description - ? html` - -
-
- ` - : ""} + + ${this.addon.long_description + ? html` + +
+ +
+
+ ` + : ""} +
+
+ `; } @@ -488,8 +515,23 @@ class HassioAddonInfo extends LitElement { haStyle, hassioStyle, css` - :host { - display: block; + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + width: 600px; + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } } paper-card { display: block; diff --git a/hassio/src/addon-view/hassio-addon-logs.ts b/hassio/src/addon-view/hassio-addon-logs.ts index 0f568df2c774..8cc2c8153e15 100644 --- a/hassio/src/addon-view/hassio-addon-logs.ts +++ b/hassio/src/addon-view/hassio-addon-logs.ts @@ -10,7 +10,7 @@ import { TemplateResult, query, } from "lit-element"; -import { HomeAssistant } from "../../../src/types"; +import { HomeAssistant, Route } from "../../../src/types"; import { HassioAddonDetails, fetchHassioAddonLogs, @@ -18,11 +18,19 @@ import { import { ANSI_HTML_STYLE, parseTextToColoredPre } from "../ansi-to-html"; import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; @customElement("hassio-addon-logs") class HassioAddonLogs extends LitElement { @property() public hass!: HomeAssistant; @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; @property() private _error?: string; @query("#content") private _logContent!: any; @@ -33,17 +41,30 @@ class HassioAddonLogs extends LitElement { protected render(): TemplateResult { return html` - - ${this._error - ? html` -
${this._error}
- ` - : ""} -
-
- Refresh + +
+
+ +
+ ${this._error + ? html` +
${this._error}
+ ` + : ""} +
+
+ Refresh +
+
+
- +
`; } @@ -53,11 +74,30 @@ class HassioAddonLogs extends LitElement { hassioStyle, ANSI_HTML_STYLE, css` - :host, + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + min-width: 600px; + max-width: calc(100% - 8px); + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } + } paper-card { display: block; } pre { + margin: 0; overflow-x: auto; white-space: pre-wrap; overflow-wrap: break-word; diff --git a/hassio/src/addon-view/hassio-addon-network.ts b/hassio/src/addon-view/hassio-addon-network.ts index 2ad9e008a7c4..ed4d8d3048a4 100644 --- a/hassio/src/addon-view/hassio-addon-network.ts +++ b/hassio/src/addon-view/hassio-addon-network.ts @@ -12,7 +12,7 @@ import { import { PaperInputElement } from "@polymer/paper-input/paper-input"; -import { HomeAssistant } from "../../../src/types"; +import { HomeAssistant, Route } from "../../../src/types"; import { HassioAddonDetails, HassioAddonSetOptionParams, @@ -21,6 +21,9 @@ import { import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; import { fireEvent } from "../../../src/common/dom/fire_event"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +import "../../../src/layouts/hass-tabs-subpage"; interface NetworkItem { description: string; @@ -36,6 +39,11 @@ interface NetworkItemInput extends PaperInputElement { class HassioAddonNetwork extends LitElement { @property() public hass!: HomeAssistant; @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; @property() private _error?: string; @property() private _config?: NetworkItem[]; @@ -45,53 +53,65 @@ class HassioAddonNetwork extends LitElement { } protected render(): TemplateResult { - if (!this._config) { - return html``; - } - return html` - -
- ${this._error - ? html` -
${this._error}
- ` - : ""} - - - - - - - - - ${this._config!.map((item) => { - return html` - - - - - - `; - })} - -
ContainerHostDescription
${item.container} - - ${item.description}
-
-
- - Reset to defaults - - Save -
-
+ + ${this._config + ? html` +
+
+ +
+ ${this._error + ? html` +
${this._error}
+ ` + : ""} + + + + + + + + + ${this._config!.map((item) => { + return html` + + + + + + `; + })} + +
ContainerHostDescription
${item.container} + + ${item.description}
+
+
+ + Reset to defaults + + Save +
+
+
+
+ ` + : ""} +
`; } @@ -100,8 +120,23 @@ class HassioAddonNetwork extends LitElement { haStyle, hassioStyle, css` - :host { - display: block; + .container { + display: flex; + width: 100%; + justify-content: center; + } + .content { + display: flex; + width: 600px; + margin-bottom: 24px; + padding: 24px 0 32px; + flex-direction: column; + } + @media only screen and (max-width: 600px) { + .content { + max-width: 100%; + min-width: 100%; + } } paper-card { display: block; diff --git a/hassio/src/addon-view/hassio-addon-router.ts b/hassio/src/addon-view/hassio-addon-router.ts new file mode 100644 index 000000000000..ab02153ab8dc --- /dev/null +++ b/hassio/src/addon-view/hassio-addon-router.ts @@ -0,0 +1,87 @@ +import "@polymer/app-route/app-route"; +import { property, customElement } from "lit-element"; + +import { + HassRouterPage, + RouterOptions, +} from "../../../src/layouts/hass-router-page"; +import { HomeAssistant, Route } from "../../../src/types"; +import { HassioAddonDetails } from "../../../src/data/hassio/addon"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; + +@customElement("hassio-addon-router") +class HaAddonRouter extends HassRouterPage { + @property() public hass!: HomeAssistant; + @property() public addon!: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; + @property() public route!: Route; + @property() public sections!: PageNavigation[]; + + protected routerOptions: RouterOptions = { + defaultPage: "info", + preloadAll: true, + showLoading: true, + routes: { + info: { + tag: "hassio-addon-info", + load: () => + import( + /* webpackChunkName: "hassio-addon-info" */ "./hassio-addon-info" + ), + }, + docs: { + tag: "hassio-addon-docs", + load: () => + import( + /* webpackChunkName: "hassio-addon-docs" */ "./hassio-addon-docs" + ), + }, + config: { + tag: "hassio-addon-config", + load: () => + import( + /* webpackChunkName: "hassio-addon-config" */ "./hassio-addon-config" + ), + }, + audio: { + tag: "hassio-addon-audio", + load: () => + import( + /* webpackChunkName: "hassio-addon-audio" */ "./hassio-addon-audio" + ), + }, + network: { + tag: "hassio-addon-network", + load: () => + import( + /* webpackChunkName: "hassio-addon-network" */ "./hassio-addon-network" + ), + }, + logs: { + tag: "hassio-addon-logs", + load: () => + import( + /* webpackChunkName: "hassio-addon-logs" */ "./hassio-addon-logs" + ), + }, + }, + }; + + protected updatePageEl(pageEl) { + pageEl.hass = this.hass; + pageEl.addon = this.addon; + pageEl.narrow = this.narrow; + pageEl.isWide = this.isWide; + pageEl.showAdvanced = this.showAdvanced; + pageEl.route = this.routeTail; + pageEl.sections = this.sections; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hassio-addon-router": HaAddonRouter; + } +} diff --git a/hassio/src/addon-view/hassio-addon-view.ts b/hassio/src/addon-view/hassio-addon-view.ts index 4f5b2cfd70c7..9068cc123810 100644 --- a/hassio/src/addon-view/hassio-addon-view.ts +++ b/hassio/src/addon-view/hassio-addon-view.ts @@ -20,18 +20,19 @@ import { } from "../../../src/data/hassio/addon"; import { hassioStyle } from "../resources/hassio-style"; import { haStyle } from "../../../src/resources/styles"; +import { PageNavigation } from "../../../src/layouts/hass-tabs-subpage"; +import { getAddonSections } from "./data/hassio-addon-sections"; -import "./hassio-addon-audio"; -import "./hassio-addon-config"; -import "./hassio-addon-info"; -import "./hassio-addon-logs"; -import "./hassio-addon-network"; +import "./hassio-addon-router"; @customElement("hassio-addon-view") class HassioAddonView extends LitElement { @property() public hass!: HomeAssistant; @property() public route!: Route; @property() public addon?: HassioAddonDetails; + @property() public narrow!: boolean; + @property() public isWide!: boolean; + @property() public showAdvanced!: boolean; protected render(): TemplateResult { if (!this.addon) { @@ -39,46 +40,26 @@ class HassioAddonView extends LitElement { `; } - return html` - -
- - ${this.addon && this.addon.version - ? html` - + const route: Route = { + prefix: `${this.route.prefix}/${this.addon.slug}`, + path: this.addon + ? this.route.path.substr(1).replace(this.addon.slug, "") + : "", + }; - ${this.addon.audio - ? html` - - ` - : ""} - ${this.addon.network - ? html` - - ` - : ""} + const sections: PageNavigation[] = getAddonSections(this.addon); - - ` - : ""} -
-
+ return html` + `; } @@ -91,32 +72,10 @@ class HassioAddonView extends LitElement { color: var(--primary-text-color); --paper-card-header-color: var(--primary-text-color); } - .content { - padding: 24px 0 32px; - display: flex; - flex-direction: column; - align-items: center; - } - hassio-addon-info, - hassio-addon-network, - hassio-addon-audio, - hassio-addon-config { - margin-bottom: 24px; - width: 600px; - } - hassio-addon-logs { - max-width: calc(100% - 8px); - min-width: 600px; - } - @media only screen and (max-width: 600px) { - hassio-addon-info, - hassio-addon-network, - hassio-addon-audio, - hassio-addon-config, - hassio-addon-logs { - max-width: 100%; - min-width: 100%; - } + paper-spinner-lite { + position: absolute; + top: calc(50% - 14px); + left: calc(50% - 14px); } `, ]; @@ -142,7 +101,10 @@ class HassioAddonView extends LitElement { } private async _routeDataChanged(routeData: Route): Promise { - const addon = routeData.path.substr(1); + let addon = routeData.path.substr(1); + if (addon.includes("/")) { + addon = addon.substring(0, addon.indexOf("/")); + } try { const addoninfo = await fetchHassioAddonInfo(this.hass, addon); this.addon = addoninfo; diff --git a/src/data/hassio/addon.ts b/src/data/hassio/addon.ts index 5599913bb8e3..8f01c8be9381 100644 --- a/src/data/hassio/addon.ts +++ b/src/data/hassio/addon.ts @@ -70,6 +70,7 @@ export interface HassioAddonDetails extends HassioAddonInfo { ingress_panel: boolean; ingress_entry: null | string; ingress_url: null | string; + documentation: boolean; } export interface HassioAddonsInfo { @@ -99,11 +100,15 @@ export interface HassioAddonSetOptionParams { network?: object | null; } -export const reloadHassioAddons = async (hass: HomeAssistant) => { +export const reloadHassioAddons = async ( + hass: HomeAssistant +): Promise => { await hass.callApi>("POST", `hassio/addons/reload`); }; -export const fetchHassioAddonsInfo = async (hass: HomeAssistant) => { +export const fetchHassioAddonsInfo = async ( + hass: HomeAssistant +): Promise => { return hassioApiResultExtractor( await hass.callApi>("GET", `hassio/addons`) ); @@ -112,7 +117,7 @@ export const fetchHassioAddonsInfo = async (hass: HomeAssistant) => { export const fetchHassioAddonInfo = async ( hass: HomeAssistant, slug: string -) => { +): Promise => { return hassioApiResultExtractor( await hass.callApi>( "GET", @@ -121,17 +126,24 @@ export const fetchHassioAddonInfo = async ( ); }; +export const fetchHassioAddonDocumentation = async ( + hass: HomeAssistant, + slug: string +): Promise => { + return hass.callApi("GET", `hassio/addons/${slug}/documentation`); +}; + export const fetchHassioAddonChangelog = async ( hass: HomeAssistant, slug: string -) => { +): Promise => { return hass.callApi("GET", `hassio/addons/${slug}/changelog`); }; export const fetchHassioAddonLogs = async ( hass: HomeAssistant, slug: string -) => { +): Promise => { return hass.callApi("GET", `hassio/addons/${slug}/logs`); }; @@ -151,7 +163,7 @@ export const setHassioAddonSecurity = async ( hass: HomeAssistant, slug: string, data: HassioAddonSetSecurityParams -) => { +): Promise => { await hass.callApi>( "POST", `hassio/addons/${slug}/security`, @@ -159,7 +171,10 @@ export const setHassioAddonSecurity = async ( ); }; -export const installHassioAddon = async (hass: HomeAssistant, slug: string) => { +export const installHassioAddon = async ( + hass: HomeAssistant, + slug: string +): Promise> => { return hass.callApi>( "POST", `hassio/addons/${slug}/install` @@ -169,7 +184,7 @@ export const installHassioAddon = async (hass: HomeAssistant, slug: string) => { export const uninstallHassioAddon = async ( hass: HomeAssistant, slug: string -) => { +): Promise => { await hass.callApi>( "POST", `hassio/addons/${slug}/uninstall` diff --git a/src/layouts/hass-tabs-subpage.ts b/src/layouts/hass-tabs-subpage.ts index 2198acf49b9a..fdac62351405 100644 --- a/src/layouts/hass-tabs-subpage.ts +++ b/src/layouts/hass-tabs-subpage.ts @@ -76,7 +76,7 @@ class HassTabsSubpage extends LitElement { ${page.translationKey ? this.hass.localize(page.translationKey) - : name} ` : ""}