From dd9683674d1c3a7c80ab9ce88e597aafe1aa85e1 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 26 Oct 2022 20:47:43 +0200 Subject: [PATCH] Add my link to add zwave and zigbee devices (#14126) --- .../integrations/protocolIntegrationPicked.ts | 41 ++++++++++++++++--- src/layouts/hass-error-screen.ts | 7 +++- .../integrations/ha-domain-integrations.ts | 3 +- .../zwave_js/zwave_js-add-node.ts | 26 ++++++++++++ .../zwave_js/zwave_js-config-router.ts | 18 ++++++++ src/panels/my/ha-panel-my.ts | 36 ++++++++++++++-- src/translations/en.json | 3 +- 7 files changed, 121 insertions(+), 13 deletions(-) create mode 100644 src/panels/config/integrations/integration-panels/zwave_js/zwave_js-add-node.ts diff --git a/src/common/integrations/protocolIntegrationPicked.ts b/src/common/integrations/protocolIntegrationPicked.ts index 0cebbea25b..52bd0b6316 100644 --- a/src/common/integrations/protocolIntegrationPicked.ts +++ b/src/common/integrations/protocolIntegrationPicked.ts @@ -1,5 +1,7 @@ import { html } from "lit"; import { getConfigEntries } from "../../data/config_entries"; +import { domainToName } from "../../data/integration"; +import { getIntegrationDescriptions } from "../../data/integrations"; import { showConfigFlowDialog } from "../../dialogs/config-flow/show-dialog-config-flow"; import { showConfirmationDialog } from "../../dialogs/generic/show-dialog-box"; import { showZWaveJSAddNodeDialog } from "../../panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node"; @@ -11,20 +13,38 @@ import { navigate } from "../navigate"; export const protocolIntegrationPicked = async ( element: HTMLElement, hass: HomeAssistant, - slug: string + domain: string, + options?: { brand?: string; domain?: string } ) => { - if (slug === "zwave_js") { + if (options?.domain) { + const localize = await hass.loadBackendTranslation("title", options.domain); + options.domain = domainToName(localize, options.domain); + } + + if (options?.brand) { + const integrationDescriptions = await getIntegrationDescriptions(hass); + options.brand = + integrationDescriptions.core.integration[options.brand]?.name || + options.brand; + } + + if (domain === "zwave_js") { const entries = await getConfigEntries(hass, { - domain: "zwave_js", + domain, }); if (!isComponentLoaded(hass, "zwave_js") || !entries.length) { // If the component isn't loaded, ask them to load the integration first showConfirmationDialog(element, { + title: hass.localize( + "ui.panel.config.integrations.config_flow.missing_zwave_zigbee_title", + { integration: "Z-Wave" } + ), text: hass.localize( "ui.panel.config.integrations.config_flow.missing_zwave_zigbee", { integration: "Z-Wave", + brand: options?.brand || options?.domain || "Z-Wave", supported_hardware_link: html`` : ""}
-

${this.error}

+ ${this.error} ${this.hass?.localize("ui.common.back")} @@ -83,10 +84,14 @@ class HassErrorScreen extends LitElement { align-items: center; justify-content: center; flex-direction: column; + box-sizing: border-box; } a { color: var(--primary-color); } + ha-alert { + margin-bottom: 16px; + } `, ]; } diff --git a/src/panels/config/integrations/ha-domain-integrations.ts b/src/panels/config/integrations/ha-domain-integrations.ts index 0de8b6c331..8a04cb3ee7 100644 --- a/src/panels/config/integrations/ha-domain-integrations.ts +++ b/src/panels/config/integrations/ha-domain-integrations.ts @@ -286,7 +286,8 @@ class HaDomainIntegrations extends LitElement { protocolIntegrationPicked( root instanceof ShadowRoot ? (root.host as HTMLElement) : this, this.hass, - domain + domain, + { brand: this.domain } ); } diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-add-node.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-add-node.ts new file mode 100644 index 0000000000..aa0b90937f --- /dev/null +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-add-node.ts @@ -0,0 +1,26 @@ +import { customElement } from "lit/decorators"; +import { navigate } from "../../../../../common/navigate"; +import { HomeAssistant } from "../../../../../types"; +import { showZWaveJSAddNodeDialog } from "./show-dialog-zwave_js-add-node"; + +@customElement("zwave_js-add-node") +export class DialogZWaveJSAddNode extends HTMLElement { + public hass!: HomeAssistant; + + public configEntryId!: string; + + connectedCallback() { + showZWaveJSAddNodeDialog(this, { + entry_id: this.configEntryId, + }); + navigate(`/config/devices/dashboard?config_entry=${this.configEntryId}`, { + replace: true, + }); + } +} + +declare global { + interface HTMLElementTagNameMap { + "zwave_js-add-node": DialogZWaveJSAddNode; + } +} diff --git a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-router.ts b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-router.ts index 6f9f165aaf..a8be9fa857 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-router.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/zwave_js-config-router.ts @@ -7,6 +7,7 @@ import { import { HomeAssistant } from "../../../../../types"; import { navigate } from "../../../../../common/navigate"; import { PageNavigation } from "../../../../../layouts/hass-tabs-subpage"; +import { getConfigEntries } from "../../../../../data/config_entries"; export const configTabs: PageNavigation[] = [ { @@ -41,6 +42,10 @@ class ZWaveJSConfigRouter extends HassRouterPage { tag: "zwave_js-config-dashboard", load: () => import("./zwave_js-config-dashboard"), }, + add: { + tag: "zwave_js-add-node", + load: () => import("./zwave_js-add-node"), + }, node_config: { tag: "zwave_js-node-config", load: () => import("./zwave_js-node-config"), @@ -54,6 +59,7 @@ class ZWaveJSConfigRouter extends HassRouterPage { load: () => import("./zwave_js-provisioned"), }, }, + initialLoad: () => this._fetchConfigEntries(), }; protected updatePageEl(el): void { @@ -74,6 +80,18 @@ class ZWaveJSConfigRouter extends HassRouterPage { ); } } + + private async _fetchConfigEntries() { + if (this._configEntry) { + return; + } + const entries = await getConfigEntries(this.hass, { + domain: "zwave_js", + }); + if (entries.length) { + this._configEntry = entries[0].entry_id; + } + } } declare global { diff --git a/src/panels/my/ha-panel-my.ts b/src/panels/my/ha-panel-my.ts index 4c8056f675..c5e60b5540 100644 --- a/src/panels/my/ha-panel-my.ts +++ b/src/panels/my/ha-panel-my.ts @@ -2,6 +2,7 @@ import { sanitizeUrl } from "@braintree/sanitize-url"; import { html, LitElement } from "lit"; import { customElement, property, state } from "lit/decorators"; import { isComponentLoaded } from "../../common/config/is_component_loaded"; +import { protocolIntegrationPicked } from "../../common/integrations/protocolIntegrationPicked"; import { navigate } from "../../common/navigate"; import { createSearchParam, @@ -74,6 +75,14 @@ export const getMyRedirects = (hasSupervisor: boolean): Redirects => ({ component: "zwave_js", redirect: "/config/zwave_js/dashboard", }, + add_zigbee_device: { + component: "zha", + redirect: "/config/zha/add", + }, + add_zwave_device: { + component: "zwave_js", + redirect: "/config/zwave_js/add", + }, config_energy: { component: "energy", redirect: "/config/energy/dashboard", @@ -295,7 +304,21 @@ class HaPanelMy extends LitElement { this._redirect.component && !isComponentLoaded(this.hass, this._redirect.component) ) { + this.hass.loadBackendTranslation("title", this._redirect.component); this._error = "no_component"; + if (["add_zwave_device", "add_zigbee_device"].includes(path)) { + const params = extractSearchParamsObject(); + const component = this._redirect.component; + this.hass + .loadFragmentTranslation("config") + .then() + .then(() => { + protocolIntegrationPicked(this, this.hass, component, { + domain: params.domain, + brand: params.brand, + }); + }); + } return; } @@ -343,9 +366,11 @@ class HaPanelMy extends LitElement { this.hass, `/integrations/${this._redirect!.component!}` )} - > - ${domainToName(this.hass.localize, this._redirect!.component!)} -
` + >${domainToName( + this.hass.localize, + this._redirect!.component! + )}` ) || "This redirect is not supported."; break; case "no_supervisor": @@ -363,7 +388,10 @@ class HaPanelMy extends LitElement { default: error = this.hass.localize("ui.panel.my.error") || "Unknown error"; } - return html``; + return html``; } return html``; } diff --git a/src/translations/en.json b/src/translations/en.json index 4bac5ab7bb..5aa0c39ff4 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -3036,7 +3036,8 @@ "could_not_load": "Config flow could not be loaded", "not_loaded": "The integration could not be loaded, try to restart Home Assistant.", "supported_brand_flow": "Support for {supported_brand} devices is provided by {flow_domain_name}. Do you want to continue?", - "missing_zwave_zigbee": "To add a {integration} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.", + "missing_zwave_zigbee": "To add a {brand} device, you first need {supported_hardware_link} and the {integration} integration set up. If you already have the hardware then you can proceed with the setup of {integration}.", + "missing_zwave_zigbee_title": "{integration} is not setup", "supported_hardware": "supported hardware", "proceed": "Proceed" }