Add labels on devices datatable (#20275)

This commit is contained in:
Paul Bottein 2024-03-29 18:46:34 +01:00 committed by GitHub
parent 1dba049038
commit 3a6382df55
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -10,6 +10,7 @@ import {
nothing, nothing,
} from "lit"; } from "lit";
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 { HASSDomEvent } from "../../../common/dom/fire_event"; import { HASSDomEvent } from "../../../common/dom/fire_event";
@ -24,17 +25,18 @@ import {
DataTableColumnContainer, DataTableColumnContainer,
RowClickedEvent, RowClickedEvent,
} from "../../../components/data-table/ha-data-table"; } from "../../../components/data-table/ha-data-table";
import "../../../components/data-table/ha-data-table-labels";
import "../../../components/entity/ha-battery-icon"; import "../../../components/entity/ha-battery-icon";
import "../../../components/ha-alert";
import "../../../components/ha-button-menu"; import "../../../components/ha-button-menu";
import "../../../components/ha-check-list-item"; import "../../../components/ha-check-list-item";
import "../../../components/ha-fab"; import "../../../components/ha-fab";
import "../../../components/ha-filter-devices"; import "../../../components/ha-filter-devices";
import "../../../components/ha-filter-floor-areas"; import "../../../components/ha-filter-floor-areas";
import "../../../components/ha-filter-integrations"; import "../../../components/ha-filter-integrations";
import "../../../components/ha-filter-states";
import "../../../components/ha-filter-labels"; import "../../../components/ha-filter-labels";
import "../../../components/ha-filter-states";
import "../../../components/ha-icon-button"; import "../../../components/ha-icon-button";
import "../../../components/ha-alert";
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 {
@ -48,7 +50,12 @@ import {
findBatteryEntity, findBatteryEntity,
} from "../../../data/entity_registry"; } from "../../../data/entity_registry";
import { IntegrationManifest } from "../../../data/integration"; import { IntegrationManifest } from "../../../data/integration";
import {
LabelRegistryEntry,
subscribeLabelRegistry,
} from "../../../data/label_registry";
import "../../../layouts/hass-tabs-subpage-data-table"; import "../../../layouts/hass-tabs-subpage-data-table";
import { SubscribeMixin } from "../../../mixins/subscribe-mixin";
import { haStyle } from "../../../resources/styles"; import { haStyle } from "../../../resources/styles";
import { HomeAssistant, Route } from "../../../types"; import { HomeAssistant, Route } from "../../../types";
import { brandsUrl } from "../../../util/brands-url"; import { brandsUrl } from "../../../util/brands-url";
@ -61,10 +68,11 @@ interface DeviceRowData extends DeviceRegistryEntry {
area?: string; area?: string;
integration?: string; integration?: string;
battery_entity?: [string | undefined, string | undefined]; battery_entity?: [string | undefined, string | undefined];
label_entries: EntityRegistryEntry[];
} }
@customElement("ha-config-devices-dashboard") @customElement("ha-config-devices-dashboard")
export class HaConfigDeviceDashboard extends LitElement { export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property({ type: Boolean }) public narrow = false; @property({ type: Boolean }) public narrow = false;
@ -92,6 +100,9 @@ export class HaConfigDeviceDashboard extends LitElement {
@state() private _expandedFilter?: string; @state() private _expandedFilter?: string;
@state()
_labels!: LabelRegistryEntry[];
private _ignoreLocationChange = false; private _ignoreLocationChange = false;
public connectedCallback() { public connectedCallback() {
@ -191,11 +202,17 @@ export class HaConfigDeviceDashboard extends LitElement {
string, string,
{ value: string[] | undefined; items: Set<string> | undefined } { value: string[] | undefined; items: Set<string> | undefined }
>, >,
localize: LocalizeFunc localize: LocalizeFunc,
labelReg?: LabelRegistryEntry[]
) => { ) => {
// Some older installations might have devices pointing at invalid entryIDs // Some older installations might have devices pointing at invalid entryIDs
// So we guard for that. // So we guard for that.
let outputDevices: DeviceRowData[] = Object.values(devices); let outputDevices: DeviceRowData[] = Object.values(devices).map(
(device) => ({
...device,
label_entries: [],
})
);
const deviceEntityLookup: DeviceEntityLookup = {}; const deviceEntityLookup: DeviceEntityLookup = {};
for (const entity of entities) { for (const entity of entities) {
@ -275,6 +292,12 @@ export class HaConfigDeviceDashboard extends LitElement {
.map((entId) => entryLookup[entId]), .map((entId) => entryLookup[entId]),
manifestLookup manifestLookup
); );
const labels = labelReg && device?.labels;
const labelsEntries = (labels || []).map(
(lbl) => labelReg!.find((label) => label.label_id === lbl)!
);
return { return {
...device, ...device,
name: computeDeviceName( name: computeDeviceName(
@ -311,6 +334,7 @@ export class HaConfigDeviceDashboard extends LitElement {
this.hass.states[ this.hass.states[
this._batteryEntity(device.id, deviceEntityLookup) || "" this._batteryEntity(device.id, deviceEntityLookup) || ""
]?.state, ]?.state,
label_entries: labelsEntries,
}; };
}); });
@ -356,8 +380,15 @@ export class HaConfigDeviceDashboard extends LitElement {
direction: "asc", direction: "asc",
grows: true, grows: true,
template: (device) => html` template: (device) => html`
${device.name} <div style="font-size: 14px;">${device.name}</div>
<div class="secondary">${device.area} | ${device.integration}</div> <div class="secondary">${device.area} | ${device.integration}</div>
${device.label_entries.length
? html`
<ha-data-table-labels
.labels=${device.label_entries}
></ha-data-table-labels>
`
: nothing}
`, `,
}; };
} else { } else {
@ -366,8 +397,18 @@ export class HaConfigDeviceDashboard extends LitElement {
main: true, main: true,
sortable: true, sortable: true,
filterable: true, filterable: true,
grows: true,
direction: "asc", direction: "asc",
grows: true,
template: (device) => html`
<div style="font-size: 14px;">${device.name}</div>
${device.label_entries.length
? html`
<ha-data-table-labels
.labels=${device.label_entries}
></ha-data-table-labels>
`
: nothing}
`,
}; };
} }
@ -446,9 +487,25 @@ export class HaConfigDeviceDashboard extends LitElement {
? this.hass.localize("ui.panel.config.devices.disabled") ? this.hass.localize("ui.panel.config.devices.disabled")
: "", : "",
}; };
columns.labels = {
title: "",
hidden: true,
filterable: true,
template: (device) =>
device.label_entries.map((lbl) => lbl.name).join(" "),
};
return columns; return columns;
}); });
protected hassSubscribe(): (UnsubscribeFunc | Promise<UnsubscribeFunc>)[] {
return [
subscribeLabelRegistry(this.hass.connection, (labels) => {
this._labels = labels;
}),
];
}
protected render(): TemplateResult { protected render(): TemplateResult {
const { devicesOutput } = this._devicesAndFilterDomains( const { devicesOutput } = this._devicesAndFilterDomains(
this.hass.devices, this.hass.devices,
@ -457,7 +514,8 @@ export class HaConfigDeviceDashboard extends LitElement {
this.hass.areas, this.hass.areas,
this.manifests, this.manifests,
this._filters, this._filters,
this.hass.localize this.hass.localize,
this._labels
); );
return html` return html`
@ -484,6 +542,7 @@ export class HaConfigDeviceDashboard extends LitElement {
@row-click=${this._handleRowClicked} @row-click=${this._handleRowClicked}
clickable clickable
hasFab hasFab
class=${this.narrow ? "narrow" : ""}
> >
<ha-integration-overflow-menu <ha-integration-overflow-menu
.hass=${this.hass} .hass=${this.hass}
@ -604,8 +663,10 @@ export class HaConfigDeviceDashboard extends LitElement {
this.hass.areas, this.hass.areas,
this.manifests, this.manifests,
this._filters, this._filters,
this.hass.localize this.hass.localize,
this._labels
); );
if ( if (
filteredDomains.size === 1 && filteredDomains.size === 1 &&
(PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes( (PROTOCOL_INTEGRATIONS as ReadonlyArray<string>).includes(
@ -625,6 +686,12 @@ export class HaConfigDeviceDashboard extends LitElement {
static get styles(): CSSResultGroup { static get styles(): CSSResultGroup {
return [ return [
css` css`
hass-tabs-subpage-data-table {
--data-table-row-height: 60px;
}
hass-tabs-subpage-data-table.narrow {
--data-table-row-height: 72px;
}
ha-button-menu { ha-button-menu {
margin-left: 8px; margin-left: 8px;
margin-inline-start: 8px; margin-inline-start: 8px;