diff --git a/src/knx-router.ts b/src/knx-router.ts index c862cc26..4ed74bf1 100644 --- a/src/knx-router.ts +++ b/src/knx-router.ts @@ -1,5 +1,5 @@ import { mdiNetwork, mdiFolderMultipleOutline, mdiFileTreeOutline } from "@mdi/js"; -import { customElement, property, state } from "lit/decorators"; +import { customElement, property } from "lit/decorators"; import { HassRouterPage, RouterOptions } from "@ha/layouts/hass-router-page"; import { PageNavigation } from "@ha/layouts/hass-tabs-subpage"; @@ -12,7 +12,7 @@ const logger = new KNXLogger("router"); export const BASE_URL: string = "/knx"; -export const knxMainTabs: PageNavigation[] = [ +const knxMainTabs = (hasProject: boolean): PageNavigation[] => [ { translationKey: "info_title", path: `${BASE_URL}/info`, @@ -23,11 +23,15 @@ export const knxMainTabs: PageNavigation[] = [ path: `${BASE_URL}/group_monitor`, iconPath: mdiNetwork, }, - { - translationKey: "project_view_title", - path: `${BASE_URL}/project`, - iconPath: mdiFileTreeOutline, - }, + ...(hasProject + ? [ + { + translationKey: "project_view_title", + path: `${BASE_URL}/project`, + iconPath: mdiFileTreeOutline, + }, + ] + : []), { translationKey: "entities_view_title", path: `${BASE_URL}/entities`, @@ -45,9 +49,6 @@ export class KnxRouter extends HassRouterPage { @property({ type: Boolean }) public narrow!: boolean; - // at later point could dynamically add and delete tabs - @state() private _tabs: PageNavigation[] = knxMainTabs; - protected routerOptions: RouterOptions = { defaultPage: "info", beforeRender: (page: string) => (page === "" ? this.routerOptions.defaultPage : undefined), @@ -91,13 +92,13 @@ export class KnxRouter extends HassRouterPage { }; protected updatePageEl(el) { + logger.debug(`Current Page: ${this._currentPage} Route: ${this.route.path}`); + el.hass = this.hass; el.knx = this.knx; el.route = this.routeTail; el.narrow = this.narrow; - el.tabs = this._tabs; - - logger.debug(`Current Page: ${this._currentPage} Route: ${this.route.path}`); + el.tabs = knxMainTabs(!!this.knx.info.project); } } diff --git a/src/knx.ts b/src/knx.ts index 0c2ac4a1..527818bb 100644 --- a/src/knx.ts +++ b/src/knx.ts @@ -8,7 +8,7 @@ import { HomeAssistant } from "@ha/types"; import { localize } from "./localize/localize"; import { KNXLogger } from "./tools/knx-logger"; -import { getKnxProject } from "./services/websocket.service"; +import { getKnxInfoData, getKnxProject } from "./services/websocket.service"; import { KNX } from "./types/knx"; export class knxElement extends ProvideHassLitMixin(LitElement) { @@ -16,17 +16,22 @@ export class knxElement extends ProvideHassLitMixin(LitElement) { @property({ attribute: false }) public knx!: KNX; - protected _initKnx() { - getConfigEntries(this.hass, { domain: "knx" }).then((configEntries) => { + protected async _initKnx() { + try { + const knxConfigEntry = await getConfigEntries(this.hass, { domain: "knx" })[0]; // single instance allowed for knx config + const knxInfo = await getKnxInfoData(this.hass); this.knx = { language: this.hass.language, - config_entry: configEntries[0], // single instance allowed for knx config + config_entry: knxConfigEntry, localize: (string, replace) => localize(this.hass, string, replace), log: new KNXLogger(), + info: knxInfo, project: null, loadProject: () => this._loadProjectPromise(), }; - }); + } catch (err) { + new KNXLogger().error("Failed to initialize KNX", err); + } } private _loadProjectPromise(): Promise { diff --git a/src/main.ts b/src/main.ts index bc9a5f6d..06b59713 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,12 +1,9 @@ -import { LitElement, css, html, nothing } from "lit"; +import { LitElement, css, html } from "lit"; import { customElement, property } from "lit/decorators"; import { applyThemesOnElement } from "@ha/common/dom/apply_themes_on_element"; import { fireEvent } from "@ha/common/dom/fire_event"; import { mainWindow } from "@ha/common/dom/get_main_window"; -import "@ha/components/ha-top-app-bar-fixed"; -import "@ha/components/ha-menu-button"; -import "@ha/components/ha-tabs"; import { listenMediaQuery } from "@ha/common/dom/media_query"; import { computeRTL, computeDirectionStyles } from "@ha/common/util/compute_rtl"; import { navigate } from "@ha/common/navigate"; @@ -19,6 +16,13 @@ import "./knx-router"; import { KNX } from "./types/knx"; import { LocationChangedEvent } from "./types/navigation"; +declare global { + // for fire event + interface HASSDomEvents { + "knx-reload": undefined; + } +} + @customElement("knx-frontend") class KnxFrontend extends knxElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -38,6 +42,11 @@ class KnxFrontend extends knxElement { } this.addEventListener("knx-location-changed", (e) => this._setRoute(e as LocationChangedEvent)); + this.addEventListener("knx-reload", (_) => { + this.knx.log.debug("Reloading KNX object"); + this._initKnx(); + }); + computeDirectionStyles(computeRTL(this.hass), this.parentElement as LitElement); document.body.addEventListener("keydown", (ev: KeyboardEvent) => { @@ -62,7 +71,7 @@ class KnxFrontend extends knxElement { protected render() { if (!this.hass || !this.knx) { - return nothing; + return html`

Loading...

`; } return html` diff --git a/src/types/knx.ts b/src/types/knx.ts index 9772c0c3..036dbdd4 100644 --- a/src/types/knx.ts +++ b/src/types/knx.ts @@ -1,11 +1,12 @@ import { ConfigEntry } from "@ha/data/config_entries"; -import { KNXProjectRespone } from "./websocket"; +import { KNXInfoData, KNXProjectRespone } from "./websocket"; export interface KNX { language: string; config_entry: ConfigEntry; localize(string: string, replace?: Record): string; log: any; + info: KNXInfoData; project: KNXProjectRespone | null; loadProject(): Promise; } diff --git a/src/views/info.ts b/src/views/info.ts index e9926316..c285f7ce 100644 --- a/src/views/info.ts +++ b/src/views/info.ts @@ -2,27 +2,22 @@ import { mdiFileUpload } from "@mdi/js"; import { css, nothing, html, LitElement, TemplateResult, CSSResultGroup } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { navigate } from "@ha/common/navigate"; +import { fireEvent } from "@ha/common/dom/fire_event"; import "@ha/components/ha-card"; import "@ha/layouts/hass-tabs-subpage"; import type { PageNavigation } from "@ha/layouts/hass-tabs-subpage"; import "@ha/components/ha-button"; import "@ha/components/ha-file-upload"; import "@ha/components/ha-selector/ha-selector-text"; -import "@ha/components/ha-circular-progress"; import { uploadFile } from "@ha/data/file_upload"; import { extractApiErrorMessage } from "@ha/data/hassio/common"; import { showAlertDialog, showConfirmationDialog } from "@ha/dialogs/generic/show-dialog-box"; import { HomeAssistant, Route } from "@ha/types"; -import { - getKnxInfoData, - processProjectFile, - removeProjectFile, -} from "../services/websocket.service"; +import { processProjectFile, removeProjectFile } from "../services/websocket.service"; import { KNX } from "../types/knx"; -import { KNXInfoData, KNXProjectInfo } from "../types/websocket"; +import { KNXProjectInfo } from "../types/websocket"; import { KNXLogger } from "../tools/knx-logger"; import { VERSION } from "../version"; @@ -40,18 +35,12 @@ export class KNXInfo extends LitElement { @property({ type: Array, reflect: false }) public tabs!: PageNavigation[]; - @state() private knxInfoData: KNXInfoData | null = null; - @state() private _projectPassword?: string; @state() private _uploading = false; @state() private _projectFile?: File; - protected firstUpdated() { - this.loadKnxInfo(); - } - protected render(): TemplateResult | void { return html`
- ${this.knxInfoData - ? html` - ${this._renderInfoCard()} - ${this.knxInfoData?.project - ? this._renderProjectDataCard(this.knxInfoData.project) - : nothing} - ${this._renderProjectUploadCard()} - ` - : html` - - `} + ${this._renderInfoCard()} + ${this.knx.info.project ? this._renderProjectDataCard(this.knx.info.project) : nothing} + ${this._renderProjectUploadCard()}
`; @@ -85,7 +66,7 @@ export class KNXInfo extends LitElement {
XKNX Version
-
${this.knxInfoData?.version}
+
${this.knx.info.version}
@@ -96,13 +77,13 @@ export class KNXInfo extends LitElement {
${this.knx.localize("info_connected_to_bus")}
- ${this.hass.localize(this.knxInfoData?.connected ? "ui.common.yes" : "ui.common.no")} + ${this.hass.localize(this.knx.info.connected ? "ui.common.yes" : "ui.common.no")}
${this.knx.localize("info_individual_address")}
-
${this.knxInfoData?.current_address}
+
${this.knx.info.current_address}
@@ -156,7 +137,7 @@ export class KNXInfo extends LitElement { ${this.knx.localize("info_project_delete")} @@ -206,19 +187,6 @@ export class KNXInfo extends LitElement { `; } - private loadKnxInfo() { - getKnxInfoData(this.hass).then( - (knxInfoData) => { - this.knxInfoData = knxInfoData; - this.requestUpdate(); - }, - (err) => { - logger.error("getKnxInfoData", err); - navigate("/knx/error", { replace: true, data: err }); - }, - ); - } - private _filePicked(ev) { this._projectFile = ev.detail.files[0]; } @@ -250,7 +218,7 @@ export class KNXInfo extends LitElement { this._projectPassword = undefined; } this._uploading = false; - this.loadKnxInfo(); + fireEvent(this, "knx-reload"); } } @@ -271,7 +239,7 @@ export class KNXInfo extends LitElement { text: extractApiErrorMessage(err), }); } finally { - this.loadKnxInfo(); + fireEvent(this, "knx-reload"); } } @@ -385,10 +353,6 @@ export class KNXInfo extends LitElement { width: 100%; margin-top: 8px; } - - ha-circular-progress { - margin-top: 32px; - } `; } }