mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-28 11:46:42 +00:00
Add multi select to devices (#20321)
This commit is contained in:
parent
a5d7043ce4
commit
6301bc713c
@ -1,6 +1,6 @@
|
|||||||
import { consume } from "@lit-labs/context";
|
import { consume } from "@lit-labs/context";
|
||||||
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
import "@lrnwebcomponents/simple-tooltip/simple-tooltip";
|
||||||
import { mdiPlus } from "@mdi/js";
|
import { mdiChevronRight, mdiMenuDown, mdiPlus } from "@mdi/js";
|
||||||
import {
|
import {
|
||||||
CSSResultGroup,
|
CSSResultGroup,
|
||||||
LitElement,
|
LitElement,
|
||||||
@ -13,6 +13,7 @@ import {
|
|||||||
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
import { UnsubscribeFunc } from "home-assistant-js-websocket";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
|
import { computeCssColor } from "../../../common/color/compute-color";
|
||||||
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
import { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||||
import {
|
import {
|
||||||
@ -24,6 +25,7 @@ import { LocalizeFunc } from "../../../common/translations/localize";
|
|||||||
import {
|
import {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
RowClickedEvent,
|
RowClickedEvent,
|
||||||
|
SelectionChangedEvent,
|
||||||
} from "../../../components/data-table/ha-data-table";
|
} from "../../../components/data-table/ha-data-table";
|
||||||
import "../../../components/data-table/ha-data-table-labels";
|
import "../../../components/data-table/ha-data-table-labels";
|
||||||
import "../../../components/entity/ha-battery-icon";
|
import "../../../components/entity/ha-battery-icon";
|
||||||
@ -37,12 +39,15 @@ import "../../../components/ha-filter-integrations";
|
|||||||
import "../../../components/ha-filter-labels";
|
import "../../../components/ha-filter-labels";
|
||||||
import "../../../components/ha-filter-states";
|
import "../../../components/ha-filter-states";
|
||||||
import "../../../components/ha-icon-button";
|
import "../../../components/ha-icon-button";
|
||||||
|
import "../../../components/ha-menu-item";
|
||||||
|
import "../../../components/ha-sub-menu";
|
||||||
import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries";
|
import { ConfigEntry, sortConfigEntries } from "../../../data/config_entries";
|
||||||
import { fullEntitiesContext } from "../../../data/context";
|
import { fullEntitiesContext } from "../../../data/context";
|
||||||
import {
|
import {
|
||||||
DeviceEntityLookup,
|
DeviceEntityLookup,
|
||||||
DeviceRegistryEntry,
|
DeviceRegistryEntry,
|
||||||
computeDeviceName,
|
computeDeviceName,
|
||||||
|
updateDeviceRegistryEntry,
|
||||||
} from "../../../data/device_registry";
|
} from "../../../data/device_registry";
|
||||||
import {
|
import {
|
||||||
EntityRegistryEntry,
|
EntityRegistryEntry,
|
||||||
@ -91,6 +96,8 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
|
|
||||||
@state() private _searchParms = new URLSearchParams(window.location.search);
|
@state() private _searchParms = new URLSearchParams(window.location.search);
|
||||||
|
|
||||||
|
@state() private _selected: string[] = [];
|
||||||
|
|
||||||
@state() private _filter: string = history.state?.filter || "";
|
@state() private _filter: string = history.state?.filter || "";
|
||||||
|
|
||||||
@state() private _filters: Record<
|
@state() private _filters: Record<
|
||||||
@ -535,6 +542,21 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
this._labels
|
this._labels
|
||||||
);
|
);
|
||||||
|
|
||||||
|
const labelItems = html` ${this._labels?.map((label) => {
|
||||||
|
const color = label.color ? computeCssColor(label.color) : undefined;
|
||||||
|
return html`<ha-menu-item
|
||||||
|
.value=${label.label_id}
|
||||||
|
@click=${this._handleBulkLabel}
|
||||||
|
>
|
||||||
|
<ha-label style=${color ? `--color: ${color}` : ""}>
|
||||||
|
${label.icon
|
||||||
|
? html`<ha-icon slot="icon" .icon=${label.icon}></ha-icon>`
|
||||||
|
: nothing}
|
||||||
|
${label.name}
|
||||||
|
</ha-label>
|
||||||
|
</ha-menu-item>`;
|
||||||
|
})}`;
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<hass-tabs-subpage-data-table
|
<hass-tabs-subpage-data-table
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
@ -549,6 +571,9 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
)}
|
)}
|
||||||
.columns=${this._columns(this.hass.localize, this.narrow)}
|
.columns=${this._columns(this.hass.localize, this.narrow)}
|
||||||
.data=${devicesOutput}
|
.data=${devicesOutput}
|
||||||
|
selectable
|
||||||
|
.selected=${this._selected.length}
|
||||||
|
@selection-changed=${this._handleSelectionChanged}
|
||||||
.filter=${this._filter}
|
.filter=${this._filter}
|
||||||
hasFilters
|
hasFilters
|
||||||
.filters=${Object.values(this._filters).filter(
|
.filters=${Object.values(this._filters).filter(
|
||||||
@ -621,6 +646,49 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
@expanded-changed=${this._filterExpanded}
|
@expanded-changed=${this._filterExpanded}
|
||||||
></ha-filter-labels>
|
></ha-filter-labels>
|
||||||
|
|
||||||
|
${!this.narrow
|
||||||
|
? html`<ha-button-menu-new slot="selection-bar">
|
||||||
|
<ha-assist-chip
|
||||||
|
slot="trigger"
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.bulk_actions.add_label"
|
||||||
|
)}
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="trailing-icon"
|
||||||
|
.path=${mdiMenuDown}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</ha-assist-chip>
|
||||||
|
${labelItems}
|
||||||
|
</ha-button-menu-new>`
|
||||||
|
: html` <ha-button-menu-new has-overflow slot="selection-bar"
|
||||||
|
><ha-assist-chip
|
||||||
|
.label=${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.bulk_action"
|
||||||
|
)}
|
||||||
|
slot="trigger"
|
||||||
|
>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="trailing-icon"
|
||||||
|
.path=${mdiMenuDown}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</ha-assist-chip>
|
||||||
|
<ha-sub-menu>
|
||||||
|
<ha-menu-item slot="item">
|
||||||
|
<div slot="headline">
|
||||||
|
${this.hass.localize(
|
||||||
|
"ui.panel.config.automation.picker.bulk_actions.add_label"
|
||||||
|
)}
|
||||||
|
</div>
|
||||||
|
<ha-svg-icon
|
||||||
|
slot="end"
|
||||||
|
.path=${mdiChevronRight}
|
||||||
|
></ha-svg-icon>
|
||||||
|
</ha-menu-item>
|
||||||
|
<ha-menu slot="menu">${labelItems}</ha-menu>
|
||||||
|
</ha-sub-menu>
|
||||||
|
</ha-button-menu-new>`}
|
||||||
</hass-tabs-subpage-data-table>
|
</hass-tabs-subpage-data-table>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
@ -700,6 +768,25 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _handleSelectionChanged(
|
||||||
|
ev: HASSDomEvent<SelectionChangedEvent>
|
||||||
|
): void {
|
||||||
|
this._selected = ev.detail.value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _handleBulkLabel(ev) {
|
||||||
|
const label = ev.currentTarget.value;
|
||||||
|
const promises: Promise<DeviceRegistryEntry>[] = [];
|
||||||
|
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 {
|
static get styles(): CSSResultGroup {
|
||||||
return [
|
return [
|
||||||
css`
|
css`
|
||||||
@ -721,6 +808,16 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
|||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
direction: var(--direction);
|
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,
|
haStyle,
|
||||||
];
|
];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user