mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-26 18:56:39 +00:00
Z-Wave: Prevent closing the Add Device dialog when user input is required (#20999)
* prevent closing the Z-Wave Add node dialog when user input is required * ask user for confirmation before leaving page during bootstrapping * fix: no non-null assertion
This commit is contained in:
parent
c7b4e8f37c
commit
9a3f7df25e
@ -3,6 +3,7 @@ import { mdiAlertCircle, mdiCheckCircle, mdiQrcodeScan } from "@mdi/js";
|
|||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, query, state } from "lit/decorators";
|
import { customElement, property, query, state } from "lit/decorators";
|
||||||
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||||
import "../../../../../components/ha-alert";
|
import "../../../../../components/ha-alert";
|
||||||
import type { HaCheckbox } from "../../../../../components/ha-checkbox";
|
import type { HaCheckbox } from "../../../../../components/ha-checkbox";
|
||||||
@ -60,7 +61,8 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
| "finished"
|
| "finished"
|
||||||
| "provisioned"
|
| "provisioned"
|
||||||
| "validate_dsk_enter_pin"
|
| "validate_dsk_enter_pin"
|
||||||
| "grant_security_classes";
|
| "grant_security_classes"
|
||||||
|
| "waiting_for_device";
|
||||||
|
|
||||||
@state() private _device?: ZWaveJSAddNodeDevice;
|
@state() private _device?: ZWaveJSAddNodeDevice;
|
||||||
|
|
||||||
@ -86,6 +88,11 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
|
|
||||||
private _qrProcessing = false;
|
private _qrProcessing = false;
|
||||||
|
|
||||||
|
public connectedCallback(): void {
|
||||||
|
super.connectedCallback();
|
||||||
|
window.addEventListener("beforeunload", this._onBeforeUnload);
|
||||||
|
}
|
||||||
|
|
||||||
public disconnectedCallback(): void {
|
public disconnectedCallback(): void {
|
||||||
super.disconnectedCallback();
|
super.disconnectedCallback();
|
||||||
this._unsubscribe();
|
this._unsubscribe();
|
||||||
@ -106,14 +113,22 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
return nothing;
|
return nothing;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Prevent accidentally closing the dialog in certain stages
|
||||||
|
const preventClose = this._shouldPreventClose();
|
||||||
|
|
||||||
|
const heading = this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.title"
|
||||||
|
);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-dialog
|
<ha-dialog
|
||||||
open
|
open
|
||||||
@closed=${this.closeDialog}
|
@closed=${this.closeDialog}
|
||||||
.heading=${createCloseHeading(
|
.heading=${preventClose
|
||||||
this.hass,
|
? heading
|
||||||
this.hass.localize("ui.panel.config.zwave_js.add_node.title")
|
: createCloseHeading(this.hass, heading)}
|
||||||
)}
|
scrimClickAction=${ifDefined(preventClose ? "" : undefined)}
|
||||||
|
escapeKeyAction=${ifDefined(preventClose ? "" : undefined)}
|
||||||
>
|
>
|
||||||
${this._status === "loading"
|
${this._status === "loading"
|
||||||
? html`<div style="display: flex; justify-content: center;">
|
? html`<div style="display: flex; justify-content: center;">
|
||||||
@ -122,81 +137,93 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
indeterminate
|
indeterminate
|
||||||
></ha-circular-progress>
|
></ha-circular-progress>
|
||||||
</div>`
|
</div>`
|
||||||
: this._status === "choose_strategy"
|
: this._status === "waiting_for_device"
|
||||||
? html`<h3>Choose strategy</h3>
|
? html`<div class="flex-container">
|
||||||
<div class="flex-column">
|
<ha-circular-progress indeterminate></ha-circular-progress>
|
||||||
<ha-formfield
|
<p>
|
||||||
.label=${html`<b>Secure if possible</b>
|
${this.hass.localize(
|
||||||
<div class="secondary">
|
"ui.panel.config.zwave_js.add_node.waiting_for_device"
|
||||||
Requires user interaction during inclusion. Fast and
|
)}
|
||||||
secure with S2 when supported. Fallback to legacy S0 or
|
</p>
|
||||||
no encryption when necessary.
|
</div>`
|
||||||
</div>`}
|
: this._status === "choose_strategy"
|
||||||
>
|
? html`<h3>Choose strategy</h3>
|
||||||
<ha-radio
|
<div class="flex-column">
|
||||||
name="strategy"
|
<ha-formfield
|
||||||
@change=${this._handleStrategyChange}
|
.label=${html`<b>Secure if possible</b>
|
||||||
.value=${InclusionStrategy.Default}
|
<div class="secondary">
|
||||||
.checked=${this._inclusionStrategy ===
|
Requires user interaction during inclusion. Fast and
|
||||||
InclusionStrategy.Default ||
|
secure with S2 when supported. Fallback to legacy S0
|
||||||
this._inclusionStrategy === undefined}
|
or no encryption when necessary.
|
||||||
|
</div>`}
|
||||||
>
|
>
|
||||||
</ha-radio>
|
<ha-radio
|
||||||
</ha-formfield>
|
name="strategy"
|
||||||
<ha-formfield
|
@change=${this._handleStrategyChange}
|
||||||
.label=${html`<b>Legacy Secure</b>
|
.value=${InclusionStrategy.Default}
|
||||||
<div class="secondary">
|
.checked=${this._inclusionStrategy ===
|
||||||
Uses the older S0 security that is secure, but slow due
|
InclusionStrategy.Default ||
|
||||||
to a lot of overhead. Allows securely including S2
|
this._inclusionStrategy === undefined}
|
||||||
capable devices which fail to be included with S2.
|
>
|
||||||
</div>`}
|
</ha-radio>
|
||||||
>
|
</ha-formfield>
|
||||||
<ha-radio
|
<ha-formfield
|
||||||
name="strategy"
|
.label=${html`<b>Legacy Secure</b>
|
||||||
@change=${this._handleStrategyChange}
|
<div class="secondary">
|
||||||
.value=${InclusionStrategy.Security_S0}
|
Uses the older S0 security that is secure, but slow
|
||||||
.checked=${this._inclusionStrategy ===
|
due to a lot of overhead. Allows securely including S2
|
||||||
InclusionStrategy.Security_S0}
|
capable devices which fail to be included with S2.
|
||||||
|
</div>`}
|
||||||
>
|
>
|
||||||
</ha-radio>
|
<ha-radio
|
||||||
</ha-formfield>
|
name="strategy"
|
||||||
<ha-formfield
|
@change=${this._handleStrategyChange}
|
||||||
.label=${html`<b>Insecure</b>
|
.value=${InclusionStrategy.Security_S0}
|
||||||
<div class="secondary">Do not use encryption.</div>`}
|
.checked=${this._inclusionStrategy ===
|
||||||
>
|
InclusionStrategy.Security_S0}
|
||||||
<ha-radio
|
>
|
||||||
name="strategy"
|
</ha-radio>
|
||||||
@change=${this._handleStrategyChange}
|
</ha-formfield>
|
||||||
.value=${InclusionStrategy.Insecure}
|
<ha-formfield
|
||||||
.checked=${this._inclusionStrategy ===
|
.label=${html`<b>Insecure</b>
|
||||||
InclusionStrategy.Insecure}
|
<div class="secondary">Do not use encryption.</div>`}
|
||||||
>
|
>
|
||||||
</ha-radio>
|
<ha-radio
|
||||||
</ha-formfield>
|
name="strategy"
|
||||||
</div>
|
@change=${this._handleStrategyChange}
|
||||||
<mwc-button
|
.value=${InclusionStrategy.Insecure}
|
||||||
slot="primaryAction"
|
.checked=${this._inclusionStrategy ===
|
||||||
@click=${this._startManualInclusion}
|
InclusionStrategy.Insecure}
|
||||||
>
|
>
|
||||||
Search device
|
</ha-radio>
|
||||||
</mwc-button>`
|
</ha-formfield>
|
||||||
: this._status === "qr_scan"
|
</div>
|
||||||
? html`${this._error
|
<mwc-button
|
||||||
? html`<ha-alert alert-type="error"
|
slot="primaryAction"
|
||||||
>${this._error}</ha-alert
|
@click=${this._startManualInclusion}
|
||||||
>`
|
>
|
||||||
: ""}
|
Search device
|
||||||
<ha-qr-scanner
|
|
||||||
.localize=${this.hass.localize}
|
|
||||||
@qr-code-scanned=${this._qrCodeScanned}
|
|
||||||
></ha-qr-scanner>
|
|
||||||
<mwc-button slot="secondaryAction" @click=${this._startOver}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.common.back"
|
|
||||||
)}
|
|
||||||
</mwc-button>`
|
</mwc-button>`
|
||||||
: this._status === "validate_dsk_enter_pin"
|
: this._status === "qr_scan"
|
||||||
? html`
|
? html`${this._error
|
||||||
|
? html`<ha-alert alert-type="error"
|
||||||
|
>${this._error}</ha-alert
|
||||||
|
>`
|
||||||
|
: ""}
|
||||||
|
<ha-qr-scanner
|
||||||
|
.localize=${this.hass.localize}
|
||||||
|
@qr-code-scanned=${this._qrCodeScanned}
|
||||||
|
></ha-qr-scanner>
|
||||||
|
<mwc-button
|
||||||
|
slot="secondaryAction"
|
||||||
|
@click=${this._startOver}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.common.back"
|
||||||
|
)}
|
||||||
|
</mwc-button>`
|
||||||
|
: this._status === "validate_dsk_enter_pin"
|
||||||
|
? html`
|
||||||
<p>
|
<p>
|
||||||
Please enter the 5-digit PIN for your device and verify that
|
Please enter the 5-digit PIN for your device and verify that
|
||||||
the rest of the device-specific key matches the one that can
|
the rest of the device-specific key matches the one that can
|
||||||
@ -225,198 +252,160 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
</mwc-button>
|
</mwc-button>
|
||||||
</div>
|
</div>
|
||||||
`
|
`
|
||||||
: this._status === "grant_security_classes"
|
: this._status === "grant_security_classes"
|
||||||
? html`
|
|
||||||
<h3>
|
|
||||||
The device has requested the following security classes:
|
|
||||||
</h3>
|
|
||||||
${this._error
|
|
||||||
? html`<ha-alert alert-type="error"
|
|
||||||
>${this._error}</ha-alert
|
|
||||||
>`
|
|
||||||
: ""}
|
|
||||||
<div class="flex-column">
|
|
||||||
${this._requestedGrant?.securityClasses
|
|
||||||
.sort((a, b) => {
|
|
||||||
// Put highest security classes at the top, S0 at the bottom
|
|
||||||
if (a === SecurityClass.S0_Legacy) return 1;
|
|
||||||
if (b === SecurityClass.S0_Legacy) return -1;
|
|
||||||
return b - a;
|
|
||||||
})
|
|
||||||
.map(
|
|
||||||
(securityClass) =>
|
|
||||||
html`<ha-formfield
|
|
||||||
.label=${html`<b
|
|
||||||
>${this.hass.localize(
|
|
||||||
`ui.panel.config.zwave_js.security_classes.${SecurityClass[securityClass]}.title`
|
|
||||||
)}</b
|
|
||||||
>
|
|
||||||
<div class="secondary">
|
|
||||||
${this.hass.localize(
|
|
||||||
`ui.panel.config.zwave_js.security_classes.${SecurityClass[securityClass]}.description`
|
|
||||||
)}
|
|
||||||
</div>`}
|
|
||||||
>
|
|
||||||
<ha-checkbox
|
|
||||||
@change=${this._handleSecurityClassChange}
|
|
||||||
.value=${securityClass}
|
|
||||||
.checked=${this._securityClasses.includes(
|
|
||||||
securityClass
|
|
||||||
)}
|
|
||||||
>
|
|
||||||
</ha-checkbox>
|
|
||||||
</ha-formfield>`
|
|
||||||
)}
|
|
||||||
</div>
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
.disabled=${!this._securityClasses.length}
|
|
||||||
@click=${this._grantSecurityClasses}
|
|
||||||
>
|
|
||||||
Submit
|
|
||||||
</mwc-button>
|
|
||||||
`
|
|
||||||
: this._status === "timed_out"
|
|
||||||
? html`
|
? html`
|
||||||
<h3>Timed out!</h3>
|
<h3>
|
||||||
<p>
|
The device has requested the following security
|
||||||
We have not found any device in inclusion mode. Make
|
classes:
|
||||||
sure the device is active and in inclusion mode.
|
</h3>
|
||||||
</p>
|
${this._error
|
||||||
<mwc-button
|
? html`<ha-alert alert-type="error"
|
||||||
slot="primaryAction"
|
>${this._error}</ha-alert
|
||||||
@click=${this._startOver}
|
>`
|
||||||
>
|
: ""}
|
||||||
Retry
|
<div class="flex-column">
|
||||||
</mwc-button>
|
${this._requestedGrant?.securityClasses
|
||||||
`
|
.sort((a, b) => {
|
||||||
: this._status === "started_specific"
|
// Put highest security classes at the top, S0 at the bottom
|
||||||
? html`<h3>
|
if (a === SecurityClass.S0_Legacy) return 1;
|
||||||
${this.hass.localize(
|
if (b === SecurityClass.S0_Legacy) return -1;
|
||||||
"ui.panel.config.zwave_js.add_node.searching_device"
|
return b - a;
|
||||||
)}
|
})
|
||||||
</h3>
|
.map(
|
||||||
<ha-circular-progress
|
(securityClass) =>
|
||||||
indeterminate
|
html`<ha-formfield
|
||||||
></ha-circular-progress>
|
.label=${html`<b
|
||||||
<p>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.follow_device_instructions"
|
|
||||||
)}
|
|
||||||
</p>`
|
|
||||||
: this._status === "started"
|
|
||||||
? html`
|
|
||||||
<div class="select-inclusion">
|
|
||||||
<div class="outline">
|
|
||||||
<h2>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.searching_device"
|
|
||||||
)}
|
|
||||||
</h2>
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
></ha-circular-progress>
|
|
||||||
<p>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.follow_device_instructions"
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<button
|
|
||||||
class="link"
|
|
||||||
@click=${this._chooseInclusionStrategy}
|
|
||||||
>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.choose_inclusion_strategy"
|
|
||||||
)}
|
|
||||||
</button>
|
|
||||||
</p>
|
|
||||||
</div>
|
|
||||||
${this._supportsSmartStart
|
|
||||||
? html` <div class="outline">
|
|
||||||
<h2>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.qr_code"
|
|
||||||
)}
|
|
||||||
</h2>
|
|
||||||
<ha-svg-icon
|
|
||||||
.path=${mdiQrcodeScan}
|
|
||||||
></ha-svg-icon>
|
|
||||||
<p>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.qr_code_paragraph"
|
|
||||||
)}
|
|
||||||
</p>
|
|
||||||
<p>
|
|
||||||
<mwc-button @click=${this._scanQRCode}>
|
|
||||||
${this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.scan_qr_code"
|
|
||||||
)}
|
|
||||||
</mwc-button>
|
|
||||||
</p>
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
|
||||||
<mwc-button
|
|
||||||
slot="primaryAction"
|
|
||||||
@click=${this.closeDialog}
|
|
||||||
>
|
|
||||||
${this.hass.localize("ui.common.cancel")}
|
|
||||||
</mwc-button>
|
|
||||||
`
|
|
||||||
: this._status === "interviewing"
|
|
||||||
? html`
|
|
||||||
<div class="flex-container">
|
|
||||||
<ha-circular-progress
|
|
||||||
indeterminate
|
|
||||||
></ha-circular-progress>
|
|
||||||
<div class="status">
|
|
||||||
<p>
|
|
||||||
<b
|
|
||||||
>${this.hass.localize(
|
>${this.hass.localize(
|
||||||
"ui.panel.config.zwave_js.add_node.interview_started"
|
`ui.panel.config.zwave_js.security_classes.${SecurityClass[securityClass]}.title`
|
||||||
)}</b
|
)}</b
|
||||||
>
|
>
|
||||||
|
<div class="secondary">
|
||||||
|
${this.hass.localize(
|
||||||
|
`ui.panel.config.zwave_js.security_classes.${SecurityClass[securityClass]}.description`
|
||||||
|
)}
|
||||||
|
</div>`}
|
||||||
|
>
|
||||||
|
<ha-checkbox
|
||||||
|
@change=${this._handleSecurityClassChange}
|
||||||
|
.value=${securityClass}
|
||||||
|
.checked=${this._securityClasses.includes(
|
||||||
|
securityClass
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
</ha-checkbox>
|
||||||
|
</ha-formfield>`
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
.disabled=${!this._securityClasses.length}
|
||||||
|
@click=${this._grantSecurityClasses}
|
||||||
|
>
|
||||||
|
Submit
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "timed_out"
|
||||||
|
? html`
|
||||||
|
<h3>Timed out!</h3>
|
||||||
|
<p>
|
||||||
|
We have not found any device in inclusion mode. Make
|
||||||
|
sure the device is active and in inclusion mode.
|
||||||
|
</p>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
@click=${this._startOver}
|
||||||
|
>
|
||||||
|
Retry
|
||||||
|
</mwc-button>
|
||||||
|
`
|
||||||
|
: this._status === "started_specific"
|
||||||
|
? html`<h3>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.searching_device"
|
||||||
|
)}
|
||||||
|
</h3>
|
||||||
|
<ha-circular-progress
|
||||||
|
indeterminate
|
||||||
|
></ha-circular-progress>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.follow_device_instructions"
|
||||||
|
)}
|
||||||
|
</p>`
|
||||||
|
: this._status === "started"
|
||||||
|
? html`
|
||||||
|
<div class="select-inclusion">
|
||||||
|
<div class="outline">
|
||||||
|
<h2>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.searching_device"
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
<ha-circular-progress
|
||||||
|
indeterminate
|
||||||
|
></ha-circular-progress>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.follow_device_instructions"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<button
|
||||||
|
class="link"
|
||||||
|
@click=${this._chooseInclusionStrategy}
|
||||||
|
>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.choose_inclusion_strategy"
|
||||||
|
)}
|
||||||
|
</button>
|
||||||
</p>
|
</p>
|
||||||
${this._stages
|
|
||||||
? html` <div class="stages">
|
|
||||||
${this._stages.map(
|
|
||||||
(stage) => html`
|
|
||||||
<span class="stage">
|
|
||||||
<ha-svg-icon
|
|
||||||
.path=${mdiCheckCircle}
|
|
||||||
class="success"
|
|
||||||
></ha-svg-icon>
|
|
||||||
${stage}
|
|
||||||
</span>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
</div>`
|
|
||||||
: ""}
|
|
||||||
</div>
|
</div>
|
||||||
|
${this._supportsSmartStart
|
||||||
|
? html` <div class="outline">
|
||||||
|
<h2>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.qr_code"
|
||||||
|
)}
|
||||||
|
</h2>
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiQrcodeScan}
|
||||||
|
></ha-svg-icon>
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.qr_code_paragraph"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<mwc-button @click=${this._scanQRCode}>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.scan_qr_code"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
</p>
|
||||||
|
</div>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
<mwc-button
|
<mwc-button
|
||||||
slot="primaryAction"
|
slot="primaryAction"
|
||||||
@click=${this.closeDialog}
|
@click=${this.closeDialog}
|
||||||
>
|
>
|
||||||
${this.hass.localize("ui.common.close")}
|
${this.hass.localize("ui.common.cancel")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
`
|
`
|
||||||
: this._status === "failed"
|
: this._status === "interviewing"
|
||||||
? html`
|
? html`
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
|
<ha-circular-progress
|
||||||
|
indeterminate
|
||||||
|
></ha-circular-progress>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<ha-alert
|
<p>
|
||||||
alert-type="error"
|
<b
|
||||||
.title=${this.hass.localize(
|
>${this.hass.localize(
|
||||||
"ui.panel.config.zwave_js.add_node.inclusion_failed"
|
"ui.panel.config.zwave_js.add_node.interview_started"
|
||||||
)}
|
)}</b
|
||||||
>
|
>
|
||||||
${this._error ||
|
</p>
|
||||||
this.hass.localize(
|
|
||||||
"ui.panel.config.zwave_js.add_node.check_logs"
|
|
||||||
)}
|
|
||||||
</ha-alert>
|
|
||||||
${this._stages
|
${this._stages
|
||||||
? html` <div class="stages">
|
? html` <div class="stages">
|
||||||
${this._stages.map(
|
${this._stages.map(
|
||||||
@ -441,45 +430,21 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
${this.hass.localize("ui.common.close")}
|
${this.hass.localize("ui.common.close")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
`
|
`
|
||||||
: this._status === "finished"
|
: this._status === "failed"
|
||||||
? html`
|
? html`
|
||||||
<div class="flex-container">
|
<div class="flex-container">
|
||||||
<ha-svg-icon
|
|
||||||
.path=${this._lowSecurity
|
|
||||||
? mdiAlertCircle
|
|
||||||
: mdiCheckCircle}
|
|
||||||
class=${this._lowSecurity
|
|
||||||
? "warning"
|
|
||||||
: "success"}
|
|
||||||
></ha-svg-icon>
|
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<p>
|
<ha-alert
|
||||||
${this.hass.localize(
|
alert-type="error"
|
||||||
"ui.panel.config.zwave_js.add_node.inclusion_finished"
|
.title=${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.inclusion_failed"
|
||||||
)}
|
)}
|
||||||
</p>
|
|
||||||
${this._lowSecurity
|
|
||||||
? html`<ha-alert
|
|
||||||
alert-type="warning"
|
|
||||||
title="The device was added insecurely"
|
|
||||||
>
|
|
||||||
There was an error during secure
|
|
||||||
inclusion. You can try again by
|
|
||||||
excluding the device and adding it
|
|
||||||
again.
|
|
||||||
</ha-alert>`
|
|
||||||
: ""}
|
|
||||||
<a
|
|
||||||
href=${`/config/devices/device/${
|
|
||||||
this._device!.id
|
|
||||||
}`}
|
|
||||||
>
|
>
|
||||||
<mwc-button>
|
${this._error ||
|
||||||
${this.hass.localize(
|
this.hass.localize(
|
||||||
"ui.panel.config.zwave_js.add_node.view_device"
|
"ui.panel.config.zwave_js.add_node.check_logs"
|
||||||
)}
|
)}
|
||||||
</mwc-button>
|
</ha-alert>
|
||||||
</a>
|
|
||||||
${this._stages
|
${this._stages
|
||||||
? html` <div class="stages">
|
? html` <div class="stages">
|
||||||
${this._stages.map(
|
${this._stages.map(
|
||||||
@ -504,18 +469,60 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
${this.hass.localize("ui.common.close")}
|
${this.hass.localize("ui.common.close")}
|
||||||
</mwc-button>
|
</mwc-button>
|
||||||
`
|
`
|
||||||
: this._status === "provisioned"
|
: this._status === "finished"
|
||||||
? html` <div class="flex-container">
|
? html`
|
||||||
|
<div class="flex-container">
|
||||||
<ha-svg-icon
|
<ha-svg-icon
|
||||||
.path=${mdiCheckCircle}
|
.path=${this._lowSecurity
|
||||||
class="success"
|
? mdiAlertCircle
|
||||||
|
: mdiCheckCircle}
|
||||||
|
class=${this._lowSecurity
|
||||||
|
? "warning"
|
||||||
|
: "success"}
|
||||||
></ha-svg-icon>
|
></ha-svg-icon>
|
||||||
<div class="status">
|
<div class="status">
|
||||||
<p>
|
<p>
|
||||||
${this.hass.localize(
|
${this.hass.localize(
|
||||||
"ui.panel.config.zwave_js.add_node.provisioning_finished"
|
"ui.panel.config.zwave_js.add_node.inclusion_finished"
|
||||||
)}
|
)}
|
||||||
</p>
|
</p>
|
||||||
|
${this._lowSecurity
|
||||||
|
? html`<ha-alert
|
||||||
|
alert-type="warning"
|
||||||
|
title="The device was added insecurely"
|
||||||
|
>
|
||||||
|
There was an error during secure
|
||||||
|
inclusion. You can try again by
|
||||||
|
excluding the device and adding it
|
||||||
|
again.
|
||||||
|
</ha-alert>`
|
||||||
|
: ""}
|
||||||
|
<a
|
||||||
|
href=${`/config/devices/device/${
|
||||||
|
this._device?.id
|
||||||
|
}`}
|
||||||
|
>
|
||||||
|
<mwc-button>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.view_device"
|
||||||
|
)}
|
||||||
|
</mwc-button>
|
||||||
|
</a>
|
||||||
|
${this._stages
|
||||||
|
? html` <div class="stages">
|
||||||
|
${this._stages.map(
|
||||||
|
(stage) => html`
|
||||||
|
<span class="stage">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCheckCircle}
|
||||||
|
class="success"
|
||||||
|
></ha-svg-icon>
|
||||||
|
${stage}
|
||||||
|
</span>
|
||||||
|
`
|
||||||
|
)}
|
||||||
|
</div>`
|
||||||
|
: ""}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<mwc-button
|
<mwc-button
|
||||||
@ -523,12 +530,42 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
@click=${this.closeDialog}
|
@click=${this.closeDialog}
|
||||||
>
|
>
|
||||||
${this.hass.localize("ui.common.close")}
|
${this.hass.localize("ui.common.close")}
|
||||||
</mwc-button>`
|
</mwc-button>
|
||||||
: ""}
|
`
|
||||||
|
: this._status === "provisioned"
|
||||||
|
? html` <div class="flex-container">
|
||||||
|
<ha-svg-icon
|
||||||
|
.path=${mdiCheckCircle}
|
||||||
|
class="success"
|
||||||
|
></ha-svg-icon>
|
||||||
|
<div class="status">
|
||||||
|
<p>
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.zwave_js.add_node.provisioning_finished"
|
||||||
|
)}
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<mwc-button
|
||||||
|
slot="primaryAction"
|
||||||
|
@click=${this.closeDialog}
|
||||||
|
>
|
||||||
|
${this.hass.localize("ui.common.close")}
|
||||||
|
</mwc-button>`
|
||||||
|
: ""}
|
||||||
</ha-dialog>
|
</ha-dialog>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _shouldPreventClose(): boolean {
|
||||||
|
return (
|
||||||
|
this._status === "started_specific" ||
|
||||||
|
this._status === "validate_dsk_enter_pin" ||
|
||||||
|
this._status === "grant_security_classes" ||
|
||||||
|
this._status === "waiting_for_device"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
private _chooseInclusionStrategy(): void {
|
private _chooseInclusionStrategy(): void {
|
||||||
this._unsubscribe();
|
this._unsubscribe();
|
||||||
this._status = "choose_strategy";
|
this._status = "choose_strategy";
|
||||||
@ -639,7 +676,7 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _validateDskAndEnterPin(): Promise<void> {
|
private async _validateDskAndEnterPin(): Promise<void> {
|
||||||
this._status = "loading";
|
this._status = "waiting_for_device";
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
try {
|
try {
|
||||||
await zwaveValidateDskAndEnterPin(
|
await zwaveValidateDskAndEnterPin(
|
||||||
@ -656,7 +693,7 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private async _grantSecurityClasses(): Promise<void> {
|
private async _grantSecurityClasses(): Promise<void> {
|
||||||
this._status = "loading";
|
this._status = "waiting_for_device";
|
||||||
this._error = undefined;
|
this._error = undefined;
|
||||||
try {
|
try {
|
||||||
await zwaveGrantSecurityClasses(
|
await zwaveGrantSecurityClasses(
|
||||||
@ -719,6 +756,12 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
this._addNodeTimeoutHandle = undefined;
|
this._addNodeTimeoutHandle = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (message.event === "node found") {
|
||||||
|
// The user may have to enter a PIN. Until then prevent accidentally
|
||||||
|
// closing the dialog
|
||||||
|
this._status = "waiting_for_device";
|
||||||
|
}
|
||||||
|
|
||||||
if (message.event === "validate dsk and enter pin") {
|
if (message.event === "validate dsk and enter pin") {
|
||||||
this._status = "validate_dsk_enter_pin";
|
this._status = "validate_dsk_enter_pin";
|
||||||
this._dsk = message.dsk;
|
this._dsk = message.dsk;
|
||||||
@ -775,6 +818,13 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
}, 90000);
|
}, 90000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _onBeforeUnload = (event: BeforeUnloadEvent) => {
|
||||||
|
if (this._shouldPreventClose()) {
|
||||||
|
event.preventDefault();
|
||||||
|
}
|
||||||
|
event.returnValue = true;
|
||||||
|
};
|
||||||
|
|
||||||
private _unsubscribe(): void {
|
private _unsubscribe(): void {
|
||||||
if (this._subscribed) {
|
if (this._subscribed) {
|
||||||
this._subscribed.then((unsub) => unsub());
|
this._subscribed.then((unsub) => unsub());
|
||||||
@ -791,6 +841,7 @@ class DialogZWaveJSAddNode extends LitElement {
|
|||||||
clearTimeout(this._addNodeTimeoutHandle);
|
clearTimeout(this._addNodeTimeoutHandle);
|
||||||
}
|
}
|
||||||
this._addNodeTimeoutHandle = undefined;
|
this._addNodeTimeoutHandle = undefined;
|
||||||
|
window.removeEventListener("beforeunload", this._onBeforeUnload);
|
||||||
}
|
}
|
||||||
|
|
||||||
public closeDialog(): void {
|
public closeDialog(): void {
|
||||||
|
@ -4863,7 +4863,8 @@
|
|||||||
"provisioning_finished": "The device has been added. Once you power it on, it will become available.",
|
"provisioning_finished": "The device has been added. Once you power it on, it will become available.",
|
||||||
"view_device": "View Device",
|
"view_device": "View Device",
|
||||||
"interview_started": "The device is being interviewed. This may take some time.",
|
"interview_started": "The device is being interviewed. This may take some time.",
|
||||||
"interview_failed": "The device interview failed. Additional information may be available in the logs."
|
"interview_failed": "The device interview failed. Additional information may be available in the logs.",
|
||||||
|
"waiting_for_device": "Communicating with the device. Please wait."
|
||||||
},
|
},
|
||||||
"provisioned": {
|
"provisioned": {
|
||||||
"dsk": "DSK",
|
"dsk": "DSK",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user