mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-23 01:06:35 +00:00
Show flows in progress when picking a handler (#8368)
This commit is contained in:
parent
6092af8de6
commit
b7d4c40736
@ -65,16 +65,18 @@ export const deleteConfigFlow = (hass: HomeAssistant, flowId: string) =>
|
|||||||
export const getConfigFlowHandlers = (hass: HomeAssistant) =>
|
export const getConfigFlowHandlers = (hass: HomeAssistant) =>
|
||||||
hass.callApi<string[]>("GET", "config/config_entries/flow_handlers");
|
hass.callApi<string[]>("GET", "config/config_entries/flow_handlers");
|
||||||
|
|
||||||
const fetchConfigFlowInProgress = (conn) =>
|
export const fetchConfigFlowInProgress = (
|
||||||
|
conn: Connection
|
||||||
|
): Promise<DataEntryFlowProgress[]> =>
|
||||||
conn.sendMessagePromise({
|
conn.sendMessagePromise({
|
||||||
type: "config_entries/flow/progress",
|
type: "config_entries/flow/progress",
|
||||||
});
|
});
|
||||||
|
|
||||||
const subscribeConfigFlowInProgressUpdates = (conn, store) =>
|
const subscribeConfigFlowInProgressUpdates = (conn: Connection, store) =>
|
||||||
conn.subscribeEvents(
|
conn.subscribeEvents(
|
||||||
debounce(
|
debounce(
|
||||||
() =>
|
() =>
|
||||||
fetchConfigFlowInProgress(conn).then((flows) =>
|
fetchConfigFlowInProgress(conn).then((flows: DataEntryFlowProgress[]) =>
|
||||||
store.setState(flows, true)
|
store.setState(flows, true)
|
||||||
),
|
),
|
||||||
500,
|
500,
|
||||||
|
@ -22,7 +22,9 @@ import {
|
|||||||
AreaRegistryEntry,
|
AreaRegistryEntry,
|
||||||
subscribeAreaRegistry,
|
subscribeAreaRegistry,
|
||||||
} from "../../data/area_registry";
|
} from "../../data/area_registry";
|
||||||
|
import { fetchConfigFlowInProgress } from "../../data/config_flow";
|
||||||
import type {
|
import type {
|
||||||
|
DataEntryFlowProgress,
|
||||||
DataEntryFlowProgressedEvent,
|
DataEntryFlowProgressedEvent,
|
||||||
DataEntryFlowStep,
|
DataEntryFlowStep,
|
||||||
} from "../../data/data_entry_flow";
|
} from "../../data/data_entry_flow";
|
||||||
@ -41,6 +43,7 @@ import "./step-flow-form";
|
|||||||
import "./step-flow-loading";
|
import "./step-flow-loading";
|
||||||
import "./step-flow-pick-handler";
|
import "./step-flow-pick-handler";
|
||||||
import "./step-flow-progress";
|
import "./step-flow-progress";
|
||||||
|
import "./step-flow-pick-flow";
|
||||||
|
|
||||||
let instance = 0;
|
let instance = 0;
|
||||||
|
|
||||||
@ -76,6 +79,10 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
|
|
||||||
@internalProperty() private _handlers?: string[];
|
@internalProperty() private _handlers?: string[];
|
||||||
|
|
||||||
|
@internalProperty() private _handler?: string;
|
||||||
|
|
||||||
|
@internalProperty() private _flowsInProgress?: DataEntryFlowProgress[];
|
||||||
|
|
||||||
private _unsubAreas?: UnsubscribeFunc;
|
private _unsubAreas?: UnsubscribeFunc;
|
||||||
|
|
||||||
private _unsubDevices?: UnsubscribeFunc;
|
private _unsubDevices?: UnsubscribeFunc;
|
||||||
@ -84,59 +91,93 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
this._params = params;
|
this._params = params;
|
||||||
this._instance = instance++;
|
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
|
// Create a new config flow. Show picker
|
||||||
if (!params.continueFlowId && !params.startFlowHandler) {
|
if (!params.flowConfig.getFlowHandlers) {
|
||||||
if (!params.flowConfig.getFlowHandlers) {
|
throw new Error("No getFlowHandlers defined in flow config");
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
await this.updateComplete;
|
||||||
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;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeDialog() {
|
public closeDialog() {
|
||||||
if (this._step) {
|
if (!this._params) {
|
||||||
this._flowDone();
|
return;
|
||||||
} else if (this._step === null) {
|
}
|
||||||
// Flow aborted during picking flow
|
const flowFinished = Boolean(
|
||||||
this._step = undefined;
|
this._step && ["create_entry", "abort"].includes(this._step.type)
|
||||||
this._params = undefined;
|
);
|
||||||
|
|
||||||
|
// 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 });
|
fireEvent(this, "dialog-closed", { dialog: this.localName });
|
||||||
}
|
}
|
||||||
@ -156,7 +197,9 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
>
|
>
|
||||||
<div>
|
<div>
|
||||||
${this._loading ||
|
${this._loading ||
|
||||||
(this._step === null && this._handlers === undefined)
|
(this._step === null &&
|
||||||
|
this._handlers === undefined &&
|
||||||
|
this._handler === undefined)
|
||||||
? html`
|
? html`
|
||||||
<step-flow-loading
|
<step-flow-loading
|
||||||
.label=${this.hass.localize(
|
.label=${this.hass.localize(
|
||||||
@ -178,15 +221,22 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
?rtl=${computeRTL(this.hass)}
|
?rtl=${computeRTL(this.hass)}
|
||||||
></ha-icon-button>
|
></ha-icon-button>
|
||||||
${this._step === null
|
${this._step === null
|
||||||
? // Show handler picker
|
? this._handler
|
||||||
html`
|
? html`<step-flow-pick-flow
|
||||||
<step-flow-pick-handler
|
|
||||||
.flowConfig=${this._params.flowConfig}
|
.flowConfig=${this._params.flowConfig}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.handlers=${this._handlers}
|
.handler=${this._handler}
|
||||||
.showAdvanced=${this._params.showAdvanced}
|
.flowsInProgress=${this._flowsInProgress}
|
||||||
></step-flow-pick-handler>
|
></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"
|
: this._step.type === "form"
|
||||||
? html`
|
? html`
|
||||||
<step-flow-form
|
<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(
|
private async _processStep(
|
||||||
step: DataEntryFlowStep | undefined | Promise<DataEntryFlowStep>
|
step: DataEntryFlowStep | undefined | Promise<DataEntryFlowStep>
|
||||||
): Promise<void> {
|
): Promise<void> {
|
||||||
@ -305,7 +392,7 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (step === undefined) {
|
if (step === undefined) {
|
||||||
this._flowDone();
|
this.closeDialog();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this._step = undefined;
|
this._step = undefined;
|
||||||
@ -313,38 +400,6 @@ class DataEntryFlowDialog extends LitElement {
|
|||||||
this._step = step;
|
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 {
|
static get styles(): CSSResultArray {
|
||||||
return [
|
return [
|
||||||
haStyleDialog,
|
haStyleDialog,
|
||||||
|
130
src/dialogs/config-flow/step-flow-pick-flow.ts
Normal file
130
src/dialogs/config-flow/step-flow-pick-flow.ts
Normal file
@ -0,0 +1,130 @@
|
|||||||
|
import "@polymer/paper-item/paper-icon-item";
|
||||||
|
import "@polymer/paper-item";
|
||||||
|
import "@polymer/paper-item/paper-item-body";
|
||||||
|
import {
|
||||||
|
css,
|
||||||
|
CSSResult,
|
||||||
|
customElement,
|
||||||
|
html,
|
||||||
|
LitElement,
|
||||||
|
property,
|
||||||
|
TemplateResult,
|
||||||
|
} from "lit-element";
|
||||||
|
import { fireEvent } from "../../common/dom/fire_event";
|
||||||
|
import "../../components/ha-icon-next";
|
||||||
|
import { localizeConfigFlowTitle } from "../../data/config_flow";
|
||||||
|
import { DataEntryFlowProgress } from "../../data/data_entry_flow";
|
||||||
|
import { domainToName } from "../../data/integration";
|
||||||
|
import { HomeAssistant } from "../../types";
|
||||||
|
import { brandsUrl } from "../../util/brands-url";
|
||||||
|
import { FlowConfig } from "./show-dialog-data-entry-flow";
|
||||||
|
import { configFlowContentStyles } from "./styles";
|
||||||
|
|
||||||
|
@customElement("step-flow-pick-flow")
|
||||||
|
class StepFlowPickFlow extends LitElement {
|
||||||
|
public flowConfig!: FlowConfig;
|
||||||
|
|
||||||
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
|
@property({ attribute: false })
|
||||||
|
public flowsInProgress!: DataEntryFlowProgress[];
|
||||||
|
|
||||||
|
@property() public handler!: string;
|
||||||
|
|
||||||
|
protected render(): TemplateResult {
|
||||||
|
return html`
|
||||||
|
<h2>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_flow.pick_flow_step.title"
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
|
||||||
|
<div>
|
||||||
|
${this.flowsInProgress.map(
|
||||||
|
(flow) => html` <paper-icon-item
|
||||||
|
@click=${this._flowInProgressPicked}
|
||||||
|
.flow=${flow}
|
||||||
|
>
|
||||||
|
<img
|
||||||
|
slot="item-icon"
|
||||||
|
loading="lazy"
|
||||||
|
src=${brandsUrl(flow.handler, "icon", true)}
|
||||||
|
referrerpolicy="no-referrer"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<paper-item-body>
|
||||||
|
${localizeConfigFlowTitle(this.hass.localize, flow)}
|
||||||
|
</paper-item-body>
|
||||||
|
<ha-icon-next></ha-icon-next>
|
||||||
|
</paper-icon-item>`
|
||||||
|
)}
|
||||||
|
<paper-item @click=${this._startNewFlowPicked} .handler=${this.handler}>
|
||||||
|
<paper-item-body>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.integrations.config_flow.pick_flow_step.new_flow",
|
||||||
|
"integration",
|
||||||
|
domainToName(this.hass.localize, this.handler)
|
||||||
|
)}
|
||||||
|
</paper-item-body>
|
||||||
|
<ha-icon-next></ha-icon-next>
|
||||||
|
</paper-item>
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
}
|
||||||
|
|
||||||
|
private _startNewFlowPicked(ev) {
|
||||||
|
this._startFlow(ev.currentTarget.handler);
|
||||||
|
}
|
||||||
|
|
||||||
|
private _startFlow(handler: string) {
|
||||||
|
fireEvent(this, "flow-update", {
|
||||||
|
stepPromise: this.flowConfig.createFlow(this.hass, handler),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private _flowInProgressPicked(ev) {
|
||||||
|
const flow: DataEntryFlowProgress = ev.currentTarget.flow;
|
||||||
|
fireEvent(this, "flow-update", {
|
||||||
|
stepPromise: this.flowConfig.fetchFlow(this.hass, flow.flow_id),
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
static get styles(): CSSResult[] {
|
||||||
|
return [
|
||||||
|
configFlowContentStyles,
|
||||||
|
css`
|
||||||
|
img {
|
||||||
|
width: 40px;
|
||||||
|
height: 40px;
|
||||||
|
}
|
||||||
|
ha-icon-next {
|
||||||
|
margin-right: 8px;
|
||||||
|
}
|
||||||
|
div {
|
||||||
|
overflow: auto;
|
||||||
|
max-height: 600px;
|
||||||
|
margin: 16px 0;
|
||||||
|
}
|
||||||
|
h2 {
|
||||||
|
padding-right: 66px;
|
||||||
|
}
|
||||||
|
@media all and (max-height: 900px) {
|
||||||
|
div {
|
||||||
|
max-height: calc(100vh - 134px);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
paper-icon-item,
|
||||||
|
paper-item {
|
||||||
|
cursor: pointer;
|
||||||
|
margin-bottom: 4px;
|
||||||
|
}
|
||||||
|
`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
interface HTMLElementTagNameMap {
|
||||||
|
"step-flow-pick-flow": StepFlowPickFlow;
|
||||||
|
}
|
||||||
|
}
|
@ -22,7 +22,6 @@ import { domainToName } from "../../data/integration";
|
|||||||
import { HomeAssistant } from "../../types";
|
import { HomeAssistant } from "../../types";
|
||||||
import { brandsUrl } from "../../util/brands-url";
|
import { brandsUrl } from "../../util/brands-url";
|
||||||
import { documentationUrl } from "../../util/documentation-url";
|
import { documentationUrl } from "../../util/documentation-url";
|
||||||
import { FlowConfig } from "./show-dialog-data-entry-flow";
|
|
||||||
import { configFlowContentStyles } from "./styles";
|
import { configFlowContentStyles } from "./styles";
|
||||||
|
|
||||||
interface HandlerObj {
|
interface HandlerObj {
|
||||||
@ -30,17 +29,24 @@ interface HandlerObj {
|
|||||||
slug: string;
|
slug: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
declare global {
|
||||||
|
// for fire event
|
||||||
|
interface HASSDomEvents {
|
||||||
|
"handler-picked": {
|
||||||
|
handler: string;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("step-flow-pick-handler")
|
@customElement("step-flow-pick-handler")
|
||||||
class StepFlowPickHandler extends LitElement {
|
class StepFlowPickHandler extends LitElement {
|
||||||
public flowConfig!: FlowConfig;
|
|
||||||
|
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
|
|
||||||
@property() public handlers!: string[];
|
@property() public handlers!: string[];
|
||||||
|
|
||||||
@property() public showAdvanced?: boolean;
|
@property() public showAdvanced?: boolean;
|
||||||
|
|
||||||
@internalProperty() private filter?: string;
|
@internalProperty() private _filter?: string;
|
||||||
|
|
||||||
private _width?: number;
|
private _width?: number;
|
||||||
|
|
||||||
@ -74,7 +80,7 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
const handlers = this._getHandlers(
|
const handlers = this._getHandlers(
|
||||||
this.handlers,
|
this.handlers,
|
||||||
this.filter,
|
this._filter,
|
||||||
this.hass.localize
|
this.hass.localize
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -82,7 +88,7 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
<h2>${this.hass.localize("ui.panel.config.integrations.new")}</h2>
|
<h2>${this.hass.localize("ui.panel.config.integrations.new")}</h2>
|
||||||
<search-input
|
<search-input
|
||||||
autofocus
|
autofocus
|
||||||
.filter=${this.filter}
|
.filter=${this._filter}
|
||||||
@value-changed=${this._filterChanged}
|
@value-changed=${this._filterChanged}
|
||||||
.label=${this.hass.localize("ui.panel.config.integrations.search")}
|
.label=${this.hass.localize("ui.panel.config.integrations.search")}
|
||||||
></search-input>
|
></search-input>
|
||||||
@ -164,15 +170,12 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _filterChanged(e) {
|
private async _filterChanged(e) {
|
||||||
this.filter = e.detail.value;
|
this._filter = e.detail.value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private async _handlerPicked(ev) {
|
private async _handlerPicked(ev) {
|
||||||
fireEvent(this, "flow-update", {
|
fireEvent(this, "handler-picked", {
|
||||||
stepPromise: this.flowConfig.createFlow(
|
handler: ev.currentTarget.handler.slug,
|
||||||
this.hass,
|
|
||||||
ev.currentTarget.handler.slug
|
|
||||||
),
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -195,6 +198,9 @@ class StepFlowPickHandler extends LitElement {
|
|||||||
overflow: auto;
|
overflow: auto;
|
||||||
max-height: 600px;
|
max-height: 600px;
|
||||||
}
|
}
|
||||||
|
h2 {
|
||||||
|
padding-right: 66px;
|
||||||
|
}
|
||||||
@media all and (max-height: 900px) {
|
@media all and (max-height: 900px) {
|
||||||
div {
|
div {
|
||||||
max-height: calc(100vh - 134px);
|
max-height: calc(100vh - 134px);
|
||||||
|
@ -2074,7 +2074,13 @@
|
|||||||
"description": "This step requires you to visit an external website to be completed.",
|
"description": "This step requires you to visit an external website to be completed.",
|
||||||
"open_site": "Open website"
|
"open_site": "Open website"
|
||||||
},
|
},
|
||||||
"loading_first_time": "Please wait while the integration is being installed"
|
"pick_flow_step": {
|
||||||
|
"title": "We discovered these, want to set them up?",
|
||||||
|
"new_flow": "No, set up an other instance of {integration}"
|
||||||
|
},
|
||||||
|
"loading_first_time": "Please wait while the integration is being installed",
|
||||||
|
"error": "Error",
|
||||||
|
"could_not_load": "Config flow could not be loaded"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"users": {
|
"users": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user