diff --git a/src/dialogs/config-flow/step-flow-pick-handler.ts b/src/dialogs/config-flow/step-flow-pick-handler.ts index 38257e66aa22..cd0652bcc275 100644 --- a/src/dialogs/config-flow/step-flow-pick-handler.ts +++ b/src/dialogs/config-flow/step-flow-pick-handler.ts @@ -1,5 +1,4 @@ -import "@polymer/paper-item/paper-icon-item"; -import "@polymer/paper-item/paper-item-body"; +import "@material/mwc-list/mwc-list-item"; import Fuse from "fuse.js"; import { css, @@ -12,12 +11,16 @@ import { import { customElement, property, state } from "lit/decorators"; import { styleMap } from "lit/directives/style-map"; import memoizeOne from "memoize-one"; +import { isComponentLoaded } from "../../common/config/is_component_loaded"; import { fireEvent } from "../../common/dom/fire_event"; +import { navigate } from "../../common/navigate"; import "../../common/search/search-input"; import { caseInsensitiveStringCompare } from "../../common/string/compare"; import { LocalizeFunc } from "../../common/translations/localize"; import "../../components/ha-icon-next"; +import { getConfigEntries } from "../../data/config_entries"; import { domainToName } from "../../data/integration"; +import { showZWaveJSAddNodeDialog } from "../../panels/config/integrations/integration-panels/zwave_js/show-dialog-zwave_js-add-node"; import { HomeAssistant } from "../../types"; import { brandsUrl } from "../../util/brands-url"; import { documentationUrl } from "../../util/documentation-url"; @@ -26,6 +29,7 @@ import { configFlowContentStyles } from "./styles"; interface HandlerObj { name: string; slug: string; + is_add?: boolean; } declare global { @@ -77,6 +81,17 @@ class StepFlowPickHandler extends LitElement { protected render(): TemplateResult { const handlers = this._getHandlers(); + const addDeviceRows: HandlerObj[] = ["zha", "zwave_js"] + .filter((domain) => isComponentLoaded(this.hass, domain)) + .map((domain) => ({ + name: this.hass.localize( + `ui.panel.config.integrations.add_${domain}_device` + ), + slug: domain, + is_add: true, + })) + .sort((a, b) => caseInsensitiveStringCompare(a.name, b.name)); + return html`

${this.hass.localize("ui.panel.config.integrations.new")}

+ ${addDeviceRows.length + ? html` + ${addDeviceRows.map((handler) => this._renderRow(handler))} +
+ ` + : ""} ${handlers.length - ? handlers.map( - (handler: HandlerObj) => - html` - - - - ${handler.name} - - - ` - ) + ? handlers.map((handler) => this._renderRow(handler)) : html`

${this.hass.localize( @@ -144,6 +143,31 @@ class StepFlowPickHandler extends LitElement { `; } + private _renderRow(handler: HandlerObj) { + return html` + + + ${handler.name} + ${handler.is_add ? "" : html``} + + `; + } + public willUpdate(changedProps: PropertyValues): void { if (this._filter === undefined && this.initialFilter !== undefined) { this._filter = this.initialFilter; @@ -161,20 +185,17 @@ class StepFlowPickHandler extends LitElement { protected updated(changedProps) { super.updated(changedProps); - // Store the width and height so that when we search, box doesn't jump - const div = this.shadowRoot!.querySelector("div")!; - if (!this._width) { - const width = div.clientWidth; - if (width) { - this._width = width; - } - } - if (!this._height) { - const height = div.clientHeight; - if (height) { - this._height = height; - } + if (!changedProps.has("handlers")) { + return; } + // Wait until list item initialized + const firstListItem = this.shadowRoot!.querySelector("mwc-list-item")!; + firstListItem.updateComplete.then(() => { + // Store the width and height so that when we search, box doesn't jump + const div = this.shadowRoot!.querySelector("div.container")!; + this._width = div.clientWidth; + this._height = div.clientHeight; + }); } private _getHandlers() { @@ -190,8 +211,31 @@ class StepFlowPickHandler extends LitElement { } private async _handlerPicked(ev) { + const handler: HandlerObj = ev.currentTarget.handler; + + if (handler.is_add) { + if (handler.slug === "zwave_js") { + const entries = await getConfigEntries(this.hass); + const entry = entries.find((ent) => ent.domain === "zwave_js"); + + if (!entry) { + return; + } + + showZWaveJSAddNodeDialog(this, { + entry_id: entry.entry_id, + }); + } else if (handler.slug === "zha") { + navigate("/config/zha/add"); + } + + // This closes dialog. + fireEvent(this, "flow-update"); + return; + } + fireEvent(this, "handler-picked", { - handler: ev.currentTarget.handler.slug, + handler: handler.slug, }); } @@ -219,7 +263,11 @@ class StepFlowPickHandler extends LitElement { } search-input { display: block; - margin: -12px 16px 0; + margin-top: 8px; + } + .divider { + margin: 8px 0; + border-top: 1px solid var(--divider-color); } ha-icon-next { margin-right: 8px; diff --git a/src/translations/en.json b/src/translations/en.json index 547d8ff918a0..cafd39ed58b6 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2478,6 +2478,8 @@ "rename_dialog": "Edit the name of this config entry", "rename_input_label": "Entry name", "search": "Search integrations", + "add_zwave_js_device": "Add Z-Wave device", + "add_zha_device": "Add Zigbee device", "disable": { "show_disabled": "Show disabled integrations", "disabled_integrations": "{number} disabled",