From 1c17210948ebb689ac4d8cde761b1a4ac251540b Mon Sep 17 00:00:00 2001 From: Paulus Schoutsen Date: Mon, 8 Apr 2019 15:15:46 -0700 Subject: [PATCH] Clean up even more (#3074) --- gulp/tasks/gen-icons.js | 11 +- hassio/script/gen-icons.js | 9 +- .../addon-store/hassio-addon-repository.js | 103 ------------ .../addon-store/hassio-addon-repository.ts | 112 +++++++++++++ hassio/src/addon-store/hassio-addon-store.js | 92 ----------- hassio/src/addon-store/hassio-addon-store.ts | 116 ++++++++++++++ .../addon-store/hassio-repositories-editor.js | 120 -------------- .../addon-store/hassio-repositories-editor.ts | 148 ++++++++++++++++++ hassio/src/addon-view/hassio-addon-info.js | 8 +- hassio/src/addon-view/hassio-addon-view.js | 20 +-- hassio/src/components/hassio-card-content.js | 90 ----------- hassio/src/components/hassio-card-content.ts | 97 ++++++++++++ hassio/src/dashboard/hassio-dashboard.js | 38 ----- hassio/src/dashboard/hassio-dashboard.ts | 52 ++++++ hassio/src/hassio-main.ts | 9 +- hassio/src/hassio-pages-with-tabs.ts | 11 +- hassio/src/hassio-tabs-router.ts | 11 +- .../src/ingress-view/hassio-ingress-view.ts | 63 ++++---- hassio/src/resources/hassio-style.js | 102 ++++++------ hassio/src/system/hassio-host-info.js | 2 +- hassio/src/system/hassio-supervisor-info.js | 2 +- hassio/src/system/hassio-system.js | 3 +- src/data/hassio.ts | 67 +++++++- src/layouts/hass-router-page.ts | 5 +- src/layouts/loading-screen.ts | 35 +++++ 25 files changed, 761 insertions(+), 565 deletions(-) delete mode 100644 hassio/src/addon-store/hassio-addon-repository.js create mode 100644 hassio/src/addon-store/hassio-addon-repository.ts delete mode 100644 hassio/src/addon-store/hassio-addon-store.js create mode 100644 hassio/src/addon-store/hassio-addon-store.ts delete mode 100644 hassio/src/addon-store/hassio-repositories-editor.js create mode 100644 hassio/src/addon-store/hassio-repositories-editor.ts delete mode 100644 hassio/src/components/hassio-card-content.js create mode 100644 hassio/src/components/hassio-card-content.ts delete mode 100644 hassio/src/dashboard/hassio-dashboard.js create mode 100644 hassio/src/dashboard/hassio-dashboard.ts create mode 100644 src/layouts/loading-screen.ts diff --git a/gulp/tasks/gen-icons.js b/gulp/tasks/gen-icons.js index b0afecb43a..c47b42f360 100644 --- a/gulp/tasks/gen-icons.js +++ b/gulp/tasks/gen-icons.js @@ -44,7 +44,7 @@ function transformXMLtoPolymer(name, xml) { // Given an iconset name and icon names, generate a polymer iconset function generateIconset(name, iconNames) { - const iconDefs = iconNames + const iconDefs = Array.from(iconNames) .map((name) => { const iconDef = loadIcon(name); if (!iconDef) { @@ -95,12 +95,15 @@ function findIcons(path, iconsetName) { } mapFiles(path, ".js", processFile); mapFiles(path, ".ts", processFile); - return Array.from(icons); + return icons; } function genHassIcons() { - const iconNames = findIcons("./src", "hass").concat(BUILT_IN_PANEL_ICONS); - fs.existsSync(OUTPUT_DIR) || fs.mkdirSync(OUTPUT_DIR); + const iconNames = findIcons("./src", "hass"); + BUILT_IN_PANEL_ICONS.forEach((name) => iconNames.add(name)); + if (!fs.existsSync(OUTPUT_DIR)) { + fs.mkdirSync(OUTPUT_DIR); + } fs.writeFileSync(HASS_OUTPUT_PATH, generateIconset("hass", iconNames)); } diff --git a/hassio/script/gen-icons.js b/hassio/script/gen-icons.js index 0c952ad04d..61fc39e212 100755 --- a/hassio/script/gen-icons.js +++ b/hassio/script/gen-icons.js @@ -6,10 +6,13 @@ const { genMDIIcons, } = require("../../gulp/tasks/gen-icons.js"); -const MENU_BUTTON_ICON = "menu"; - function genHassioIcons() { - const iconNames = findIcons("./src", "hassio").concat(MENU_BUTTON_ICON); + const iconNames = findIcons("./src", "hassio"); + + for (const item of findIcons("../src", "hassio")) { + iconNames.add(item); + } + fs.writeFileSync("./hassio-icons.html", generateIconset("hassio", iconNames)); } diff --git a/hassio/src/addon-store/hassio-addon-repository.js b/hassio/src/addon-store/hassio-addon-repository.js deleted file mode 100644 index cc95f068bf..0000000000 --- a/hassio/src/addon-store/hassio-addon-repository.js +++ /dev/null @@ -1,103 +0,0 @@ -import "@polymer/paper-card/paper-card"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../components/hassio-card-content"; -import "../resources/hassio-style"; -import NavigateMixin from "../../../src/mixins/navigate-mixin"; - -class HassioAddonRepository extends NavigateMixin(PolymerElement) { - static get template() { - return html` - - - `; - } - - static get properties() { - return { - hass: Object, - repo: Object, - addons: Array, - }; - } - - sortAddons(a, b) { - return a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1; - } - - computeIcon(addon) { - return addon.installed && addon.installed !== addon.version - ? "hassio:arrow-up-bold-circle" - : "hassio:puzzle"; - } - - computeIconTitle(addon) { - if (addon.installed) - return addon.installed !== addon.version - ? "New version available" - : "Add-on is installed"; - return addon.available - ? "Add-on is not installed" - : "Add-on is not available on your system"; - } - - computeIconClass(addon) { - if (addon.installed) - return addon.installed !== addon.version ? "update" : "installed"; - return !addon.available ? "not_available" : ""; - } - - computeClass(addon) { - return !addon.available ? "not_available" : ""; - } - - addonTapped(ev) { - this.navigate(`/hassio/addon/${ev.model.addon.slug}`); - } -} - -customElements.define("hassio-addon-repository", HassioAddonRepository); diff --git a/hassio/src/addon-store/hassio-addon-repository.ts b/hassio/src/addon-store/hassio-addon-repository.ts new file mode 100644 index 0000000000..dd5a56ea46 --- /dev/null +++ b/hassio/src/addon-store/hassio-addon-repository.ts @@ -0,0 +1,112 @@ +import { + css, + TemplateResult, + html, + LitElement, + property, + CSSResultArray, +} from "lit-element"; +import "@polymer/paper-card/paper-card"; + +import "../components/hassio-card-content"; +import { hassioStyle } from "../resources/hassio-style"; +import { HomeAssistant } from "../../../src/types"; +import { + HassioAddonInfo, + HassioAddonRepository, +} from "../../../src/data/hassio"; +import { navigate } from "../../../src/common/navigate"; + +class HassioAddonRepositoryEl extends LitElement { + @property() public hass!: HomeAssistant; + @property() public repo!: HassioAddonRepository; + @property() public addons!: HassioAddonInfo[]; + + protected render(): TemplateResult | void { + const repo = this.repo; + return html` +
+
+ ${repo.name} +
+ Maintained by ${repo.maintainer}
+ ${repo.url} +
+
+ + ${this.addons + .sort((a, b) => + a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1 + ) + .map( + (addon) => html` + +
+ +
+
+ ` + )} +
+ `; + } + + private computeIcon(addon) { + return addon.installed && addon.installed !== addon.version + ? "hassio:arrow-up-bold-circle" + : "hassio:puzzle"; + } + + private computeIconTitle(addon) { + if (addon.installed) { + return addon.installed !== addon.version + ? "New version available" + : "Add-on is installed"; + } + return addon.available + ? "Add-on is not installed" + : "Add-on is not available on your system"; + } + + private computeIconClass(addon) { + if (addon.installed) { + return addon.installed !== addon.version ? "update" : "installed"; + } + return !addon.available ? "not_available" : ""; + } + + private addonTapped(ev) { + navigate(this, `/hassio/addon/${ev.currentTarget.addon.slug}`); + } + + static get styles(): CSSResultArray { + return [ + hassioStyle, + css` + paper-card { + cursor: pointer; + } + .not_available { + opacity: 0.6; + } + a.repo { + color: var(--primary-text-color); + } + `, + ]; + } +} + +customElements.define("hassio-addon-repository", HassioAddonRepositoryEl); diff --git a/hassio/src/addon-store/hassio-addon-store.js b/hassio/src/addon-store/hassio-addon-store.js deleted file mode 100644 index 4e49bc6628..0000000000 --- a/hassio/src/addon-store/hassio-addon-store.js +++ /dev/null @@ -1,92 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "./hassio-addon-repository"; -import "./hassio-repositories-editor"; - -class HassioAddonStore extends PolymerElement { - static get template() { - return html` - - - - - `; - } - - static get properties() { - return { - hass: Object, - addons: Array, - repos: Array, - }; - } - - ready() { - super.ready(); - this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev)); - this.loadData(); - } - - apiCalled(ev) { - if (ev.detail.success) { - this.loadData(); - } - } - - sortRepos(a, b) { - if (a.slug === "local") { - return -1; - } - if (b.slug === "local") { - return 1; - } - if (a.slug === "core") { - return -1; - } - if (b.slug === "core") { - return 1; - } - return a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1; - } - - computeAddons(repo) { - return this.addons.filter(function(addon) { - return addon.repository === repo; - }); - } - - loadData() { - this.hass.callApi("get", "hassio/addons").then( - (info) => { - this.addons = info.data.addons; - this.repos = info.data.repositories; - }, - () => { - this.addons = []; - this.repos = []; - } - ); - } - - refreshData() { - this.hass.callApi("post", "hassio/addons/reload").then(() => { - this.loadData(); - }); - } -} - -customElements.define("hassio-addon-store", HassioAddonStore); diff --git a/hassio/src/addon-store/hassio-addon-store.ts b/hassio/src/addon-store/hassio-addon-store.ts new file mode 100644 index 0000000000..35440bb58e --- /dev/null +++ b/hassio/src/addon-store/hassio-addon-store.ts @@ -0,0 +1,116 @@ +import "./hassio-addon-repository"; +import "./hassio-repositories-editor"; +import { TemplateResult, html } from "lit-html"; +import { + LitElement, + CSSResult, + css, + property, + PropertyValues, +} from "lit-element"; +import { HomeAssistant } from "../../../src/types"; +import { + HassioAddonRepository, + HassioAddonInfo, + fetchHassioAddonsInfo, + reloadHassioAddons, +} from "../../../src/data/hassio"; +import "../../../src/layouts/loading-screen"; + +const sortRepos = (a: HassioAddonRepository, b: HassioAddonRepository) => { + if (a.slug === "local") { + return -1; + } + if (b.slug === "local") { + return 1; + } + if (a.slug === "core") { + return -1; + } + if (b.slug === "core") { + return 1; + } + return a.name.toUpperCase() < b.name.toUpperCase() ? -1 : 1; +}; + +class HassioAddonStore extends LitElement { + @property() public hass!: HomeAssistant; + @property() private _addons?: HassioAddonInfo[]; + @property() private _repos?: HassioAddonRepository[]; + + public async refreshData() { + this._repos = undefined; + this._addons = undefined; + await reloadHassioAddons(this.hass); + await this._loadData(); + } + + protected render(): TemplateResult | void { + if (!this._addons || !this._repos) { + return html` + + `; + } + const repos: TemplateResult[] = []; + + for (const repo of this._repos) { + const addons = this._addons!.filter( + (addon) => addon.repository === repo.slug + ); + + if (addons.length === 0) { + continue; + } + + repos.push(html` + + `); + } + + return html` + + + ${repos} + `; + } + + protected firstUpdated(changedProps: PropertyValues) { + super.firstUpdated(changedProps); + this.addEventListener("hass-api-called", (ev) => this.apiCalled(ev)); + this._loadData(); + } + + private apiCalled(ev) { + if (ev.detail.success) { + this._loadData(); + } + } + + private async _loadData() { + try { + const addonsInfo = await fetchHassioAddonsInfo(this.hass); + this._repos = addonsInfo.repositories; + this._repos.sort(sortRepos); + this._addons = addonsInfo.addons; + } catch (err) { + alert("Failed to fetch add-on info"); + } + } + + static get styles(): CSSResult { + return css` + hassio-addon-repository { + margin-top: 24px; + } + `; + } +} + +customElements.define("hassio-addon-store", HassioAddonStore); diff --git a/hassio/src/addon-store/hassio-repositories-editor.js b/hassio/src/addon-store/hassio-repositories-editor.js deleted file mode 100644 index 93455375d8..0000000000 --- a/hassio/src/addon-store/hassio-repositories-editor.js +++ /dev/null @@ -1,120 +0,0 @@ -import "@polymer/iron-icon/iron-icon"; -import "@polymer/paper-card/paper-card"; -import "@polymer/paper-input/paper-input"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../../../src/components/buttons/ha-call-api-button"; -import "../components/hassio-card-content"; -import "../resources/hassio-style"; - -class HassioRepositoriesEditor extends PolymerElement { - static get template() { - return html` - -
-
- Repositories -
- Configure which add-on repositories to fetch data from: -
-
- - -
- - -
-
- Add -
-
-
- `; - } - - 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.source); - return { addons_repositories: list }; - } - - computeAddRepoData(repoList, url) { - const list = repoList ? repoList.map((repo) => repo.source) : []; - list.push(url); - return { addons_repositories: list }; - } -} - -customElements.define("hassio-repositories-editor", HassioRepositoriesEditor); diff --git a/hassio/src/addon-store/hassio-repositories-editor.ts b/hassio/src/addon-store/hassio-repositories-editor.ts new file mode 100644 index 0000000000..f901ed5a35 --- /dev/null +++ b/hassio/src/addon-store/hassio-repositories-editor.ts @@ -0,0 +1,148 @@ +import { + LitElement, + html, + CSSResultArray, + css, + property, + TemplateResult, + customElement, + PropertyValues, +} from "lit-element"; +import "@polymer/iron-icon/iron-icon"; +import "@polymer/paper-card/paper-card"; +import "@polymer/paper-input/paper-input"; +import memoizeOne from "memoize-one"; + +import "../../../src/components/buttons/ha-call-api-button"; +import "../components/hassio-card-content"; +import { hassioStyle } from "../resources/hassio-style"; +import { HomeAssistant } from "../../../src/types"; +import { HassioAddonRepository } from "../../../src/data/hassio"; +import { PolymerChangedEvent } from "../../../src/polymer-types"; +import { repeat } from "lit-html/directives/repeat"; + +@customElement("hassio-repositories-editor") +class HassioRepositoriesEditor extends LitElement { + @property() public hass!: HomeAssistant; + @property() public repos!: HassioAddonRepository[]; + @property() private _repoUrl = ""; + + private _sortedRepos = memoizeOne((repos: HassioAddonRepository[]) => + repos + .filter((repo) => repo.slug !== "core" && repo.slug !== "local") + .sort((a, b) => (a.name < b.name ? -1 : 1)) + ); + + protected render(): TemplateResult | void { + const repos = this._sortedRepos(this.repos); + return html` +
+
+ Repositories +
+ Configure which add-on repositories to fetch data from: +
+
+ ${// Use repeat so that the fade-out from call-service-api-button + // stays with the correct repo after we add/delete one. + repeat( + repos, + (repo) => repo.slug, + (repo) => html` + +
+ +
+
+ + Remove + +
+
+ ` + )} + + +
+ + +
+
+ + Add + +
+
+
+ `; + } + + protected updated(changedProps: PropertyValues) { + super.updated(changedProps); + + if (changedProps.has("repos")) { + this._repoUrl = ""; + } + } + + private _urlChanged(ev: PolymerChangedEvent) { + this._repoUrl = ev.detail.value; + } + + private computeRemoveRepoData(repoList, url) { + const list = repoList + .filter((repo) => repo.url !== url) + .map((repo) => repo.source); + return { addons_repositories: list }; + } + + private computeAddRepoData(repoList, url) { + const list = repoList ? repoList.map((repo) => repo.source) : []; + list.push(url); + return { addons_repositories: list }; + } + + static get styles(): CSSResultArray { + return [ + hassioStyle, + css` + .add { + padding: 12px 16px; + } + iron-icon { + color: var(--secondary-text-color); + margin-right: 16px; + display: inline-block; + } + paper-input { + width: calc(100% - 49px); + display: inline-block; + } + `, + ]; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hassio-repositories-editor": HassioRepositoriesEditor; + } +} diff --git a/hassio/src/addon-view/hassio-addon-info.js b/hassio/src/addon-view/hassio-addon-info.js index 80db47a5ea..10d8de3ad5 100644 --- a/hassio/src/addon-view/hassio-addon-info.js +++ b/hassio/src/addon-view/hassio-addon-info.js @@ -168,12 +168,18 @@ class HassioAddonInfo extends EventsMixin(PolymerElement) { icon="hassio:arrow-up-bold-circle" icon-class="update" > +
Update + Update +
- + `; } @@ -141,10 +131,6 @@ class HassioAddonView extends PolymerElement { ); } - backTapped() { - history.back(); - } - _computeSlug(route) { return route.path.substr(1); } diff --git a/hassio/src/components/hassio-card-content.js b/hassio/src/components/hassio-card-content.js deleted file mode 100644 index 16876bba68..0000000000 --- a/hassio/src/components/hassio-card-content.js +++ /dev/null @@ -1,90 +0,0 @@ -import "@polymer/iron-icon/iron-icon"; -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "../../../src/components/ha-relative-time"; - -class HassioCardContent extends PolymerElement { - static get template() { - return html` - - -
-
[[title]]
-
- - - -
-
- `; - } - - static get properties() { - return { - hass: Object, - title: String, - description: String, - available: Boolean, - datetime: String, - icon: { - type: String, - value: "hass:help-circle", - }, - iconTitle: String, - iconClass: String, - }; - } -} -customElements.define("hassio-card-content", HassioCardContent); diff --git a/hassio/src/components/hassio-card-content.ts b/hassio/src/components/hassio-card-content.ts new file mode 100644 index 0000000000..82d1f6ab6a --- /dev/null +++ b/hassio/src/components/hassio-card-content.ts @@ -0,0 +1,97 @@ +import { + LitElement, + TemplateResult, + html, + CSSResult, + css, + property, + customElement, +} from "lit-element"; +import "@polymer/iron-icon/iron-icon"; + +import "../../../src/components/ha-relative-time"; +import { HomeAssistant } from "../../../src/types"; + +@customElement("hassio-card-content") +class HassioCardContent extends LitElement { + @property() public hass!: HomeAssistant; + @property() public title!: string; + @property() public description?: string; + @property() public available: boolean = true; + @property() public datetime?: string; + @property() public iconTitle?: string; + @property() public iconClass?: string; + @property() public icon = "hass:help-circle"; + + protected render(): TemplateResult | void { + return html` + +
+
${this.title}
+
+ ${this.description} ${this.available ? undefined : " (Not available"} + ${this.datetime + ? html` + + ` + : undefined} +
+
+ `; + } + + static get styles(): CSSResult { + return css` + iron-icon { + margin-right: 16px; + margin-top: 16px; + float: left; + color: var(--secondary-text-color); + } + iron-icon.update { + color: var(--paper-orange-400); + } + iron-icon.running, + iron-icon.installed { + color: var(--paper-green-400); + } + iron-icon.hassupdate, + iron-icon.snapshot { + color: var(--paper-item-icon-color); + } + iron-icon.not_available { + color: var(--google-red-500); + } + .title { + color: var(--primary-text-color); + white-space: nowrap; + text-overflow: ellipsis; + overflow: hidden; + } + .addition { + color: var(--secondary-text-color); + overflow: hidden; + position: relative; + height: 2.4em; + line-height: 1.2em; + } + ha-relative-time { + display: block; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hassio-card-content": HassioCardContent; + } +} diff --git a/hassio/src/dashboard/hassio-dashboard.js b/hassio/src/dashboard/hassio-dashboard.js deleted file mode 100644 index 05a0671b17..0000000000 --- a/hassio/src/dashboard/hassio-dashboard.js +++ /dev/null @@ -1,38 +0,0 @@ -import { html } from "@polymer/polymer/lib/utils/html-tag"; -import { PolymerElement } from "@polymer/polymer/polymer-element"; - -import "./hassio-addons"; -import "./hassio-hass-update"; -import EventsMixin from "../../../src/mixins/events-mixin"; - -class HassioDashboard extends EventsMixin(PolymerElement) { - static get template() { - return html` - -
- - -
- `; - } - - static get properties() { - return { - hass: Object, - supervisorInfo: Object, - hassInfo: Object, - }; - } -} - -customElements.define("hassio-dashboard", HassioDashboard); diff --git a/hassio/src/dashboard/hassio-dashboard.ts b/hassio/src/dashboard/hassio-dashboard.ts new file mode 100644 index 0000000000..aa312395b6 --- /dev/null +++ b/hassio/src/dashboard/hassio-dashboard.ts @@ -0,0 +1,52 @@ +import { + LitElement, + TemplateResult, + html, + CSSResult, + css, + property, + customElement, +} from "lit-element"; +import "./hassio-addons"; +import "./hassio-hass-update"; +import { HomeAssistant } from "../../../src/types"; +import { + HassioSupervisorInfo, + HassioHomeAssistantInfo, +} from "../../../src/data/hassio"; + +@customElement("hassio-dashboard") +class HassioDashboard extends LitElement { + @property() public hass!: HomeAssistant; + @property() public supervisorInfo!: HassioSupervisorInfo; + @property() public hassInfo!: HassioHomeAssistantInfo; + + protected render(): TemplateResult | void { + return html` +
+ + +
+ `; + } + + static get styles(): CSSResult { + return css` + .content { + margin: 0 auto; + } + `; + } +} + +declare global { + interface HTMLElementTagNameMap { + "hassio-dashboard": HassioDashboard; + } +} diff --git a/hassio/src/hassio-main.ts b/hassio/src/hassio-main.ts index 7fbf80a7fa..cc4123630c 100644 --- a/hassio/src/hassio-main.ts +++ b/hassio/src/hassio-main.ts @@ -14,6 +14,9 @@ import { fetchHassioSupervisorInfo, fetchHassioHostInfo, fetchHassioHomeAssistantInfo, + HassioSupervisorInfo, + HassioHostInfo, + HassioHomeAssistantInfo, } from "../../src/data/hassio"; import { makeDialogManager } from "../../src/dialogs/make-dialog-manager"; import { ProvideHassLitMixin } from "../../src/mixins/provide-hass-lit-mixin"; @@ -54,9 +57,9 @@ class HassioMain extends ProvideHassLitMixin(HassRouterPage) { }, }; - @property() private _supervisorInfo: any; - @property() private _hostInfo: any; - @property() private _hassInfo: any; + @property() private _supervisorInfo: HassioSupervisorInfo; + @property() private _hostInfo: HassioHostInfo; + @property() private _hassInfo: HassioHomeAssistantInfo; protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); diff --git a/hassio/src/hassio-pages-with-tabs.ts b/hassio/src/hassio-pages-with-tabs.ts index 9e33d12c27..adb43d373f 100644 --- a/hassio/src/hassio-pages-with-tabs.ts +++ b/hassio/src/hassio-pages-with-tabs.ts @@ -23,6 +23,11 @@ import scrollToTarget from "../../src/common/dom/scroll-to-target"; import { haStyle } from "../../src/resources/styles"; import { HomeAssistant, Route } from "../../src/types"; import { navigate } from "../../src/common/navigate"; +import { + HassioSupervisorInfo, + HassioHostInfo, + HassioHomeAssistantInfo, +} from "../../src/data/hassio"; const HAS_REFRESH_BUTTON = ["store", "snapshots"]; @@ -30,9 +35,9 @@ const HAS_REFRESH_BUTTON = ["store", "snapshots"]; class HassioPagesWithTabs extends LitElement { @property() public hass!: HomeAssistant; @property() public route!: Route; - @property() public supervisorInfo!: any; - @property() public hostInfo!: any; - @property() public hassInfo!: any; + @property() public supervisorInfo!: HassioSupervisorInfo; + @property() public hostInfo!: HassioHostInfo; + @property() public hassInfo!: HassioHomeAssistantInfo; protected render(): TemplateResult | void { const page = this._page; diff --git a/hassio/src/hassio-tabs-router.ts b/hassio/src/hassio-tabs-router.ts index 11f8d12710..11726c8c36 100644 --- a/hassio/src/hassio-tabs-router.ts +++ b/hassio/src/hassio-tabs-router.ts @@ -7,13 +7,18 @@ import { PolymerElement } from "@polymer/polymer"; import { HomeAssistant } from "../../src/types"; // Don't codesplit it, that way the dashboard always loads fast. import "./dashboard/hassio-dashboard"; +import { + HassioSupervisorInfo, + HassioHostInfo, + HassioHomeAssistantInfo, +} from "../../src/data/hassio"; @customElement("hassio-tabs-router") class HassioTabsRouter extends HassRouterPage { @property() public hass!: HomeAssistant; - @property() public supervisorInfo: any; - @property() public hostInfo: any; - @property() public hassInfo: any; + @property() public supervisorInfo: HassioSupervisorInfo; + @property() public hostInfo: HassioHostInfo; + @property() public hassInfo: HassioHomeAssistantInfo; protected routerOptions: RouterOptions = { routes: { diff --git a/hassio/src/ingress-view/hassio-ingress-view.ts b/hassio/src/ingress-view/hassio-ingress-view.ts index 303cfc4bbc..ff2b5f9221 100644 --- a/hassio/src/ingress-view/hassio-ingress-view.ts +++ b/hassio/src/ingress-view/hassio-ingress-view.ts @@ -11,7 +11,7 @@ import { import { HomeAssistant, Route } from "../../../src/types"; import { createHassioSession, - HassioAddon, + HassioAddonDetails, fetchHassioAddonInfo, } from "../../../src/data/hassio"; import "../../../src/layouts/hass-loading-screen"; @@ -20,24 +20,27 @@ import "../../../src/layouts/hass-subpage"; @customElement("hassio-ingress-view") class HassioIngressView extends LitElement { @property() public hass!: HomeAssistant; - @property() public route!: Route & { slug: string }; - @property() private _hasSession = false; - @property() private _addon?: HassioAddon; + @property() public route!: Route; + @property() private _addon?: HassioAddonDetails; protected render(): TemplateResult | void { - if (!this._hasSession || !this._addon) { + if (!this._addon) { return html` `; } - return html` - - - - - - + + const iframe = html` + `; + + return location.search === "?kiosk" + ? iframe + : html` + + ${iframe} + + `; } protected updated(changedProps: PropertyValues) { @@ -53,32 +56,30 @@ class HassioIngressView extends LitElement { const oldAddon = oldRoute ? oldRoute.path.substr(1) : undefined; if (addon && addon !== oldAddon) { - this._createSession(); - this._fetchAddonInfo(addon); + this._fetchData(addon); } } - private async _fetchAddonInfo(addonSlug: string) { + private async _fetchData(addonSlug: string) { try { - const addon = await fetchHassioAddonInfo(this.hass, addonSlug); - if (addon.ingress) { - this._addon = addon; - } else { - alert("This add-on does not support ingress."); - history.back(); + const [addon] = await Promise.all([ + fetchHassioAddonInfo(this.hass, addonSlug).catch(() => { + throw new Error("Failed to fetch add-on info"); + }), + createHassioSession(this.hass).catch(() => { + throw new Error("Failed to create an ingress session"); + }), + ]); + + if (!addon.ingress) { + throw new Error("This add-on does not support ingress"); } - } catch (err) { - alert("Failed to fetch add-on info"); - history.back(); - } - } - private async _createSession() { - try { - await createHassioSession(this.hass); - this._hasSession = true; + this._addon = addon; } catch (err) { - alert("Failed to generate a session"); + // tslint:disable-next-line + console.error(err); + alert(err.message || "Unknown error starting ingress."); history.back(); } } diff --git a/hassio/src/resources/hassio-style.js b/hassio/src/resources/hassio-style.js index 1541329c45..6eb6c2340a 100644 --- a/hassio/src/resources/hassio-style.js +++ b/hassio/src/resources/hassio-style.js @@ -1,56 +1,64 @@ +import { css } from "lit-element"; + const documentContainer = document.createElement("template"); documentContainer.setAttribute("style", "display: none;"); +export const hassioStyle = css` + .card-group { + margin-top: 24px; + } + .card-group .title { + color: var(--primary-text-color); + font-size: 2em; + padding-left: 8px; + margin-bottom: 8px; + } + .card-group .description { + font-size: 0.5em; + font-weight: 500; + margin-top: 4px; + } + .card-group paper-card { + --card-group-columns: 4; + width: calc( + (100% - 12px * var(--card-group-columns)) / var(--card-group-columns) + ); + margin: 4px; + vertical-align: top; + } + @media screen and (max-width: 1200px) and (min-width: 901px) { + .card-group paper-card { + --card-group-columns: 3; + } + } + @media screen and (max-width: 900px) and (min-width: 601px) { + .card-group paper-card { + --card-group-columns: 2; + } + } + @media screen and (max-width: 600px) and (min-width: 0) { + .card-group paper-card { + width: 100%; + margin: 4px 0; + } + .content { + padding: 0; + } + } + ha-call-api-button { + font-weight: 500; + color: var(--primary-color); + } + .error { + color: var(--google-red-500); + margin-top: 16px; + } +`; + documentContainer.innerHTML = ` `; diff --git a/hassio/src/system/hassio-host-info.js b/hassio/src/system/hassio-host-info.js index 929774165e..12ddb7b621 100644 --- a/hassio/src/system/hassio-host-info.js +++ b/hassio/src/system/hassio-host-info.js @@ -11,7 +11,7 @@ import { showHassioMarkdownDialog } from "../dialogs/markdown/show-dialog-hassio class HassioHostInfo extends EventsMixin(PolymerElement) { static get template() { return html` -