From e84b6960abd03bd21b4bc598e8b17dcde44a23e7 Mon Sep 17 00:00:00 2001 From: Zack Date: Tue, 24 May 2022 09:39:40 -0500 Subject: [PATCH 1/7] Move Logbook and make device page better --- .../config/areas/ha-config-area-page.ts | 8 +- .../mqtt/ha-device-actions-mqtt.ts | 28 +-- .../zha/ha-device-actions-zha.ts | 94 +++++---- .../zha/ha-device-info-zha.ts | 66 +++--- .../zwave_js/ha-device-actions-zwave_js.ts | 35 ++-- .../zwave_js/ha-device-info-zwave_js.ts | 142 ++++++------- .../config/devices/ha-config-device-page.ts | 195 +++++++++++------- 7 files changed, 308 insertions(+), 260 deletions(-) diff --git a/src/panels/config/areas/ha-config-area-page.ts b/src/panels/config/areas/ha-config-area-page.ts index 801b1902f7ca..ed4573578c57 100644 --- a/src/panels/config/areas/ha-config-area-page.ts +++ b/src/panels/config/areas/ha-config-area-page.ts @@ -19,7 +19,6 @@ import { afterNextRender } from "../../../common/util/render-status"; import "../../../components/ha-card"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; -import "../../logbook/ha-logbook"; import { AreaRegistryEntry, deleteAreaRegistryEntry, @@ -43,15 +42,16 @@ import { SceneEntity } from "../../../data/scene"; import { ScriptEntity } from "../../../data/script"; import { findRelated, RelatedResult } from "../../../data/search"; import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; +import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { haStyle } from "../../../resources/styles"; import { HomeAssistant, Route } from "../../../types"; +import "../../logbook/ha-logbook"; import { showEntityEditorDialog } from "../entities/show-dialog-entity-editor"; import { configSections } from "../ha-panel-config"; import { loadAreaRegistryDetailDialog, showAreaRegistryDetailDialog, } from "./show-dialog-area-registry-detail"; -import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; declare type NameAndEntity = { name: string; @@ -761,10 +761,10 @@ class HaConfigAreaPage extends SubscribeMixin(LitElement) { border-radius: 50%; } ha-logbook { - height: 800px; + height: 400px; } :host([narrow]) ha-logbook { - height: 400px; + height: 235px; overflow: auto; } `, diff --git a/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts b/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts index f7e7847722c1..0980c2ea9b7c 100644 --- a/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts +++ b/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts @@ -1,7 +1,8 @@ -import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; +import "@material/mwc-list/mwc-list-item"; +import { html, LitElement, TemplateResult } from "lit"; import { customElement, property } from "lit/decorators"; +import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; -import { haStyle } from "../../../../../../resources/styles"; import { HomeAssistant } from "../../../../../../types"; import { showMQTTDeviceDebugInfoDialog } from "./show-dialog-mqtt-device-debug-info"; @@ -13,24 +14,23 @@ export class HaDeviceActionsMqtt extends LitElement { protected render(): TemplateResult { return html` - MQTT Info + + MQTT Info + `; } - private async _showDebugInfo(): Promise { + private async _showDebugInfo(ev): Promise { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } const device = this.device; await showMQTTDeviceDebugInfoDialog(this, { device }); } +} - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - :host { - display: flex; - justify-content: space-between; - } - `, - ]; +declare global { + interface HTMLElementTagNameMap { + "ha-device-actions-mqtt": HaDeviceActionsMqtt; } } diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts index 2a0337c0438a..4f4df82b8c6f 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts @@ -1,17 +1,11 @@ -import { - css, - CSSResultGroup, - html, - LitElement, - PropertyValues, - TemplateResult, -} from "lit"; +import "@material/mwc-list/mwc-list-item"; +import { html, LitElement, PropertyValues, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; import { navigate } from "../../../../../../common/navigate"; import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import { fetchZHADevice, ZHADevice } from "../../../../../../data/zha"; import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box"; -import { haStyle } from "../../../../../../resources/styles"; import { HomeAssistant } from "../../../../../../types"; import { showZHAClusterDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-cluster"; import { showZHADeviceChildrenDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-children"; @@ -47,82 +41,107 @@ export class HaDeviceActionsZha extends LitElement { return html` ${this._zhaDevice.device_type !== "Coordinator" ? html` - + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.reconfigure" )} - + ` : ""} ${this._zhaDevice.power_source === "Mains" && (this._zhaDevice.device_type === "Router" || this._zhaDevice.device_type === "Coordinator") ? html` - + ${this.hass!.localize("ui.dialogs.zha_device_info.buttons.add")} - - + + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.device_children" )} - + ` : ""} ${this._zhaDevice.device_type !== "Coordinator" ? html` - + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.zigbee_information" )} - - + + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.clusters" )} - - + + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.view_in_visualization" )} - - + + ${this.hass!.localize( "ui.dialogs.zha_device_info.buttons.remove" )} - + ` : ""} `; } - private async _showClustersDialog(): Promise { + private async _showClustersDialog(ev): Promise { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } await showZHAClusterDialog(this, { device: this._zhaDevice! }); } - private async _onReconfigureNodeClick(): Promise { - if (!this.hass) { + private async _onReconfigureNodeClick(ev): Promise { + if (!this.hass || !shouldHandleRequestSelectedEvent(ev)) { return; } showZHAReconfigureDeviceDialog(this, { device: this._zhaDevice! }); } - private _onAddDevicesClick() { + private _onAddDevicesClick(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } navigate(`/config/zha/add/${this._zhaDevice!.ieee}`); } - private _onViewInVisualizationClick() { + private _onViewInVisualizationClick(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } navigate(`/config/zha/visualization/${this._zhaDevice!.device_reg_id}`); } - private async _handleZigbeeInfoClicked() { + private async _handleZigbeeInfoClicked(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } showZHADeviceZigbeeInfoDialog(this, { device: this._zhaDevice! }); } - private async _handleDeviceChildrenClicked() { + private async _handleDeviceChildrenClicked(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } showZHADeviceChildrenDialog(this, { device: this._zhaDevice! }); } - private async _removeDevice() { + private async _removeDevice(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } const confirmed = await showConfirmationDialog(this, { text: this.hass.localize( "ui.dialogs.zha_device_info.confirmations.remove" @@ -139,17 +158,4 @@ export class HaDeviceActionsZha extends LitElement { history.back(); } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - :host { - display: flex; - flex-direction: column; - align-items: flex-start; - } - `, - ]; - } } diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts index 28a3e3e0e6dc..70e80a1dd5e2 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts @@ -7,6 +7,7 @@ import { TemplateResult, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import "../../../../../../components/ha-expansion-panel"; import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import { fetchZHADevice, ZHADevice } from "../../../../../../data/zha"; import { haStyle } from "../../../../../../resources/styles"; @@ -40,38 +41,39 @@ export class HaDeviceActionsZha extends LitElement { return html``; } return html` -

Zigbee info

-
IEEE: ${this._zhaDevice.ieee}
-
Nwk: ${formatAsPaddedHex(this._zhaDevice.nwk)}
-
Device Type: ${this._zhaDevice.device_type}
-
- LQI: - ${this._zhaDevice.lqi || - this.hass!.localize("ui.dialogs.zha_device_info.unknown")} -
-
- RSSI: - ${this._zhaDevice.rssi || - this.hass!.localize("ui.dialogs.zha_device_info.unknown")} -
-
- ${this.hass!.localize("ui.dialogs.zha_device_info.last_seen")}: - ${this._zhaDevice.last_seen || - this.hass!.localize("ui.dialogs.zha_device_info.unknown")} -
-
- ${this.hass!.localize("ui.dialogs.zha_device_info.power_source")}: - ${this._zhaDevice.power_source || - this.hass!.localize("ui.dialogs.zha_device_info.unknown")} -
- ${this._zhaDevice.quirk_applied - ? html` -
- ${this.hass!.localize("ui.dialogs.zha_device_info.quirk")}: - ${this._zhaDevice.quirk_class} -
- ` - : ""} + +
IEEE: ${this._zhaDevice.ieee}
+
Nwk: ${formatAsPaddedHex(this._zhaDevice.nwk)}
+
Device Type: ${this._zhaDevice.device_type}
+
+ LQI: + ${this._zhaDevice.lqi || + this.hass!.localize("ui.dialogs.zha_device_info.unknown")} +
+
+ RSSI: + ${this._zhaDevice.rssi || + this.hass!.localize("ui.dialogs.zha_device_info.unknown")} +
+
+ ${this.hass!.localize("ui.dialogs.zha_device_info.last_seen")}: + ${this._zhaDevice.last_seen || + this.hass!.localize("ui.dialogs.zha_device_info.unknown")} +
+
+ ${this.hass!.localize("ui.dialogs.zha_device_info.power_source")}: + ${this._zhaDevice.power_source || + this.hass!.localize("ui.dialogs.zha_device_info.unknown")} +
+ ${this._zhaDevice.quirk_applied + ? html` +
+ ${this.hass!.localize("ui.dialogs.zha_device_info.quirk")}: + ${this._zhaDevice.quirk_class} +
+ ` + : ""} +
`; } diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts index b0a707f5b746..af6ad3c04faf 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts @@ -1,4 +1,4 @@ -import "@material/mwc-button/mwc-button"; +import "@material/mwc-list/mwc-list-item"; import { css, CSSResultGroup, @@ -8,6 +8,8 @@ import { TemplateResult, } from "lit"; import { customElement, property, state } from "lit/decorators"; +import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; +import { getConfigEntries } from "../../../../../../data/config_entries"; import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import { fetchZwaveNodeStatus, @@ -15,10 +17,9 @@ import { } from "../../../../../../data/zwave_js"; import { haStyle } from "../../../../../../resources/styles"; import { HomeAssistant } from "../../../../../../types"; -import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node"; import { showZWaveJSHealNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-heal-node"; +import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node"; import { showZWaveJSRemoveFailedNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-remove-failed-node"; -import { getConfigEntries } from "../../../../../../data/config_entries"; @customElement("ha-device-actions-zwave_js") export class HaDeviceActionsZWaveJS extends LitElement { @@ -71,34 +72,34 @@ export class HaDeviceActionsZWaveJS extends LitElement { - + ${this.hass.localize( "ui.panel.config.zwave_js.device_info.device_config" )} - + - + ${this.hass.localize( "ui.panel.config.zwave_js.device_info.reinterview_device" )} - - + + ${this.hass.localize( "ui.panel.config.zwave_js.device_info.heal_node" )} - - + + ${this.hass.localize( "ui.panel.config.zwave_js.device_info.remove_failed" )} - + ` : ""} `; } - private async _reinterviewClicked() { - if (!this.device) { + private async _reinterviewClicked(ev) { + if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { return; } showZWaveJSReinterviewNodeDialog(this, { @@ -106,8 +107,8 @@ export class HaDeviceActionsZWaveJS extends LitElement { }); } - private async _healNodeClicked() { - if (!this.device) { + private async _healNodeClicked(ev) { + if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { return; } showZWaveJSHealNodeDialog(this, { @@ -116,8 +117,8 @@ export class HaDeviceActionsZWaveJS extends LitElement { }); } - private async _removeFailedNode() { - if (!this.device) { + private async _removeFailedNode(ev) { + if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { return; } showZWaveJSRemoveFailedNodeDialog(this, { diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts index 02147196f148..c874be26e200 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts @@ -7,16 +7,17 @@ import { TemplateResult, } from "lit"; import { customElement, property, state } from "lit/decorators"; -import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; +import "../../../../../../components/ha-expansion-panel"; import { ConfigEntry, getConfigEntries, } from "../../../../../../data/config_entries"; +import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; import { fetchZwaveNodeStatus, nodeStatus, - ZWaveJSNodeStatus, SecurityClass, + ZWaveJSNodeStatus, } from "../../../../../../data/zwave_js"; import { haStyle } from "../../../../../../resources/styles"; import { HomeAssistant } from "../../../../../../types"; @@ -69,73 +70,76 @@ export class HaDeviceInfoZWaveJS extends LitElement { return html``; } return html` -

- ${this.hass.localize("ui.panel.config.zwave_js.device_info.zwave_info")} -

- ${this._multipleConfigEntries - ? html` -
- ${this.hass.localize("ui.panel.config.zwave_js.common.source")}: - ${this._configEntry!.title} -
- ` - : ""} -
- ${this.hass.localize("ui.panel.config.zwave_js.common.node_id")}: - ${this._node.node_id} -
- ${!this._node.is_controller_node - ? html` -
- ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.node_status" - )}: - ${this.hass.localize( - `ui.panel.config.zwave_js.node_status.${ - nodeStatus[this._node.status] - }` - )} -
-
- ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.node_ready" - )}: - ${this._node.ready - ? this.hass.localize("ui.common.yes") - : this.hass.localize("ui.common.no")} -
-
- ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.highest_security" - )}: - ${this._node.highest_security_class !== null - ? this.hass.localize( - `ui.panel.config.zwave_js.security_classes.${ - SecurityClass[this._node.highest_security_class] - }.title` - ) - : this._node.is_secure === false - ? this.hass.localize( - "ui.panel.config.zwave_js.security_classes.none.title" - ) - : this.hass.localize( - "ui.panel.config.zwave_js.device_info.unknown" - )} -
-
- ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.zwave_plus" - )}: - ${this._node.zwave_plus_version - ? this.hass.localize( - "ui.panel.config.zwave_js.device_info.zwave_plus_version", - "version", - this._node.zwave_plus_version - ) - : this.hass.localize("ui.common.no")} -
- ` - : ""} + + ${this._multipleConfigEntries + ? html` +
+ ${this.hass.localize("ui.panel.config.zwave_js.common.source")}: + ${this._configEntry!.title} +
+ ` + : ""} +
+ ${this.hass.localize("ui.panel.config.zwave_js.common.node_id")}: + ${this._node.node_id} +
+ ${!this._node.is_controller_node + ? html` +
+ ${this.hass.localize( + "ui.panel.config.zwave_js.device_info.node_status" + )}: + ${this.hass.localize( + `ui.panel.config.zwave_js.node_status.${ + nodeStatus[this._node.status] + }` + )} +
+
+ ${this.hass.localize( + "ui.panel.config.zwave_js.device_info.node_ready" + )}: + ${this._node.ready + ? this.hass.localize("ui.common.yes") + : this.hass.localize("ui.common.no")} +
+
+ ${this.hass.localize( + "ui.panel.config.zwave_js.device_info.highest_security" + )}: + ${this._node.highest_security_class !== null + ? this.hass.localize( + `ui.panel.config.zwave_js.security_classes.${ + SecurityClass[this._node.highest_security_class] + }.title` + ) + : this._node.is_secure === false + ? this.hass.localize( + "ui.panel.config.zwave_js.security_classes.none.title" + ) + : this.hass.localize( + "ui.panel.config.zwave_js.device_info.unknown" + )} +
+
+ ${this.hass.localize( + "ui.panel.config.zwave_js.device_info.zwave_plus" + )}: + ${this._node.zwave_plus_version + ? this.hass.localize( + "ui.panel.config.zwave_js.device_info.zwave_plus_version", + "version", + this._node.zwave_plus_version + ) + : this.hass.localize("ui.common.no")} +
+ ` + : ""} +
`; } diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 8e989de7c3fa..44b97fb3c644 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -1,4 +1,9 @@ -import { mdiOpenInNew, mdiPencil, mdiPlusCircle } from "@mdi/js"; +import { + mdiDotsVertical, + mdiOpenInNew, + mdiPencil, + mdiPlusCircle, +} from "@mdi/js"; import "@polymer/paper-tooltip/paper-tooltip"; import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit"; import { customElement, property, state } from "lit/decorators"; @@ -8,11 +13,13 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; +import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event"; import { stringCompare } from "../../../common/string/compare"; import { slugify } from "../../../common/string/slugify"; import { groupBy } from "../../../common/util/group-by"; import "../../../components/entity/ha-battery-icon"; import "../../../components/ha-alert"; +import "../../../components/ha-button-menu"; import "../../../components/ha-icon-button"; import "../../../components/ha-icon-next"; import "../../../components/ha-svg-icon"; @@ -26,14 +33,14 @@ import { import { computeDeviceName, DeviceRegistryEntry, - updateDeviceRegistryEntry, removeConfigEntryFromDevice, + updateDeviceRegistryEntry, } from "../../../data/device_registry"; import { + DiagnosticInfo, fetchDiagnosticHandler, - getDeviceDiagnosticsDownloadUrl, getConfigEntryDiagnosticsDownloadUrl, - DiagnosticInfo, + getDeviceDiagnosticsDownloadUrl, } from "../../../data/diagnostics"; import { EntityRegistryEntry, @@ -51,9 +58,10 @@ import { import "../../../layouts/hass-error-screen"; import "../../../layouts/hass-tabs-subpage"; import { haStyle } from "../../../resources/styles"; -import { HomeAssistant, Route } from "../../../types"; +import type { HomeAssistant, Route } from "../../../types"; import { brandsUrl } from "../../../util/brands-url"; import { fileDownload } from "../../../util/file_download"; +import "../../logbook/ha-logbook"; import "../ha-config-section"; import { configSections } from "../ha-panel-config"; import "./device-detail/ha-device-entities-card"; @@ -63,7 +71,6 @@ import { loadDeviceRegistryDetailDialog, showDeviceRegistryDetailDialog, } from "./device-registry-detail/show-dialog-device-registry-detail"; -import "../../logbook/ha-logbook"; export interface EntityRegistryStateEntry extends EntityRegistryEntry { stateName?: string | null; @@ -215,7 +222,7 @@ export class HaConfigDevicePage extends LitElement { this._diagnosticDownloadLinks = Math.random(); this._deleteButtons = []; // To prevent re-rendering if no delete buttons this._renderDiagnosticButtons(this._diagnosticDownloadLinks); - this._renderDeleteButtons(); + this._renderDeleteActions(); } private async _renderDiagnosticButtons(requestId: number): Promise { @@ -269,7 +276,7 @@ export class HaConfigDevicePage extends LitElement { ).map( (link) => html` - + ${links.length > 1 ? this.hass.localize( `ui.panel.config.devices.download_diagnostics_integration`, @@ -283,14 +290,14 @@ export class HaConfigDevicePage extends LitElement { : this.hass.localize( `ui.panel.config.devices.download_diagnostics` )} - + ` ); } } - private _renderDeleteButtons() { + private _renderDeleteActions() { const device = this._device(this.deviceId, this.devices); if (!device) { @@ -303,10 +310,10 @@ export class HaConfigDevicePage extends LitElement { return; } buttons.push(html` - ${buttons.length > 1 ? this.hass.localize( @@ -316,7 +323,7 @@ export class HaConfigDevicePage extends LitElement { } ) : this.hass.localize(`ui.panel.config.devices.delete_device`)} - + `); }); @@ -325,8 +332,11 @@ export class HaConfigDevicePage extends LitElement { } } - private async _confirmDeleteEntry(e: MouseEvent): Promise { - const entryId = (e.currentTarget as any).entryId; + private async _confirmDeleteEntry(ev): Promise { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } + const entryId = (ev.currentTarget as any).entryId; const confirmed = await showConfirmationDialog(this, { text: this.hass.localize("ui.panel.config.devices.confirm_delete"), @@ -407,20 +417,23 @@ export class HaConfigDevicePage extends LitElement { )} ${device.disabled_by === "user" - ? html`
- - ${this.hass.localize("ui.common.enable")} - -
` + ? html` +
+ + ${this.hass.localize("ui.common.enable")} + +
+ ` : ""} ` ); } - const deviceActions: (TemplateResult | string)[] = []; + const deviceButtonActions: (TemplateResult | string)[] = []; + const deviceOverflowActions: (TemplateResult | string)[] = []; if (configurationUrl) { - deviceActions.push(html` + deviceButtonActions.push(html`
${ @@ -555,57 +564,31 @@ export class HaConfigDevicePage extends LitElement { > ${deviceInfo} ${ - deviceActions.length + deviceButtonActions.length || deviceOverflowActions.length ? html`
- ${deviceActions} +
${deviceButtonActions}
+ + ${deviceOverflowActions.length + ? html` + + + ${deviceOverflowActions} + + ` + : ""}
` : "" } -
-
- ${["control", "sensor", "config", "diagnostic"].map((category) => - // Make sure we render controls if no other cards will be rendered - entitiesByCategory[category].length > 0 || - (entities.length === 0 && category === "control") - ? html` - - - ` - : "" - )} - ${ - isComponentLoaded(this.hass, "logbook") - ? html` - -

- ${this.hass.localize("panel.logbook")} -

- -
- ` - : "" - } -
-
+ ${ isComponentLoaded(this.hass, "automation") ? html` @@ -874,6 +857,49 @@ export class HaConfigDevicePage extends LitElement { ` : "" } +
+
+ ${["control", "sensor", "config", "diagnostic"].map((category) => + // Make sure we render controls if no other cards will be rendered + entitiesByCategory[category].length > 0 || + (entities.length === 0 && category === "control") + ? html` + + + ` + : "" + )} +
+
+ + ${ + isComponentLoaded(this.hass, "logbook") + ? html` + +

+ ${this.hass.localize("panel.logbook")} +

+ +
+ ` + : "" + }
@@ -928,14 +954,14 @@ export class HaConfigDevicePage extends LitElement { device: DeviceRegistryEntry, integrations: ConfigEntry[], deviceInfo: TemplateResult[], - deviceActions: (string | TemplateResult)[] + deviceOverflowActions: (string | TemplateResult)[] ) { const domains = integrations.map((int) => int.domain); if (domains.includes("mqtt")) { import( "./device-detail/integration-elements/mqtt/ha-device-actions-mqtt" ); - deviceActions.push(html` + deviceOverflowActions.push(html` `); - deviceActions.push(html` + deviceOverflowActions.push(html` `); - deviceActions.push(html` + deviceOverflowActions.push(html` Date: Tue, 24 May 2022 17:50:02 +0200 Subject: [PATCH 2/7] update logbook styling --- src/panels/logbook/ha-logbook-renderer.ts | 11 ++++++----- src/resources/styles.ts | 1 + 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/src/panels/logbook/ha-logbook-renderer.ts b/src/panels/logbook/ha-logbook-renderer.ts index 69b7bed3cf09..6e382b3cce83 100644 --- a/src/panels/logbook/ha-logbook-renderer.ts +++ b/src/panels/logbook/ha-logbook-renderer.ts @@ -556,10 +556,6 @@ class HaLogbookRenderer extends LitElement { padding: 0 16px; } - .narrow .date { - padding: 0 8px; - } - .rtl .date { direction: rtl; } @@ -590,6 +586,12 @@ class HaLogbookRenderer extends LitElement { a { color: var(--primary-color); + text-decoration: none; + } + + button.link { + color: var(--paper-item-icon-color); + text-decoration: none; } .container { @@ -607,7 +609,6 @@ class HaLogbookRenderer extends LitElement { .narrow .entry { line-height: 1.5; - padding: 8px; } .narrow .icon-message state-badge { diff --git a/src/resources/styles.ts b/src/resources/styles.ts index 92f141c829c0..62af21f47140 100644 --- a/src/resources/styles.ts +++ b/src/resources/styles.ts @@ -158,6 +158,7 @@ export const buttonLinkStyle = css` text-align: left; text-decoration: underline; cursor: pointer; + outline: none; } `; From bbfddf855974b03612c14625b6408b2a3b412381 Mon Sep 17 00:00:00 2001 From: Zack Date: Tue, 24 May 2022 12:23:33 -0500 Subject: [PATCH 3/7] Start moving stuff --- .../zha/ha-device-info-zha.ts | 7 +- .../zwave_js/device-actions.ts | 4 + .../zwave_js/ha-device-actions-zwave_js.ts | 6 ++ .../zwave_js/ha-device-info-zwave_js.ts | 5 + .../config/devices/ha-config-device-page.ts | 92 +++++++++++-------- 5 files changed, 75 insertions(+), 39 deletions(-) create mode 100644 src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts index 70e80a1dd5e2..5ccaf7c5e593 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-info-zha.ts @@ -41,7 +41,7 @@ export class HaDeviceActionsZha extends LitElement { return html``; } return html` - +
IEEE: ${this._zhaDevice.ieee}
Nwk: ${formatAsPaddedHex(this._zhaDevice.nwk)}
Device Type: ${this._zhaDevice.device_type}
@@ -88,6 +88,11 @@ export class HaDeviceActionsZha extends LitElement { word-break: break-all; margin-top: 2px; } + ha-expansion-panel { + --expansion-panel-summary-padding: 0; + --expansion-panel-content-padding: 0; + padding-top: 4px; + } `, ]; } diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts new file mode 100644 index 000000000000..e9eb57fc19fb --- /dev/null +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts @@ -0,0 +1,4 @@ +// export const getZwaveDeviceActions = ( +// hass: HomeAssistant, +// device: DeviceRegistryEntry +// ): DeviceAction[] => {}; diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts index af6ad3c04faf..a5ed41c63135 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts @@ -137,3 +137,9 @@ export class HaDeviceActionsZWaveJS extends LitElement { ]; } } + +declare global { + interface HTMLElementTagNameMap { + "ha-device-actions-zwave_js": HaDeviceActionsZWaveJS; + } +} diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts index c874be26e200..eae6b47a1bd7 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-info-zwave_js.ts @@ -154,6 +154,11 @@ export class HaDeviceInfoZWaveJS extends LitElement { word-break: break-all; margin-top: 2px; } + ha-expansion-panel { + --expansion-panel-summary-padding: 0; + --expansion-panel-content-padding: 0; + padding-top: 4px; + } `, ]; } diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 44b97fb3c644..ab2d017d73a5 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -76,6 +76,15 @@ export interface EntityRegistryStateEntry extends EntityRegistryEntry { stateName?: string | null; } +export interface DeviceAction { + href?: string; + action?: any; + label: string; + trailingIcon?: string; + entryId?: string; + classes?: string; +} + @customElement("ha-config-device-page") export class HaConfigDevicePage extends LitElement { @property({ attribute: false }) public hass!: HomeAssistant; @@ -101,11 +110,11 @@ export class HaConfigDevicePage extends LitElement { @state() private _related?: RelatedResult; // If a number, it's the request ID so we make sure we don't show older info - @state() private _diagnosticDownloadLinks?: - | number - | (TemplateResult | string)[]; + @state() private _diagnosticDownloadLinks?: number | DeviceAction[]; - @state() private _deleteButtons?: (TemplateResult | string)[]; + @state() private _deleteButtons?: DeviceAction[]; + + @state() private _deviceActions?: DeviceAction[]; private _logbookTime = { recent: 86400 }; @@ -273,27 +282,21 @@ export class HaConfigDevicePage extends LitElement { if (links.length > 0) { this._diagnosticDownloadLinks = ( links as { link: string; domain: string }[] - ).map( - (link) => html` -
- - ${links.length > 1 - ? this.hass.localize( - `ui.panel.config.devices.download_diagnostics_integration`, - { - integration: domainToName( - this.hass.localize, - link.domain - ), - } - ) - : this.hass.localize( - `ui.panel.config.devices.download_diagnostics` - )} - - - ` - ); + ).map((link) => ({ + href: link.link, + action: this._signUrl, + label: + links.length > 1 + ? this.hass.localize( + `ui.panel.config.devices.download_diagnostics_integration`, + { + integration: domainToName(this.hass.localize, link.domain), + } + ) + : this.hass.localize( + `ui.panel.config.devices.download_diagnostics` + ), + })); } } @@ -304,27 +307,25 @@ export class HaConfigDevicePage extends LitElement { return; } - const buttons: TemplateResult[] = []; + const buttons: DeviceAction[] = []; this._integrations(device, this.entries).forEach((entry) => { if (entry.state !== "loaded" || !entry.supports_remove_device) { return; } - buttons.push(html` - - ${buttons.length > 1 + buttons.push({ + action: this._confirmDeleteEntry, + entryId: entry.entry_id, + classes: "warning", + label: + buttons.length > 1 ? this.hass.localize( `ui.panel.config.devices.delete_device_integration`, { integration: domainToName(this.hass.localize, entry.domain), } ) - : this.hass.localize(`ui.panel.config.devices.delete_device`)} - - `); + : this.hass.localize(`ui.panel.config.devices.delete_device`), + }); }); if (buttons.length > 0) { @@ -431,8 +432,23 @@ export class HaConfigDevicePage extends LitElement { const deviceButtonActions: (TemplateResult | string)[] = []; const deviceOverflowActions: (TemplateResult | string)[] = []; + const deviceActions: { + href?: string; + action?: any; + label: string; + trailingIcon?: string; + }[] = []; if (configurationUrl) { + deviceActions.push({ + href: configurationUrl, + label: this.hass.localize( + `ui.panel.config.devices.open_configuration_url_${ + device.entry_type || "device" + }` + ), + trailingIcon: mdiOpenInNew, + }); deviceButtonActions.push(html` Date: Tue, 24 May 2022 22:43:56 -0500 Subject: [PATCH 4/7] Update to better logic for buttons --- .../mqtt/device-actions.ts | 13 + .../mqtt/ha-device-actions-mqtt.ts | 36 -- .../zha/device-actions.ts | 108 +++++ .../zha/ha-device-actions-zha.ts | 161 ------- .../zwave_js/device-actions.ts | 73 ++- .../zwave_js/ha-device-actions-zwave_js.ts | 145 ------ .../config/devices/ha-config-device-page.ts | 453 ++++++++++-------- 7 files changed, 431 insertions(+), 558 deletions(-) create mode 100644 src/panels/config/devices/device-detail/integration-elements/mqtt/device-actions.ts delete mode 100644 src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts create mode 100644 src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts delete mode 100644 src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts delete mode 100644 src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts diff --git a/src/panels/config/devices/device-detail/integration-elements/mqtt/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/mqtt/device-actions.ts new file mode 100644 index 000000000000..ff3be5d1a9fb --- /dev/null +++ b/src/panels/config/devices/device-detail/integration-elements/mqtt/device-actions.ts @@ -0,0 +1,13 @@ +import type { DeviceRegistryEntry } from "../../../../../../data/device_registry"; +import type { DeviceAction } from "../../../ha-config-device-page"; +import { showMQTTDeviceDebugInfoDialog } from "./show-dialog-mqtt-device-debug-info"; + +export const getMQTTDeviceActions = ( + el: HTMLElement, + device: DeviceRegistryEntry +): DeviceAction[] => [ + { + label: "MQTT Info", + action: async () => showMQTTDeviceDebugInfoDialog(el, { device }), + }, +]; diff --git a/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts b/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts deleted file mode 100644 index 0980c2ea9b7c..000000000000 --- a/src/panels/config/devices/device-detail/integration-elements/mqtt/ha-device-actions-mqtt.ts +++ /dev/null @@ -1,36 +0,0 @@ -import "@material/mwc-list/mwc-list-item"; -import { html, LitElement, TemplateResult } from "lit"; -import { customElement, property } from "lit/decorators"; -import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; -import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; -import { HomeAssistant } from "../../../../../../types"; -import { showMQTTDeviceDebugInfoDialog } from "./show-dialog-mqtt-device-debug-info"; - -@customElement("ha-device-actions-mqtt") -export class HaDeviceActionsMqtt extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property() public device!: DeviceRegistryEntry; - - protected render(): TemplateResult { - return html` - - MQTT Info - - `; - } - - private async _showDebugInfo(ev): Promise { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - const device = this.device; - await showMQTTDeviceDebugInfoDialog(this, { device }); - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-device-actions-mqtt": HaDeviceActionsMqtt; - } -} diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts new file mode 100644 index 000000000000..476ff749932a --- /dev/null +++ b/src/panels/config/devices/device-detail/integration-elements/zha/device-actions.ts @@ -0,0 +1,108 @@ +import { navigate } from "../../../../../../common/navigate"; +import type { DeviceRegistryEntry } from "../../../../../../data/device_registry"; +import { fetchZHADevice } from "../../../../../../data/zha"; +import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box"; +import type { HomeAssistant } from "../../../../../../types"; +import { showZHAClusterDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-cluster"; +import { showZHADeviceChildrenDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-children"; +import { showZHADeviceZigbeeInfoDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info"; +import { showZHAReconfigureDeviceDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-reconfigure-device"; +import type { DeviceAction } from "../../../ha-config-device-page"; + +export const getZHADeviceActions = async ( + el: HTMLElement, + hass: HomeAssistant, + device: DeviceRegistryEntry +): Promise => { + const zigbeeConnection = device.connections.find( + (conn) => conn[0] === "zigbee" + ); + + if (!zigbeeConnection) { + return []; + } + + const zhaDevice = await fetchZHADevice(hass, zigbeeConnection[1]); + + if (!zhaDevice) { + return []; + } + + const actions: DeviceAction[] = []; + + if (zhaDevice.device_type !== "Coordinator") { + actions.push({ + label: hass.localize("ui.dialogs.zha_device_info.buttons.reconfigure"), + action: () => showZHAReconfigureDeviceDialog(el, { device: zhaDevice }), + }); + } + + if ( + zhaDevice.power_source === "Mains" && + (zhaDevice.device_type === "Router" || + zhaDevice.device_type === "Coordinator") + ) { + actions.push( + ...[ + { + label: hass.localize("ui.dialogs.zha_device_info.buttons.add"), + action: () => navigate(`/config/zha/add/${zhaDevice!.ieee}`), + }, + { + label: hass.localize( + "ui.dialogs.zha_device_info.buttons.device_children" + ), + action: () => showZHADeviceChildrenDialog(el, { device: zhaDevice! }), + }, + ] + ); + } + + if (zhaDevice.device_type !== "Coordinator") { + actions.push( + ...[ + { + label: hass.localize( + "ui.dialogs.zha_device_info.buttons.zigbee_information" + ), + action: () => + showZHADeviceZigbeeInfoDialog(el, { device: zhaDevice }), + }, + { + label: hass.localize("ui.dialogs.zha_device_info.buttons.clusters"), + action: () => showZHAClusterDialog(el, { device: zhaDevice }), + }, + { + label: hass.localize( + "ui.dialogs.zha_device_info.buttons.view_in_visualization" + ), + action: () => + navigate(`/config/zha/visualization/${zhaDevice!.device_reg_id}`), + }, + { + label: hass.localize("ui.dialogs.zha_device_info.buttons.remove"), + classes: "warning", + action: async () => { + const confirmed = await showConfirmationDialog(el, { + text: hass.localize( + "ui.dialogs.zha_device_info.confirmations.remove" + ), + }); + + if (!confirmed) { + return; + } + + await hass.callService("zha", "remove", { + ieee: zhaDevice.ieee, + }); + + history.back(); + }, + }, + ] + ); + } + + return actions; +}; diff --git a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts b/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts deleted file mode 100644 index 4f4df82b8c6f..000000000000 --- a/src/panels/config/devices/device-detail/integration-elements/zha/ha-device-actions-zha.ts +++ /dev/null @@ -1,161 +0,0 @@ -import "@material/mwc-list/mwc-list-item"; -import { html, LitElement, PropertyValues, TemplateResult } from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; -import { navigate } from "../../../../../../common/navigate"; -import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; -import { fetchZHADevice, ZHADevice } from "../../../../../../data/zha"; -import { showConfirmationDialog } from "../../../../../../dialogs/generic/show-dialog-box"; -import { HomeAssistant } from "../../../../../../types"; -import { showZHAClusterDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-cluster"; -import { showZHADeviceChildrenDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-children"; -import { showZHADeviceZigbeeInfoDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-device-zigbee-info"; -import { showZHAReconfigureDeviceDialog } from "../../../../integrations/integration-panels/zha/show-dialog-zha-reconfigure-device"; - -@customElement("ha-device-actions-zha") -export class HaDeviceActionsZha extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property() public device!: DeviceRegistryEntry; - - @state() private _zhaDevice?: ZHADevice; - - protected updated(changedProperties: PropertyValues) { - if (changedProperties.has("device")) { - const zigbeeConnection = this.device.connections.find( - (conn) => conn[0] === "zigbee" - ); - if (!zigbeeConnection) { - return; - } - fetchZHADevice(this.hass, zigbeeConnection[1]).then((device) => { - this._zhaDevice = device; - }); - } - } - - protected render(): TemplateResult { - if (!this._zhaDevice) { - return html``; - } - return html` - ${this._zhaDevice.device_type !== "Coordinator" - ? html` - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.reconfigure" - )} - - ` - : ""} - ${this._zhaDevice.power_source === "Mains" && - (this._zhaDevice.device_type === "Router" || - this._zhaDevice.device_type === "Coordinator") - ? html` - - ${this.hass!.localize("ui.dialogs.zha_device_info.buttons.add")} - - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.device_children" - )} - - ` - : ""} - ${this._zhaDevice.device_type !== "Coordinator" - ? html` - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.zigbee_information" - )} - - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.clusters" - )} - - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.view_in_visualization" - )} - - - ${this.hass!.localize( - "ui.dialogs.zha_device_info.buttons.remove" - )} - - ` - : ""} - `; - } - - private async _showClustersDialog(ev): Promise { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - await showZHAClusterDialog(this, { device: this._zhaDevice! }); - } - - private async _onReconfigureNodeClick(ev): Promise { - if (!this.hass || !shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZHAReconfigureDeviceDialog(this, { device: this._zhaDevice! }); - } - - private _onAddDevicesClick(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - navigate(`/config/zha/add/${this._zhaDevice!.ieee}`); - } - - private _onViewInVisualizationClick(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - navigate(`/config/zha/visualization/${this._zhaDevice!.device_reg_id}`); - } - - private async _handleZigbeeInfoClicked(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZHADeviceZigbeeInfoDialog(this, { device: this._zhaDevice! }); - } - - private async _handleDeviceChildrenClicked(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZHADeviceChildrenDialog(this, { device: this._zhaDevice! }); - } - - private async _removeDevice(ev) { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - const confirmed = await showConfirmationDialog(this, { - text: this.hass.localize( - "ui.dialogs.zha_device_info.confirmations.remove" - ), - }); - - if (!confirmed) { - return; - } - - await this.hass.callService("zha", "remove", { - ieee: this._zhaDevice!.ieee, - }); - - history.back(); - } -} diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts index e9eb57fc19fb..e2ecedbeb443 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts @@ -1,4 +1,69 @@ -// export const getZwaveDeviceActions = ( -// hass: HomeAssistant, -// device: DeviceRegistryEntry -// ): DeviceAction[] => {}; +import { getConfigEntries } from "../../../../../../data/config_entries"; +import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; +import { fetchZwaveNodeStatus } from "../../../../../../data/zwave_js"; +import type { HomeAssistant } from "../../../../../../types"; +import { showZWaveJSHealNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-heal-node"; +import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node"; +import { showZWaveJSRemoveFailedNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-remove-failed-node"; +import type { DeviceAction } from "../../../ha-config-device-page"; + +export const getZwaveDeviceActions = async ( + el: HTMLElement, + hass: HomeAssistant, + device: DeviceRegistryEntry +): Promise => { + const configEntries = await getConfigEntries(hass, { + domain: "zwave_js", + }); + + const configEntry = configEntries.find((entry) => + device.config_entries.includes(entry.entry_id) + ); + + if (!configEntry) { + return []; + } + + const entryId = configEntry.entry_id; + + const node = await fetchZwaveNodeStatus(hass, device.id); + + if (!node || !node.is_controller_node) { + return []; + } + + return [ + { + label: hass.localize( + "ui.panel.config.zwave_js.device_info.device_config" + ), + href: `/config/zwave_js/node_config/${device.id}?config_entry=${entryId}`, + }, + { + label: hass.localize( + "ui.panel.config.zwave_js.device_info.reinterview_device" + ), + action: () => + showZWaveJSReinterviewNodeDialog(el, { + device_id: device.id, + }), + }, + { + label: hass.localize("ui.panel.config.zwave_js.device_info.heal_node"), + action: () => + showZWaveJSHealNodeDialog(el, { + entry_id: entryId, + device: device, + }), + }, + { + label: hass.localize( + "ui.panel.config.zwave_js.device_info.remove_failed" + ), + action: () => + showZWaveJSRemoveFailedNodeDialog(el, { + device_id: device.id, + }), + }, + ]; +}; diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts deleted file mode 100644 index a5ed41c63135..000000000000 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js.ts +++ /dev/null @@ -1,145 +0,0 @@ -import "@material/mwc-list/mwc-list-item"; -import { - css, - CSSResultGroup, - html, - LitElement, - PropertyValues, - TemplateResult, -} from "lit"; -import { customElement, property, state } from "lit/decorators"; -import { shouldHandleRequestSelectedEvent } from "../../../../../../common/mwc/handle-request-selected-event"; -import { getConfigEntries } from "../../../../../../data/config_entries"; -import { DeviceRegistryEntry } from "../../../../../../data/device_registry"; -import { - fetchZwaveNodeStatus, - ZWaveJSNodeStatus, -} from "../../../../../../data/zwave_js"; -import { haStyle } from "../../../../../../resources/styles"; -import { HomeAssistant } from "../../../../../../types"; -import { showZWaveJSHealNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-heal-node"; -import { showZWaveJSReinterviewNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-reinterview-node"; -import { showZWaveJSRemoveFailedNodeDialog } from "../../../../integrations/integration-panels/zwave_js/show-dialog-zwave_js-remove-failed-node"; - -@customElement("ha-device-actions-zwave_js") -export class HaDeviceActionsZWaveJS extends LitElement { - @property({ attribute: false }) public hass!: HomeAssistant; - - @property() public device!: DeviceRegistryEntry; - - @state() private _entryId?: string; - - @state() private _node?: ZWaveJSNodeStatus; - - public willUpdate(changedProperties: PropertyValues) { - super.willUpdate(changedProperties); - if (changedProperties.has("device")) { - this._fetchNodeDetails(); - } - } - - protected async _fetchNodeDetails() { - if (!this.device) { - return; - } - - this._node = undefined; - - const configEntries = await getConfigEntries(this.hass, { - domain: "zwave_js", - }); - - const configEntry = configEntries.find((entry) => - this.device.config_entries.includes(entry.entry_id) - ); - - if (!configEntry) { - return; - } - - this._entryId = configEntry.entry_id; - - this._node = await fetchZwaveNodeStatus(this.hass, this.device.id); - } - - protected render(): TemplateResult { - if (!this._node) { - return html``; - } - return html` - ${!this._node.is_controller_node - ? html` - - - ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.device_config" - )} - - - - ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.reinterview_device" - )} - - - ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.heal_node" - )} - - - ${this.hass.localize( - "ui.panel.config.zwave_js.device_info.remove_failed" - )} - - ` - : ""} - `; - } - - private async _reinterviewClicked(ev) { - if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZWaveJSReinterviewNodeDialog(this, { - device_id: this.device.id, - }); - } - - private async _healNodeClicked(ev) { - if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZWaveJSHealNodeDialog(this, { - entry_id: this._entryId!, - device: this.device, - }); - } - - private async _removeFailedNode(ev) { - if (!this.device || !shouldHandleRequestSelectedEvent(ev)) { - return; - } - showZWaveJSRemoveFailedNodeDialog(this, { - device_id: this.device.id, - }); - } - - static get styles(): CSSResultGroup { - return [ - haStyle, - css` - a { - text-decoration: none; - } - `, - ]; - } -} - -declare global { - interface HTMLElementTagNameMap { - "ha-device-actions-zwave_js": HaDeviceActionsZWaveJS; - } -} diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index ab2d017d73a5..f95e7e53cef3 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -81,7 +81,6 @@ export interface DeviceAction { action?: any; label: string; trailingIcon?: string; - entryId?: string; classes?: string; } @@ -212,15 +211,17 @@ export class HaConfigDevicePage extends LitElement { if ( changedProps.has("deviceId") || changedProps.has("devices") || - changedProps.has("deviceId") || changedProps.has("entries") ) { this._diagnosticDownloadLinks = undefined; this._deleteButtons = undefined; + this._deviceActions = undefined; } if ( - (this._diagnosticDownloadLinks && this._deleteButtons) || + (this._diagnosticDownloadLinks && + this._deleteButtons && + this._deviceActions) || !this.devices || !this.deviceId || !this.entries @@ -230,124 +231,10 @@ export class HaConfigDevicePage extends LitElement { this._diagnosticDownloadLinks = Math.random(); this._deleteButtons = []; // To prevent re-rendering if no delete buttons + this._deviceActions = []; this._renderDiagnosticButtons(this._diagnosticDownloadLinks); this._renderDeleteActions(); - } - - private async _renderDiagnosticButtons(requestId: number): Promise { - if (!isComponentLoaded(this.hass, "diagnostics")) { - return; - } - - const device = this._device(this.deviceId, this.devices); - - if (!device) { - return; - } - - let links = await Promise.all( - this._integrations(device, this.entries).map( - async (entry): Promise => { - if (entry.state !== "loaded") { - return false; - } - let info: DiagnosticInfo; - try { - info = await fetchDiagnosticHandler(this.hass, entry.domain); - } catch (err: any) { - if (err.code === "not_found") { - return false; - } - throw err; - } - - if (!info.handlers.device && !info.handlers.config_entry) { - return false; - } - return { - link: info.handlers.device - ? getDeviceDiagnosticsDownloadUrl(entry.entry_id, this.deviceId) - : getConfigEntryDiagnosticsDownloadUrl(entry.entry_id), - domain: entry.domain, - }; - } - ) - ); - - links = links.filter(Boolean); - - if (this._diagnosticDownloadLinks !== requestId) { - return; - } - if (links.length > 0) { - this._diagnosticDownloadLinks = ( - links as { link: string; domain: string }[] - ).map((link) => ({ - href: link.link, - action: this._signUrl, - label: - links.length > 1 - ? this.hass.localize( - `ui.panel.config.devices.download_diagnostics_integration`, - { - integration: domainToName(this.hass.localize, link.domain), - } - ) - : this.hass.localize( - `ui.panel.config.devices.download_diagnostics` - ), - })); - } - } - - private _renderDeleteActions() { - const device = this._device(this.deviceId, this.devices); - - if (!device) { - return; - } - - const buttons: DeviceAction[] = []; - this._integrations(device, this.entries).forEach((entry) => { - if (entry.state !== "loaded" || !entry.supports_remove_device) { - return; - } - buttons.push({ - action: this._confirmDeleteEntry, - entryId: entry.entry_id, - classes: "warning", - label: - buttons.length > 1 - ? this.hass.localize( - `ui.panel.config.devices.delete_device_integration`, - { - integration: domainToName(this.hass.localize, entry.domain), - } - ) - : this.hass.localize(`ui.panel.config.devices.delete_device`), - }); - }); - - if (buttons.length > 0) { - this._deleteButtons = buttons; - } - } - - private async _confirmDeleteEntry(ev): Promise { - if (!shouldHandleRequestSelectedEvent(ev)) { - return; - } - const entryId = (ev.currentTarget as any).entryId; - - const confirmed = await showConfirmationDialog(this, { - text: this.hass.localize("ui.panel.config.devices.confirm_delete"), - }); - - if (!confirmed) { - return; - } - - await removeConfigEntryFromDevice(this.hass!, this.deviceId, entryId); + this._renderDeviceActions(); } protected firstUpdated(changedProps) { @@ -392,14 +279,18 @@ export class HaConfigDevicePage extends LitElement { : undefined; const area = this._computeArea(this.areas, device); - const configurationUrlIsHomeAssistant = - device.configuration_url?.startsWith("homeassistant://") || false; + const deviceInfo: TemplateResult[] = []; - const configurationUrl = configurationUrlIsHomeAssistant - ? device.configuration_url!.replace("homeassistant://", "/") - : device.configuration_url; + const actions = [...(this._deviceActions || [])]; + if (Array.isArray(this._diagnosticDownloadLinks)) { + actions.push(...this._diagnosticDownloadLinks); + } + if (this._deleteButtons) { + actions.push(...this._deleteButtons); + } - const deviceInfo: TemplateResult[] = []; + const firstDeviceAction = actions[0]; + const overflowDeviceActions = actions.slice(1); if (device.disabled_by) { deviceInfo.push( @@ -430,59 +321,7 @@ export class HaConfigDevicePage extends LitElement { ); } - const deviceButtonActions: (TemplateResult | string)[] = []; - const deviceOverflowActions: (TemplateResult | string)[] = []; - const deviceActions: { - href?: string; - action?: any; - label: string; - trailingIcon?: string; - }[] = []; - - if (configurationUrl) { - deviceActions.push({ - href: configurationUrl, - label: this.hass.localize( - `ui.panel.config.devices.open_configuration_url_${ - device.entry_type || "device" - }` - ), - trailingIcon: mdiOpenInNew, - }); - deviceButtonActions.push(html` - - - ${this.hass.localize( - `ui.panel.config.devices.open_configuration_url_${ - device.entry_type || "device" - }` - )} - - - - `); - } - - this._renderIntegrationInfo( - device, - integrations, - deviceInfo, - deviceOverflowActions - ); - - if (Array.isArray(this._diagnosticDownloadLinks)) { - deviceActions.push(...this._diagnosticDownloadLinks); - } - if (this._deleteButtons) { - deviceActions.push(...this._deleteButtons); - } + this._renderIntegrationInfo(device, integrations, deviceInfo); return html` ${deviceInfo} ${ - deviceButtonActions.length || deviceOverflowActions.length + actions.length ? html`
-
${deviceButtonActions}
+ - ${deviceOverflowActions.length + ${overflowDeviceActions!.length ? html` - ${deviceOverflowActions} + ${overflowDeviceActions.map( + (deviceAction) => html` + + + ${deviceAction!.label} + ${deviceAction!.trailingIcon + ? html` + + ` + : ""} + + + ` + )} ` : ""} @@ -895,7 +774,6 @@ export class HaConfigDevicePage extends LitElement { )}
- ${ isComponentLoaded(this.hass, "logbook") ? html` @@ -922,6 +800,177 @@ export class HaConfigDevicePage extends LitElement { `; } + private async _renderDiagnosticButtons(requestId: number): Promise { + if (!isComponentLoaded(this.hass, "diagnostics")) { + return; + } + + const device = this._device(this.deviceId, this.devices); + + if (!device) { + return; + } + + let links = await Promise.all( + this._integrations(device, this.entries).map( + async (entry): Promise => { + if (entry.state !== "loaded") { + return false; + } + let info: DiagnosticInfo; + try { + info = await fetchDiagnosticHandler(this.hass, entry.domain); + } catch (err: any) { + if (err.code === "not_found") { + return false; + } + throw err; + } + + if (!info.handlers.device && !info.handlers.config_entry) { + return false; + } + return { + link: info.handlers.device + ? getDeviceDiagnosticsDownloadUrl(entry.entry_id, this.deviceId) + : getConfigEntryDiagnosticsDownloadUrl(entry.entry_id), + domain: entry.domain, + }; + } + ) + ); + + links = links.filter(Boolean); + + if (this._diagnosticDownloadLinks !== requestId) { + return; + } + if (links.length > 0) { + this._diagnosticDownloadLinks = ( + links as { link: string; domain: string }[] + ).map((link) => ({ + href: link.link, + action: this._signUrl, + label: + links.length > 1 + ? this.hass.localize( + `ui.panel.config.devices.download_diagnostics_integration`, + { + integration: domainToName(this.hass.localize, link.domain), + } + ) + : this.hass.localize( + `ui.panel.config.devices.download_diagnostics` + ), + })); + } + } + + private _renderDeleteActions() { + const device = this._device(this.deviceId, this.devices); + + if (!device) { + return; + } + + const buttons: DeviceAction[] = []; + this._integrations(device, this.entries).forEach((entry) => { + if (entry.state !== "loaded" || !entry.supports_remove_device) { + return; + } + buttons.push({ + action: async () => { + const confirmed = await showConfirmationDialog(this, { + text: this.hass.localize("ui.panel.config.devices.confirm_delete"), + }); + + if (!confirmed) { + return; + } + + await removeConfigEntryFromDevice( + this.hass!, + this.deviceId, + entry.entry_id + ); + }, + classes: "warning", + label: + buttons.length > 1 + ? this.hass.localize( + `ui.panel.config.devices.delete_device_integration`, + { + integration: domainToName(this.hass.localize, entry.domain), + } + ) + : this.hass.localize(`ui.panel.config.devices.delete_device`), + }); + }); + + if (buttons.length > 0) { + this._deleteButtons = buttons; + } + } + + private async _renderDeviceActions() { + const device = this._device(this.deviceId, this.devices); + + if (!device) { + return; + } + + const deviceActions: DeviceAction[] = []; + + const configurationUrlIsHomeAssistant = + device.configuration_url?.startsWith("homeassistant://") || false; + + const configurationUrl = configurationUrlIsHomeAssistant + ? device.configuration_url!.replace("homeassistant://", "/") + : device.configuration_url; + + if (configurationUrl) { + deviceActions.push({ + href: configurationUrl, + label: this.hass.localize( + `ui.panel.config.devices.open_configuration_url_${ + device.entry_type || "device" + }` + ), + trailingIcon: mdiOpenInNew, + }); + } + + const domains = this._integrations(device, this.entries).map( + (int) => int.domain + ); + + if (domains.includes("mqtt")) { + const mqtt = await import( + "./device-detail/integration-elements/mqtt/device-actions" + ); + const actions = mqtt.getMQTTDeviceActions(this, device); + deviceActions.push(...actions); + } else if (domains.includes("zha")) { + const zha = await import( + "./device-detail/integration-elements/zha/device-actions" + ); + const actions = await zha.getZHADeviceActions(this, this.hass, device); + deviceActions.push(...actions); + } else if (domains.includes("zwave_js")) { + const zwave = await import( + "./device-detail/integration-elements/zwave_js/device-actions" + ); + const actions = await zwave.getZwaveDeviceActions( + this, + this.hass, + device + ); + deviceActions.push(...actions); + } + + this._deviceActions = deviceActions; + } + private _computeEntityName(entity: EntityRegistryEntry) { if (entity.name) { return entity.name; @@ -969,23 +1018,10 @@ export class HaConfigDevicePage extends LitElement { private _renderIntegrationInfo( device: DeviceRegistryEntry, integrations: ConfigEntry[], - deviceInfo: TemplateResult[], - deviceOverflowActions: (string | TemplateResult)[] + deviceInfo: TemplateResult[] ) { const domains = integrations.map((int) => int.domain); - if (domains.includes("mqtt")) { - import( - "./device-detail/integration-elements/mqtt/ha-device-actions-mqtt" - ); - deviceOverflowActions.push(html` - - `); - } if (domains.includes("zha")) { - import("./device-detail/integration-elements/zha/ha-device-actions-zha"); import("./device-detail/integration-elements/zha/ha-device-info-zha"); deviceInfo.push(html` `); - deviceOverflowActions.push(html` - - `); } if (domains.includes("zwave_js")) { import( "./device-detail/integration-elements/zwave_js/ha-device-info-zwave_js" ); - import( - "./device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js" - ); deviceInfo.push(html` `); - deviceOverflowActions.push(html` - - `); } } @@ -1166,6 +1187,14 @@ export class HaConfigDevicePage extends LitElement { fileDownload(signedUrl.path); } + private _deviceActionClicked(ev) { + if (!shouldHandleRequestSelectedEvent(ev)) { + return; + } + + (ev.currentTarget as any).action(); + } + static get styles(): CSSResultGroup { return [ haStyle, From bfabdec46af3b1429f92beed62cafa01a4c078ac Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 25 May 2022 12:12:09 +0200 Subject: [PATCH 5/7] fixes --- .../zwave_js/device-actions.ts | 2 +- .../config/devices/ha-config-device-page.ts | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts index e2ecedbeb443..7992a3a767f6 100644 --- a/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts +++ b/src/panels/config/devices/device-detail/integration-elements/zwave_js/device-actions.ts @@ -28,7 +28,7 @@ export const getZwaveDeviceActions = async ( const node = await fetchZwaveNodeStatus(hass, device.id); - if (!node || !node.is_controller_node) { + if (!node || node.is_controller_node) { return []; } diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index f95e7e53cef3..760828450818 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -232,9 +232,9 @@ export class HaConfigDevicePage extends LitElement { this._diagnosticDownloadLinks = Math.random(); this._deleteButtons = []; // To prevent re-rendering if no delete buttons this._deviceActions = []; - this._renderDiagnosticButtons(this._diagnosticDownloadLinks); - this._renderDeleteActions(); - this._renderDeviceActions(); + this._getDiagnosticButtons(this._diagnosticDownloadLinks); + this._getDeleteActions(); + this._getDeviceActions(); } protected firstUpdated(changedProps) { @@ -800,7 +800,7 @@ export class HaConfigDevicePage extends LitElement { `; } - private async _renderDiagnosticButtons(requestId: number): Promise { + private async _getDiagnosticButtons(requestId: number): Promise { if (!isComponentLoaded(this.hass, "diagnostics")) { return; } @@ -866,7 +866,7 @@ export class HaConfigDevicePage extends LitElement { } } - private _renderDeleteActions() { + private _getDeleteActions() { const device = this._device(this.deviceId, this.devices); if (!device) { @@ -912,7 +912,7 @@ export class HaConfigDevicePage extends LitElement { } } - private async _renderDeviceActions() { + private async _getDeviceActions() { const device = this._device(this.deviceId, this.devices); if (!device) { @@ -950,13 +950,15 @@ export class HaConfigDevicePage extends LitElement { ); const actions = mqtt.getMQTTDeviceActions(this, device); deviceActions.push(...actions); - } else if (domains.includes("zha")) { + } + if (domains.includes("zha")) { const zha = await import( "./device-detail/integration-elements/zha/device-actions" ); const actions = await zha.getZHADeviceActions(this, this.hass, device); deviceActions.push(...actions); - } else if (domains.includes("zwave_js")) { + } + if (domains.includes("zwave_js")) { const zwave = await import( "./device-detail/integration-elements/zwave_js/device-actions" ); From cad2a5612d124b449a4b5da1e39e9f8c0d9d45b2 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 25 May 2022 12:24:02 +0200 Subject: [PATCH 6/7] fix rebase --- .../config/devices/ha-config-device-page.ts | 47 +------------------ 1 file changed, 2 insertions(+), 45 deletions(-) diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 1e4e0ec6e2bc..80b2edbeed66 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -280,6 +280,7 @@ export class HaConfigDevicePage extends LitElement { const area = this._computeArea(this.areas, device); const deviceInfo: TemplateResult[] = []; + const deviceAlerts: TemplateResult[] = []; const actions = [...(this._deviceActions || [])]; if (Array.isArray(this._diagnosticDownloadLinks)) { @@ -292,8 +293,6 @@ export class HaConfigDevicePage extends LitElement { const firstDeviceAction = actions[0]; const overflowDeviceActions = actions.slice(1); - const deviceAlerts: TemplateResult[] = []; - if (device.disabled_by) { deviceInfo.push( html` @@ -323,45 +322,7 @@ export class HaConfigDevicePage extends LitElement { ); } - this._renderIntegrationInfo(device, integrations, deviceInfo); - const deviceActions: (TemplateResult | string)[] = []; - - if (configurationUrl) { - deviceActions.push(html` - - - ${this.hass.localize( - `ui.panel.config.devices.open_configuration_url_${ - device.entry_type || "device" - }` - )} - - - - `); - } - - this._renderIntegrationInfo( - device, - integrations, - deviceInfo, - deviceActions, - deviceAlerts - ); - - if (Array.isArray(this._diagnosticDownloadLinks)) { - deviceActions.push(...this._diagnosticDownloadLinks); - } - if (this._deleteButtons) { - deviceActions.push(...this._deleteButtons); - } + this._renderIntegrationInfo(device, integrations, deviceInfo, deviceAlerts); return html` int.domain); @@ -1086,9 +1046,6 @@ export class HaConfigDevicePage extends LitElement { import( "./device-detail/integration-elements/zwave_js/ha-device-info-zwave_js" ); - import( - "./device-detail/integration-elements/zwave_js/ha-device-actions-zwave_js" - ); deviceAlerts.push(html` Date: Wed, 25 May 2022 14:41:02 +0200 Subject: [PATCH 7/7] fix --- .../config/devices/ha-config-device-page.ts | 36 +++++++++---------- 1 file changed, 17 insertions(+), 19 deletions(-) diff --git a/src/panels/config/devices/ha-config-device-page.ts b/src/panels/config/devices/ha-config-device-page.ts index 80b2edbeed66..305575ebe472 100644 --- a/src/panels/config/devices/ha-config-device-page.ts +++ b/src/panels/config/devices/ha-config-device-page.ts @@ -13,7 +13,6 @@ import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { computeDomain } from "../../../common/entity/compute_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateName } from "../../../common/entity/compute_state_name"; -import { shouldHandleRequestSelectedEvent } from "../../../common/mwc/handle-request-selected-event"; import { stringCompare } from "../../../common/string/compare"; import { slugify } from "../../../common/string/slugify"; import { groupBy } from "../../../common/util/group-by"; @@ -78,7 +77,7 @@ export interface EntityRegistryStateEntry extends EntityRegistryEntry { export interface DeviceAction { href?: string; - action?: any; + action?: (ev: any) => void; label: string; trailingIcon?: string; classes?: string; @@ -290,8 +289,7 @@ export class HaConfigDevicePage extends LitElement { actions.push(...this._deleteButtons); } - const firstDeviceAction = actions[0]; - const overflowDeviceActions = actions.slice(1); + const firstDeviceAction = actions.shift(); if (device.disabled_by) { deviceInfo.push( @@ -425,14 +423,15 @@ export class HaConfigDevicePage extends LitElement { > ${deviceInfo} ${ - actions.length + firstDeviceAction || actions.length ? html`