mirror of
https://github.com/home-assistant/frontend.git
synced 2025-11-09 02:49:51 +00:00
Show flows in progress when picking a handler (#8368)
This commit is contained in:
@@ -22,7 +22,9 @@ import {
|
||||
AreaRegistryEntry,
|
||||
subscribeAreaRegistry,
|
||||
} from "../../data/area_registry";
|
||||
import { fetchConfigFlowInProgress } from "../../data/config_flow";
|
||||
import type {
|
||||
DataEntryFlowProgress,
|
||||
DataEntryFlowProgressedEvent,
|
||||
DataEntryFlowStep,
|
||||
} from "../../data/data_entry_flow";
|
||||
@@ -41,6 +43,7 @@ import "./step-flow-form";
|
||||
import "./step-flow-loading";
|
||||
import "./step-flow-pick-handler";
|
||||
import "./step-flow-progress";
|
||||
import "./step-flow-pick-flow";
|
||||
|
||||
let instance = 0;
|
||||
|
||||
@@ -76,6 +79,10 @@ class DataEntryFlowDialog extends LitElement {
|
||||
|
||||
@internalProperty() private _handlers?: string[];
|
||||
|
||||
@internalProperty() private _handler?: string;
|
||||
|
||||
@internalProperty() private _flowsInProgress?: DataEntryFlowProgress[];
|
||||
|
||||
private _unsubAreas?: UnsubscribeFunc;
|
||||
|
||||
private _unsubDevices?: UnsubscribeFunc;
|
||||
@@ -84,59 +91,93 @@ class DataEntryFlowDialog extends LitElement {
|
||||
this._params = params;
|
||||
this._instance = instance++;
|
||||
|
||||
if (params.startFlowHandler) {
|
||||
this._checkFlowsInProgress(params.startFlowHandler);
|
||||
return;
|
||||
}
|
||||
|
||||
if (params.continueFlowId) {
|
||||
this._loading = true;
|
||||
const curInstance = this._instance;
|
||||
let step: DataEntryFlowStep;
|
||||
try {
|
||||
step = await params.flowConfig.fetchFlow(
|
||||
this.hass,
|
||||
params.continueFlowId
|
||||
);
|
||||
} catch (err) {
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.error"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.could_not_load"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Happens if second showDialog called
|
||||
if (curInstance !== this._instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._processStep(step);
|
||||
this._loading = false;
|
||||
return;
|
||||
}
|
||||
|
||||
// Create a new config flow. Show picker
|
||||
if (!params.continueFlowId && !params.startFlowHandler) {
|
||||
if (!params.flowConfig.getFlowHandlers) {
|
||||
throw new Error("No getFlowHandlers defined in flow config");
|
||||
if (!params.flowConfig.getFlowHandlers) {
|
||||
throw new Error("No getFlowHandlers defined in flow config");
|
||||
}
|
||||
this._step = null;
|
||||
|
||||
// We only load the handlers once
|
||||
if (this._handlers === undefined) {
|
||||
this._loading = true;
|
||||
try {
|
||||
this._handlers = await params.flowConfig.getFlowHandlers(this.hass);
|
||||
} finally {
|
||||
this._loading = false;
|
||||
}
|
||||
this._step = null;
|
||||
|
||||
// We only load the handlers once
|
||||
if (this._handlers === undefined) {
|
||||
this._loading = true;
|
||||
try {
|
||||
this._handlers = await params.flowConfig.getFlowHandlers(this.hass);
|
||||
} finally {
|
||||
this._loading = false;
|
||||
}
|
||||
}
|
||||
await this.updateComplete;
|
||||
return;
|
||||
}
|
||||
|
||||
this._loading = true;
|
||||
const curInstance = this._instance;
|
||||
let step: DataEntryFlowStep;
|
||||
try {
|
||||
step = await (params.continueFlowId
|
||||
? params.flowConfig.fetchFlow(this.hass, params.continueFlowId)
|
||||
: params.flowConfig.createFlow(this.hass, params.startFlowHandler!));
|
||||
} catch (err) {
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
showAlertDialog(this, {
|
||||
title: "Error",
|
||||
text: "Config flow could not be loaded",
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
||||
// Happens if second showDialog called
|
||||
if (curInstance !== this._instance) {
|
||||
return;
|
||||
}
|
||||
|
||||
this._processStep(step);
|
||||
this._loading = false;
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
public closeDialog() {
|
||||
if (this._step) {
|
||||
this._flowDone();
|
||||
} else if (this._step === null) {
|
||||
// Flow aborted during picking flow
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
if (!this._params) {
|
||||
return;
|
||||
}
|
||||
const flowFinished = Boolean(
|
||||
this._step && ["create_entry", "abort"].includes(this._step.type)
|
||||
);
|
||||
|
||||
// If we created this flow, delete it now.
|
||||
if (this._step && !flowFinished && !this._params.continueFlowId) {
|
||||
this._params.flowConfig.deleteFlow(this.hass, this._step.flow_id);
|
||||
}
|
||||
|
||||
if (this._step !== null && this._params.dialogClosedCallback) {
|
||||
this._params.dialogClosedCallback({
|
||||
flowFinished,
|
||||
});
|
||||
}
|
||||
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
this._devices = undefined;
|
||||
this._flowsInProgress = undefined;
|
||||
this._handler = undefined;
|
||||
if (this._unsubAreas) {
|
||||
this._unsubAreas();
|
||||
this._unsubAreas = undefined;
|
||||
}
|
||||
if (this._unsubDevices) {
|
||||
this._unsubDevices();
|
||||
this._unsubDevices = undefined;
|
||||
}
|
||||
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||
}
|
||||
@@ -156,7 +197,9 @@ class DataEntryFlowDialog extends LitElement {
|
||||
>
|
||||
<div>
|
||||
${this._loading ||
|
||||
(this._step === null && this._handlers === undefined)
|
||||
(this._step === null &&
|
||||
this._handlers === undefined &&
|
||||
this._handler === undefined)
|
||||
? html`
|
||||
<step-flow-loading
|
||||
.label=${this.hass.localize(
|
||||
@@ -178,15 +221,22 @@ class DataEntryFlowDialog extends LitElement {
|
||||
?rtl=${computeRTL(this.hass)}
|
||||
></ha-icon-button>
|
||||
${this._step === null
|
||||
? // Show handler picker
|
||||
html`
|
||||
<step-flow-pick-handler
|
||||
? this._handler
|
||||
? html`<step-flow-pick-flow
|
||||
.flowConfig=${this._params.flowConfig}
|
||||
.hass=${this.hass}
|
||||
.handlers=${this._handlers}
|
||||
.showAdvanced=${this._params.showAdvanced}
|
||||
></step-flow-pick-handler>
|
||||
`
|
||||
.handler=${this._handler}
|
||||
.flowsInProgress=${this._flowsInProgress}
|
||||
></step-flow-pick-flow>`
|
||||
: // Show handler picker
|
||||
html`
|
||||
<step-flow-pick-handler
|
||||
.hass=${this.hass}
|
||||
.handlers=${this._handlers}
|
||||
.showAdvanced=${this._params.showAdvanced}
|
||||
@handler-picked=${this._handlerPicked}
|
||||
></step-flow-pick-handler>
|
||||
`
|
||||
: this._step.type === "form"
|
||||
? html`
|
||||
<step-flow-form
|
||||
@@ -291,6 +341,43 @@ class DataEntryFlowDialog extends LitElement {
|
||||
});
|
||||
}
|
||||
|
||||
private async _checkFlowsInProgress(handler: string) {
|
||||
this._loading = true;
|
||||
|
||||
const flowsInProgress = (
|
||||
await fetchConfigFlowInProgress(this.hass.connection)
|
||||
).filter((flow) => flow.handler === handler);
|
||||
|
||||
if (!flowsInProgress.length) {
|
||||
let step: DataEntryFlowStep;
|
||||
try {
|
||||
step = await this._params!.flowConfig.createFlow(this.hass, handler);
|
||||
} catch (err) {
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
showAlertDialog(this, {
|
||||
title: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.error"
|
||||
),
|
||||
text: this.hass.localize(
|
||||
"ui.panel.config.integrations.config_flow.could_not_load"
|
||||
),
|
||||
});
|
||||
return;
|
||||
}
|
||||
this._processStep(step);
|
||||
} else {
|
||||
this._step = null;
|
||||
this._handler = handler;
|
||||
this._flowsInProgress = flowsInProgress;
|
||||
}
|
||||
this._loading = false;
|
||||
}
|
||||
|
||||
private _handlerPicked(ev) {
|
||||
this._checkFlowsInProgress(ev.detail.handler);
|
||||
}
|
||||
|
||||
private async _processStep(
|
||||
step: DataEntryFlowStep | undefined | Promise<DataEntryFlowStep>
|
||||
): Promise<void> {
|
||||
@@ -305,7 +392,7 @@ class DataEntryFlowDialog extends LitElement {
|
||||
}
|
||||
|
||||
if (step === undefined) {
|
||||
this._flowDone();
|
||||
this.closeDialog();
|
||||
return;
|
||||
}
|
||||
this._step = undefined;
|
||||
@@ -313,38 +400,6 @@ class DataEntryFlowDialog extends LitElement {
|
||||
this._step = step;
|
||||
}
|
||||
|
||||
private _flowDone(): void {
|
||||
if (!this._params) {
|
||||
return;
|
||||
}
|
||||
const flowFinished = Boolean(
|
||||
this._step && ["create_entry", "abort"].includes(this._step.type)
|
||||
);
|
||||
|
||||
// If we created this flow, delete it now.
|
||||
if (this._step && !flowFinished && !this._params.continueFlowId) {
|
||||
this._params.flowConfig.deleteFlow(this.hass, this._step.flow_id);
|
||||
}
|
||||
|
||||
if (this._params.dialogClosedCallback) {
|
||||
this._params.dialogClosedCallback({
|
||||
flowFinished,
|
||||
});
|
||||
}
|
||||
|
||||
this._step = undefined;
|
||||
this._params = undefined;
|
||||
this._devices = undefined;
|
||||
if (this._unsubAreas) {
|
||||
this._unsubAreas();
|
||||
this._unsubAreas = undefined;
|
||||
}
|
||||
if (this._unsubDevices) {
|
||||
this._unsubDevices();
|
||||
this._unsubDevices = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
static get styles(): CSSResultArray {
|
||||
return [
|
||||
haStyleDialog,
|
||||
|
||||
Reference in New Issue
Block a user