diff --git a/src/panels/config/devices/ha-config-devices-dashboard.ts b/src/panels/config/devices/ha-config-devices-dashboard.ts index 9f25431623..76e086cba9 100644 --- a/src/panels/config/devices/ha-config-devices-dashboard.ts +++ b/src/panels/config/devices/ha-config-devices-dashboard.ts @@ -1,6 +1,6 @@ import { consume } from "@lit-labs/context"; import "@lrnwebcomponents/simple-tooltip/simple-tooltip"; -import { mdiPlus } from "@mdi/js"; +import { mdiChevronRight, mdiMenuDown, mdiPlus } from "@mdi/js"; import { CSSResultGroup, LitElement, @@ -13,6 +13,7 @@ import { import { UnsubscribeFunc } from "home-assistant-js-websocket"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; +import { computeCssColor } from "../../../common/color/compute-color"; import { HASSDomEvent } from "../../../common/dom/fire_event"; import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { @@ -24,6 +25,7 @@ import { LocalizeFunc } from "../../../common/translations/localize"; import { DataTableColumnContainer, RowClickedEvent, + SelectionChangedEvent, } from "../../../components/data-table/ha-data-table"; import "../../../components/data-table/ha-data-table-labels"; import "../../../components/entity/ha-battery-icon"; @@ -37,12 +39,15 @@ import "../../../components/ha-filter-integrations"; import "../../../components/ha-filter-labels"; import "../../../components/ha-filter-states"; import "../../../components/ha-icon-button"; +import "../../../components/ha-menu-item"; +import "../../../components/ha-sub-menu"; import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries"; import { fullEntitiesContext } from "../../../data/context"; import { DeviceEntityLookup, DeviceRegistryEntry, computeDeviceName, + updateDeviceRegistryEntry, } from "../../../data/device_registry"; import { EntityRegistryEntry, @@ -91,6 +96,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) { @state() private _searchParms = new URLSearchParams(window.location.search); + @state() private _selected: string[] = []; + @state() private _filter: string = history.state?.filter || ""; @state() private _filters: Record< @@ -535,6 +542,21 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) { this._labels ); + const labelItems = html` ${this._labels?.map((label) => { + const color = label.color ? computeCssColor(label.color) : undefined; + return html` + + ${label.icon + ? html`` + : nothing} + ${label.name} + + `; + })}`; + return html` + + ${!this.narrow + ? html` + + + + ${labelItems} + ` + : html` + + + + + + ${this.hass.localize( + "ui.panel.config.automation.picker.bulk_actions.add_label" + )} + + + + ${labelItems} + + `} `; } @@ -700,6 +768,25 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) { }); } + private _handleSelectionChanged( + ev: HASSDomEvent + ): void { + this._selected = ev.detail.value; + } + + private async _handleBulkLabel(ev) { + const label = ev.currentTarget.value; + const promises: Promise[] = []; + this._selected.forEach((deviceId) => { + promises.push( + updateDeviceRegistryEntry(this.hass, deviceId, { + labels: this.hass.devices[deviceId].labels.concat(label), + }) + ); + }); + await Promise.all(promises); + } + static get styles(): CSSResultGroup { return [ css` @@ -721,6 +808,16 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) { text-transform: uppercase; direction: var(--direction); } + ha-assist-chip { + --ha-assist-chip-container-shape: 10px; + } + ha-button-menu-new ha-assist-chip { + --md-assist-chip-trailing-space: 8px; + } + ha-label { + --ha-label-background-color: var(--color, var(--grey-color)); + --ha-label-background-opacity: 0.5; + } `, haStyle, ];