diff --git a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-remove-node.ts b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-remove-node.ts index 581b59ba0e..528e35740d 100644 --- a/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-remove-node.ts +++ b/src/panels/config/integrations/integration-panels/zwave_js/dialog-zwave_js-remove-node.ts @@ -1,17 +1,25 @@ -import "@material/mwc-button/mwc-button"; -import { mdiCheckCircle, mdiCloseCircle } from "@mdi/js"; -import type { CSSResultGroup } from "lit"; +import { + mdiCheckCircle, + mdiClose, + mdiCloseCircle, + mdiVectorSquareRemove, +} from "@mdi/js"; +import type { UnsubscribeFunc } from "home-assistant-js-websocket"; +import type { CSSResultGroup, TemplateResult } from "lit"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; -import type { UnsubscribeFunc } from "home-assistant-js-websocket"; import { fireEvent } from "../../../../../common/dom/fire_event"; -import "../../../../../components/ha-spinner"; import "../../../../../components/ha-alert"; -import { createCloseHeading } from "../../../../../components/ha-dialog"; +import "../../../../../components/ha-button"; +import "../../../../../components/ha-dialog"; +import "../../../../../components/ha-dialog-header"; +import "../../../../../components/ha-spinner"; import { haStyleDialog } from "../../../../../resources/styles"; import type { HomeAssistant } from "../../../../../types"; import type { ZWaveJSRemoveNodeDialogParams } from "./show-dialog-zwave_js-remove-node"; +const EXCLUSION_TIMEOUT_SECONDS = 120; + export interface ZWaveJSRemovedNode { node_id: number; manufacturer: string; @@ -24,7 +32,13 @@ class DialogZWaveJSRemoveNode extends LitElement { @state() private entry_id?: string; - @state() private _status = ""; + @state() private _step: + | "start" + | "exclusion" + | "remove" + | "finished" + | "failed" + | "timeout" = "start"; @state() private _node?: ZWaveJSRemovedNode; @@ -56,142 +70,126 @@ class DialogZWaveJSRemoveNode extends LitElement { return nothing; } + const dialogTitle = this.hass.localize( + "ui.panel.config.zwave_js.remove_node.title" + ); + return html` - - ${this._status === "" - ? html` -

- ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.introduction" - )} -

- - ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.start_exclusion" - )} - - ` - : nothing} - ${this._status === "started" - ? html` -
- -
-

- ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.controller_in_exclusion_mode" - )} -

-

- ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.follow_device_instructions" - )} -

-
-
- - ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.cancel_exclusion" - )} - - ` - : nothing} - ${this._status === "failed" - ? html` -
- -
-

- ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.exclusion_failed" - )} -

- ${this._error - ? html` - ${this._error} - ` - : nothing} -
-
- - ${this.hass.localize("ui.common.close")} - - ` - : nothing} - ${this._status === "finished" - ? html` -
- -
-

- ${this.hass.localize( - "ui.panel.config.zwave_js.remove_node.exclusion_finished", - { id: this._node!.node_id } - )} -

-
-
- - ${this.hass.localize("ui.common.close")} - - ` - : nothing} + + + + ${dialogTitle} + +
${this._renderStepContent()}
+ ${this._renderAction()}
`; } - private _startExclusion(): void { - if (!this.hass) { - return; + private _renderStepContent(): TemplateResult { + if (this._step === "start") { + return html` + +

+ ${this.hass.localize( + "ui.panel.config.zwave_js.remove_node.introduction" + )} +

+ `; } + + if (["exclusion", "remove"].includes(this._step)) { + return html` + +
+

+ ${this.hass.localize( + `ui.panel.config.zwave_js.remove_node.${this._step === "exclusion" ? "follow_device_instructions" : "removing_device"}` + )} +

+
+ `; + } + + if (this._step === "finished") { + return html` +

+ ${this.hass.localize( + "ui.panel.config.zwave_js.remove_node.exclusion_finished", + { id: html`${this._node!.node_id}` } + )} +

`; + } + + // failed + return html` + +

+ ${this.hass.localize( + "ui.panel.config.zwave_js.remove_node.exclusion_failed" + )} +

+ ${this._error + ? html`${this._error}` + : nothing} + `; + } + + private _renderAction(): TemplateResult { + return html` + + ${this.hass.localize( + this._step === "start" + ? "ui.panel.config.zwave_js.remove_node.start_exclusion" + : this._step === "exclusion" + ? "ui.panel.config.zwave_js.remove_node.cancel_exclusion" + : "ui.common.close" + )} + + `; + } + + private _startExclusion(): void { this._subscribed = this.hass.connection .subscribeMessage((message) => this._handleMessage(message), { type: "zwave_js/remove_node", entry_id: this.entry_id, }) .catch((err) => { - this._status = "failed"; + this._step = "failed"; this._error = err.message; return undefined; }); - this._status = "started"; - this._removeNodeTimeoutHandle = window.setTimeout( - () => this._unsubscribe(), - 120000 - ); + this._step = "exclusion"; + this._removeNodeTimeoutHandle = window.setTimeout(() => { + this._unsubscribe(); + this._step = "timeout"; + }, EXCLUSION_TIMEOUT_SECONDS * 1000); } private _handleMessage(message: any): void { - if (message.event === "exclusion started") { - this._status = "started"; - } if (message.event === "exclusion failed") { this._unsubscribe(); - this._status = "failed"; + this._step = "failed"; } if (message.event === "exclusion stopped") { - if (this._status !== "finished") { - this._status = ""; - } - this._unsubscribe(); + this._step = "remove"; } if (message.event === "node removed") { - this._status = "finished"; + this._step = "finished"; this._node = message.node; this._unsubscribe(); if (this._removedCallback) { @@ -200,29 +198,35 @@ class DialogZWaveJSRemoveNode extends LitElement { } } - private _unsubscribe(): void { - if (this._subscribed) { - this._subscribed.then((unsub) => unsub && unsub()); - this._subscribed = undefined; - } - if (this._status === "started") { + private _stopExclusion(): void { + try { this.hass.callWS({ type: "zwave_js/stop_exclusion", entry_id: this.entry_id, }); + } catch (err) { + // eslint-disable-next-line no-console + console.error(err); } - if (this._status !== "finished") { - this._status = ""; + } + + private _unsubscribe = () => { + if (this._subscribed) { + this._subscribed.then((unsub) => unsub && unsub()); + this._subscribed = undefined; + } + if (this._step === "exclusion") { + this._stopExclusion(); } if (this._removeNodeTimeoutHandle) { clearTimeout(this._removeNodeTimeoutHandle); } - } + }; public closeDialog(): void { this._unsubscribe(); this.entry_id = undefined; - this._status = ""; + this._step = "start"; fireEvent(this, "dialog-closed", { dialog: this.localName }); } @@ -231,29 +235,36 @@ class DialogZWaveJSRemoveNode extends LitElement { return [ haStyleDialog, css` - .success { - color: var(--success-color); - } - - .failed { - color: var(--error-color); - } - - .flex-container { + .content { display: flex; align-items: center; + flex-direction: column; + gap: 16px; + text-align: center; + } + + .content ha-spinner { + padding: 32px 0; + } + + .content p { + color: var(--secondary-text-color); } ha-svg-icon { - width: 68px; + padding: 32px 0; + width: 48px; height: 48px; } + ha-svg-icon.success { + color: var(--success-color); + } - .flex-container ha-spinner, - .flex-container ha-svg-icon { - margin-right: 20px; - margin-inline-end: 20px; - margin-inline-start: initial; + ha-svg-icon.failed { + color: var(--error-color); + } + ha-alert { + width: 100%; } `, ]; diff --git a/src/translations/en.json b/src/translations/en.json index b4c960539d..80f1a0642b 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -5941,9 +5941,9 @@ "introduction": "Remove a device from your Z-Wave network, and remove the associated device and entities from Home Assistant.", "start_exclusion": "Start exclusion", "cancel_exclusion": "Cancel exclusion", - "controller_in_exclusion_mode": "Your Z-Wave controller is now in exclusion mode.", "follow_device_instructions": "Follow the directions that came with your device to trigger exclusion on the device.", - "exclusion_failed": "The device could not be removed. Please check the logs for more information.", + "removing_device": "Removing device", + "exclusion_failed": "An error occurred during exclusion. Please check the logs for more information.", "exclusion_finished": "Device {id} has been removed from your Z-Wave network." }, "remove_failed_node": {