diff --git a/src/dialogs/config-flow/dialog-data-entry-flow.ts b/src/dialogs/config-flow/dialog-data-entry-flow.ts index 8fd26b47cb..0bed359665 100644 --- a/src/dialogs/config-flow/dialog-data-entry-flow.ts +++ b/src/dialogs/config-flow/dialog-data-entry-flow.ts @@ -9,23 +9,15 @@ import { html, nothing, } from "lit"; -import { customElement, state } from "lit/decorators"; +import { customElement, property, state } from "lit/decorators"; import { HASSDomEvent, fireEvent } from "../../common/dom/fire_event"; import "../../components/ha-circular-progress"; import "../../components/ha-dialog"; import "../../components/ha-icon-button"; -import { - AreaRegistryEntry, - subscribeAreaRegistry, -} from "../../data/area_registry"; import { DataEntryFlowStep, subscribeDataEntryFlowProgressed, } from "../../data/data_entry_flow"; -import { - DeviceRegistryEntry, - subscribeDeviceRegistry, -} from "../../data/device_registry"; import { haStyleDialog } from "../../resources/styles"; import type { HomeAssistant } from "../../types"; import { documentationUrl } from "../../util/documentation-url"; @@ -62,7 +54,7 @@ declare global { @customElement("dialog-data-entry-flow") class DataEntryFlowDialog extends LitElement { - public hass!: HomeAssistant; + @property({ attribute: false }) public hass!: HomeAssistant; @state() private _params?: DataEntryFlowDialogParams; @@ -76,16 +68,8 @@ class DataEntryFlowDialog extends LitElement { // Null means we need to pick a config flow | null; - @state() private _devices?: DeviceRegistryEntry[]; - - @state() private _areas?: AreaRegistryEntry[]; - @state() private _handler?: string; - private _unsubAreas?: UnsubscribeFunc; - - private _unsubDevices?: UnsubscribeFunc; - private _unsubDataEntryFlowProgressed?: Promise; public async showDialog(params: DataEntryFlowDialogParams): Promise { @@ -183,16 +167,7 @@ class DataEntryFlowDialog extends LitElement { this._loading = undefined; this._step = undefined; this._params = undefined; - this._devices = undefined; this._handler = undefined; - if (this._unsubAreas) { - this._unsubAreas(); - this._unsubAreas = undefined; - } - if (this._unsubDevices) { - this._unsubDevices(); - this._unsubDevices = undefined; - } if (this._unsubDataEntryFlowProgressed) { this._unsubDataEntryFlowProgressed.then((unsub) => { unsub(); @@ -309,25 +284,13 @@ class DataEntryFlowDialog extends LitElement { .hass=${this.hass} > ` - : this._devices === undefined || - this._areas === undefined - ? // When it's a create entry result, we will fetch device & area registry - html` - - ` - : html` - - `} + : html` + + `} `} @@ -351,32 +314,6 @@ class DataEntryFlowDialog extends LitElement { // external and progress step will send update event from the backend, so we should subscribe to them this._subscribeDataEntryFlowProgressed(); } - if (this._step.type === "create_entry") { - if (this._step.result && this._params!.flowConfig.loadDevicesAndAreas) { - this._fetchDevices(this._step.result.entry_id); - this._fetchAreas(); - } else { - this._devices = []; - this._areas = []; - } - } - } - - private async _fetchDevices(configEntryId) { - this._unsubDevices = subscribeDeviceRegistry( - this.hass.connection, - (devices) => { - this._devices = devices.filter((device) => - device.config_entries.includes(configEntryId) - ); - } - ); - } - - private async _fetchAreas() { - this._unsubAreas = subscribeAreaRegistry(this.hass.connection, (areas) => { - this._areas = areas; - }); } private async _processStep( diff --git a/src/dialogs/config-flow/show-dialog-config-flow.ts b/src/dialogs/config-flow/show-dialog-config-flow.ts index 33609402b2..6101e02466 100644 --- a/src/dialogs/config-flow/show-dialog-config-flow.ts +++ b/src/dialogs/config-flow/show-dialog-config-flow.ts @@ -20,7 +20,7 @@ export const showConfigFlowDialog = ( ): void => showFlowDialog(element, dialogParams, { flowType: "config_flow", - loadDevicesAndAreas: true, + showDevices: true, createFlow: async (hass, handler) => { const [step] = await Promise.all([ createConfigFlow(hass, handler, dialogParams.entryId), diff --git a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts index f35d8d88d6..62f71eb184 100644 --- a/src/dialogs/config-flow/show-dialog-data-entry-flow.ts +++ b/src/dialogs/config-flow/show-dialog-data-entry-flow.ts @@ -17,7 +17,7 @@ import type { HomeAssistant } from "../../types"; export interface FlowConfig { flowType: FlowType; - loadDevicesAndAreas: boolean; + showDevices: boolean; createFlow(hass: HomeAssistant, handler: string): Promise; @@ -134,8 +134,7 @@ export interface FlowConfig { export type LoadingReason = | "loading_handlers" | "loading_flow" - | "loading_step" - | "loading_devices_areas"; + | "loading_step"; export interface DataEntryFlowDialogParams { startFlowHandler?: string; diff --git a/src/dialogs/config-flow/show-dialog-options-flow.ts b/src/dialogs/config-flow/show-dialog-options-flow.ts index 089f0eee33..a58b304ad7 100644 --- a/src/dialogs/config-flow/show-dialog-options-flow.ts +++ b/src/dialogs/config-flow/show-dialog-options-flow.ts @@ -29,7 +29,7 @@ export const showOptionsFlowDialog = ( }, { flowType: "options_flow", - loadDevicesAndAreas: false, + showDevices: false, createFlow: async (hass, handler) => { const [step] = await Promise.all([ createOptionsFlow(hass, handler), diff --git a/src/dialogs/config-flow/step-flow-create-entry.ts b/src/dialogs/config-flow/step-flow-create-entry.ts index a897378c04..095a8af136 100644 --- a/src/dialogs/config-flow/step-flow-create-entry.ts +++ b/src/dialogs/config-flow/step-flow-create-entry.ts @@ -4,6 +4,7 @@ import { CSSResultGroup, html, LitElement, + nothing, PropertyValues, TemplateResult, } from "lit"; @@ -34,7 +35,16 @@ class StepFlowCreateEntry extends LitElement { @property({ attribute: false }) public step!: DataEntryFlowStepCreateEntry; - @property({ attribute: false }) public devices!: DeviceRegistryEntry[]; + private _devices = memoizeOne( + ( + showDevices: boolean, + devices: DeviceRegistryEntry[], + entry_id?: string + ) => + showDevices && entry_id + ? devices.filter((device) => device.config_entries.includes(entry_id)) + : [] + ); private _deviceEntities = memoizeOne( ( @@ -50,35 +60,48 @@ class StepFlowCreateEntry extends LitElement { ); protected willUpdate(changedProps: PropertyValues) { + if (!changedProps.has("devices") && !changedProps.has("hass")) { + return; + } + + const devices = this._devices( + this.flowConfig.showDevices, + Object.values(this.hass.devices), + this.step.result?.entry_id + ); + if ( - (changedProps.has("devices") || changedProps.has("hass")) && - this.devices.length === 1 + devices.length !== 1 || + devices[0].primary_config_entry !== this.step.result?.entry_id ) { - // integration_type === "device" - const assistSatellites = this._deviceEntities( - this.devices[0].id, - Object.values(this.hass.entities), - "assist_satellite" - ); - if ( - assistSatellites.length && - assistSatellites.some((satellite) => - assistSatelliteSupportsSetupFlow( - this.hass.states[satellite.entity_id] - ) - ) - ) { - this._flowDone(); - showVoiceAssistantSetupDialog(this, { - deviceId: this.devices[0].id, - }); - } + return; + } + + const assistSatellites = this._deviceEntities( + devices[0].id, + Object.values(this.hass.entities), + "assist_satellite" + ); + if ( + assistSatellites.length && + assistSatellites.some((satellite) => + assistSatelliteSupportsSetupFlow(this.hass.states[satellite.entity_id]) + ) + ) { + this._flowDone(); + showVoiceAssistantSetupDialog(this, { + deviceId: devices[0].id, + }); } } protected render(): TemplateResult { const localize = this.hass.localize; - + const devices = this._devices( + this.flowConfig.showDevices, + Object.values(this.hass.devices), + this.step.result?.entry_id + ); return html`

${localize("ui.panel.config.integrations.config_flow.success")}!

@@ -89,9 +112,9 @@ class StepFlowCreateEntry extends LitElement { "ui.panel.config.integrations.config_flow.not_loaded" )}` - : ""} - ${this.devices.length === 0 - ? "" + : nothing} + ${devices.length === 0 + ? nothing : html`

${localize( @@ -99,7 +122,7 @@ class StepFlowCreateEntry extends LitElement { )}:

- ${this.devices.map( + ${devices.map( (device) => html`
diff --git a/src/panels/config/repairs/show-dialog-repair-flow.ts b/src/panels/config/repairs/show-dialog-repair-flow.ts index 890c51eeca..149da94cf1 100644 --- a/src/panels/config/repairs/show-dialog-repair-flow.ts +++ b/src/panels/config/repairs/show-dialog-repair-flow.ts @@ -47,7 +47,7 @@ export const showRepairsFlowDialog = ( }, { flowType: "repair_flow", - loadDevicesAndAreas: false, + showDevices: false, createFlow: async (hass, handler) => { const [step] = await Promise.all([ createRepairsFlow(hass, handler, issue.issue_id),