mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-27 11:16:35 +00:00
Use new entity naming in card entity picker (#25316)
This commit is contained in:
parent
9081441d95
commit
7434b12d9f
@ -4,11 +4,7 @@ import { css, html, LitElement, nothing } from "lit";
|
|||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { cache } from "lit/directives/cache";
|
import { cache } from "lit/directives/cache";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import memoize from "memoize-one";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
|
|
||||||
import "../../../../components/ha-dialog";
|
import "../../../../components/ha-dialog";
|
||||||
import "../../../../components/ha-dialog-header";
|
import "../../../../components/ha-dialog-header";
|
||||||
import "../../../../components/sl-tab-group";
|
import "../../../../components/sl-tab-group";
|
||||||
@ -137,7 +133,6 @@ export class HuiCreateDialogBadge
|
|||||||
no-label-float
|
no-label-float
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.narrow=${true}
|
.narrow=${true}
|
||||||
.entities=${this._allEntities(this.hass.states)}
|
|
||||||
@selected-changed=${this._handleSelectedChanged}
|
@selected-changed=${this._handleSelectedChanged}
|
||||||
></hui-entity-picker-table>
|
></hui-entity-picker-table>
|
||||||
`
|
`
|
||||||
@ -276,20 +271,6 @@ export class HuiCreateDialogBadge
|
|||||||
|
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _allEntities = memoize((entities) =>
|
|
||||||
Object.keys(entities).map((entity) => {
|
|
||||||
const stateObj = this.hass.states[entity];
|
|
||||||
return {
|
|
||||||
icon: "",
|
|
||||||
entity_id: entity,
|
|
||||||
stateObj,
|
|
||||||
name: computeStateName(stateObj),
|
|
||||||
domain: computeDomain(entity),
|
|
||||||
last_changed: stateObj!.last_changed,
|
|
||||||
} as DataTableRowData;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -5,11 +5,7 @@ import { customElement, property, state } from "lit/decorators";
|
|||||||
import { cache } from "lit/directives/cache";
|
import { cache } from "lit/directives/cache";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { ifDefined } from "lit/directives/if-defined";
|
import { ifDefined } from "lit/directives/if-defined";
|
||||||
import memoize from "memoize-one";
|
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
|
|
||||||
import "../../../../components/ha-dialog";
|
import "../../../../components/ha-dialog";
|
||||||
import "../../../../components/ha-dialog-header";
|
import "../../../../components/ha-dialog-header";
|
||||||
import "../../../../components/sl-tab-group";
|
import "../../../../components/sl-tab-group";
|
||||||
@ -157,7 +153,6 @@ export class HuiCreateDialogCard
|
|||||||
no-label-float
|
no-label-float
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
narrow
|
narrow
|
||||||
.entities=${this._allEntities(this.hass.states)}
|
|
||||||
@selected-changed=${this._handleSelectedChanged}
|
@selected-changed=${this._handleSelectedChanged}
|
||||||
></hui-entity-picker-table>
|
></hui-entity-picker-table>
|
||||||
`
|
`
|
||||||
@ -340,20 +335,6 @@ export class HuiCreateDialogCard
|
|||||||
|
|
||||||
this.closeDialog();
|
this.closeDialog();
|
||||||
}
|
}
|
||||||
|
|
||||||
private _allEntities = memoize((entities) =>
|
|
||||||
Object.keys(entities).map((entity) => {
|
|
||||||
const stateObj = this.hass.states[entity];
|
|
||||||
return {
|
|
||||||
icon: "",
|
|
||||||
entity_id: entity,
|
|
||||||
stateObj,
|
|
||||||
name: computeStateName(stateObj),
|
|
||||||
domain: computeDomain(entity),
|
|
||||||
last_changed: stateObj!.last_changed,
|
|
||||||
} as DataTableRowData;
|
|
||||||
})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
declare global {
|
declare global {
|
||||||
|
@ -1,9 +1,17 @@
|
|||||||
import type { TemplateResult } from "lit";
|
import type { PropertyValues, TemplateResult } from "lit";
|
||||||
import { css, html, LitElement } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property } from "lit/decorators";
|
import { customElement, property } from "lit/decorators";
|
||||||
|
import { styleMap } from "lit/directives/style-map";
|
||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
import type { HASSDomEvent } from "../../../../common/dom/fire_event";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
|
import { computeAreaName } from "../../../../common/entity/compute_area_name";
|
||||||
|
import { computeDeviceName } from "../../../../common/entity/compute_device_name";
|
||||||
|
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||||
|
import { computeEntityName } from "../../../../common/entity/compute_entity_name";
|
||||||
|
import { getEntityContext } from "../../../../common/entity/context/get_entity_context";
|
||||||
|
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||||
|
import { computeRTL } from "../../../../common/util/compute_rtl";
|
||||||
import "../../../../components/data-table/ha-data-table";
|
import "../../../../components/data-table/ha-data-table";
|
||||||
import type {
|
import type {
|
||||||
DataTableColumnContainer,
|
DataTableColumnContainer,
|
||||||
@ -12,8 +20,26 @@ import type {
|
|||||||
} from "../../../../components/data-table/ha-data-table";
|
} from "../../../../components/data-table/ha-data-table";
|
||||||
import "../../../../components/entity/state-badge";
|
import "../../../../components/entity/state-badge";
|
||||||
import "../../../../components/ha-relative-time";
|
import "../../../../components/ha-relative-time";
|
||||||
|
import { domainToName } from "../../../../data/integration";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
|
|
||||||
|
const ENTITY_ID_STYLE = styleMap({
|
||||||
|
fontFamily: "var(--ha-font-family-code)",
|
||||||
|
fontSize: "var(--ha-font-size-xs)",
|
||||||
|
});
|
||||||
|
|
||||||
|
interface EntityPickerTableRowData extends DataTableRowData {
|
||||||
|
icon: string;
|
||||||
|
entity_id: string;
|
||||||
|
stateObj: any;
|
||||||
|
name: string;
|
||||||
|
entity_name?: string;
|
||||||
|
device_name?: string;
|
||||||
|
area_name?: string;
|
||||||
|
domain_name: string;
|
||||||
|
last_changed: string;
|
||||||
|
}
|
||||||
|
|
||||||
@customElement("hui-entity-picker-table")
|
@customElement("hui-entity-picker-table")
|
||||||
export class HuiEntityPickerTable extends LitElement {
|
export class HuiEntityPickerTable extends LitElement {
|
||||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||||
@ -23,16 +49,69 @@ export class HuiEntityPickerTable extends LitElement {
|
|||||||
@property({ type: Boolean, attribute: "no-label-float" })
|
@property({ type: Boolean, attribute: "no-label-float" })
|
||||||
public noLabelFloat? = false;
|
public noLabelFloat? = false;
|
||||||
|
|
||||||
@property({ type: Array }) public entities!: DataTableRowData[];
|
@property({ type: Array }) public entities?: string[];
|
||||||
|
|
||||||
|
protected firstUpdated(_changedProperties: PropertyValues): void {
|
||||||
|
super.firstUpdated(_changedProperties);
|
||||||
|
this.hass.loadBackendTranslation("title");
|
||||||
|
}
|
||||||
|
|
||||||
|
private _data = memoizeOne(
|
||||||
|
(
|
||||||
|
states: HomeAssistant["states"],
|
||||||
|
localize: LocalizeFunc,
|
||||||
|
entities?: string[]
|
||||||
|
): EntityPickerTableRowData[] =>
|
||||||
|
(entities || Object.keys(states)).map<EntityPickerTableRowData>(
|
||||||
|
(entity) => {
|
||||||
|
const stateObj = this.hass.states[entity];
|
||||||
|
|
||||||
|
const { area, device } = getEntityContext(stateObj, this.hass);
|
||||||
|
|
||||||
|
const entityName = computeEntityName(stateObj, this.hass);
|
||||||
|
const deviceName = device ? computeDeviceName(device) : undefined;
|
||||||
|
const areaName = area ? computeAreaName(area) : undefined;
|
||||||
|
const name = [deviceName, entityName].filter(Boolean).join(" ");
|
||||||
|
const domain = computeDomain(entity);
|
||||||
|
|
||||||
|
return {
|
||||||
|
icon: "",
|
||||||
|
entity_id: entity,
|
||||||
|
stateObj,
|
||||||
|
name: name,
|
||||||
|
entity_name: entityName,
|
||||||
|
device_name: deviceName,
|
||||||
|
area_name: areaName,
|
||||||
|
domain_name: domainToName(localize, domain),
|
||||||
|
last_changed: stateObj!.last_changed,
|
||||||
|
} satisfies EntityPickerTableRowData;
|
||||||
|
}
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
protected render(): TemplateResult {
|
protected render(): TemplateResult {
|
||||||
|
const data = this._data(
|
||||||
|
this.hass.states,
|
||||||
|
this.hass.localize,
|
||||||
|
this.entities
|
||||||
|
);
|
||||||
|
|
||||||
|
const showEntityId = Boolean(this.hass.userData?.showEntityIdPicker);
|
||||||
|
|
||||||
|
const columns = this._columns(
|
||||||
|
this.narrow,
|
||||||
|
computeRTL(this.hass),
|
||||||
|
showEntityId
|
||||||
|
);
|
||||||
|
|
||||||
return html`
|
return html`
|
||||||
<ha-data-table
|
<ha-data-table
|
||||||
|
class=${showEntityId ? "show-entity-id" : ""}
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
selectable
|
selectable
|
||||||
.id=${"entity_id"}
|
.id=${"entity_id"}
|
||||||
.columns=${this._columns(this.narrow!)}
|
.columns=${columns}
|
||||||
.data=${this.entities}
|
.data=${data}
|
||||||
.searchLabel=${this.hass.localize(
|
.searchLabel=${this.hass.localize(
|
||||||
"ui.panel.lovelace.unused_entities.search"
|
"ui.panel.lovelace.unused_entities.search"
|
||||||
)}
|
)}
|
||||||
@ -45,7 +124,8 @@ export class HuiEntityPickerTable extends LitElement {
|
|||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
private _columns = memoizeOne((narrow: boolean) => {
|
private _columns = memoizeOne(
|
||||||
|
(narrow: boolean, isRTL: boolean, showEntityId: boolean) => {
|
||||||
const columns: DataTableColumnContainer = {
|
const columns: DataTableColumnContainer = {
|
||||||
icon: {
|
icon: {
|
||||||
title: "",
|
title: "",
|
||||||
@ -62,35 +142,74 @@ export class HuiEntityPickerTable extends LitElement {
|
|||||||
`,
|
`,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity"),
|
title: this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.unused_entities.entity"
|
||||||
|
),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
flex: 2,
|
flex: 2,
|
||||||
main: true,
|
main: true,
|
||||||
direction: "asc",
|
direction: "asc",
|
||||||
template: (entity: any) => html`
|
template: (entity: any) => {
|
||||||
|
const primary =
|
||||||
|
entity.entity_name || entity.device_name || entity.entity_id;
|
||||||
|
const secondary = [
|
||||||
|
entity.area_name,
|
||||||
|
entity.entity_name ? entity.device_name : undefined,
|
||||||
|
]
|
||||||
|
.filter(Boolean)
|
||||||
|
.join(isRTL ? " ◂ " : " ▸ ");
|
||||||
|
return html`
|
||||||
<div @click=${this._handleEntityClicked} style="cursor: pointer;">
|
<div @click=${this._handleEntityClicked} style="cursor: pointer;">
|
||||||
${entity.name}
|
${primary}
|
||||||
${narrow
|
${secondary
|
||||||
? html` <div class="secondary">${entity.entity_id}</div> `
|
? html`<div class="secondary">${secondary}</div>`
|
||||||
: ""}
|
: nothing}
|
||||||
|
${narrow && showEntityId
|
||||||
|
? html`
|
||||||
|
<div class="secondary" style=${ENTITY_ID_STYLE}>
|
||||||
|
${entity.entity_id}
|
||||||
</div>
|
</div>
|
||||||
`,
|
`
|
||||||
|
: nothing}
|
||||||
|
</div>
|
||||||
|
`;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
columns.entity_id = {
|
columns.entity_name = {
|
||||||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.entity_id"),
|
title: "entity_name",
|
||||||
sortable: true,
|
|
||||||
filterable: true,
|
filterable: true,
|
||||||
hidden: narrow,
|
hidden: true,
|
||||||
};
|
};
|
||||||
|
|
||||||
columns.domain = {
|
columns.device_name = {
|
||||||
|
title: "device_name",
|
||||||
|
filterable: true,
|
||||||
|
hidden: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
columns.area_name = {
|
||||||
|
title: "area_name",
|
||||||
|
filterable: true,
|
||||||
|
hidden: true,
|
||||||
|
};
|
||||||
|
|
||||||
|
columns.entity_id = {
|
||||||
|
title: this.hass!.localize(
|
||||||
|
"ui.panel.lovelace.unused_entities.entity_id"
|
||||||
|
),
|
||||||
|
sortable: true,
|
||||||
|
filterable: true,
|
||||||
|
hidden: narrow || !showEntityId,
|
||||||
|
};
|
||||||
|
|
||||||
|
columns.domain_name = {
|
||||||
title: this.hass!.localize("ui.panel.lovelace.unused_entities.domain"),
|
title: this.hass!.localize("ui.panel.lovelace.unused_entities.domain"),
|
||||||
sortable: true,
|
sortable: true,
|
||||||
filterable: true,
|
filterable: true,
|
||||||
hidden: narrow,
|
hidden: narrow || showEntityId,
|
||||||
};
|
};
|
||||||
|
|
||||||
columns.last_changed = {
|
columns.last_changed = {
|
||||||
@ -110,7 +229,8 @@ export class HuiEntityPickerTable extends LitElement {
|
|||||||
};
|
};
|
||||||
|
|
||||||
return columns;
|
return columns;
|
||||||
});
|
}
|
||||||
|
);
|
||||||
|
|
||||||
private _handleSelectionChanged(
|
private _handleSelectionChanged(
|
||||||
ev: HASSDomEvent<SelectionChangedEvent>
|
ev: HASSDomEvent<SelectionChangedEvent>
|
||||||
@ -134,6 +254,9 @@ export class HuiEntityPickerTable extends LitElement {
|
|||||||
--data-table-border-width: 0;
|
--data-table-border-width: 0;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
}
|
}
|
||||||
|
ha-data-table.show-entity-id {
|
||||||
|
--data-table-row-height: 64px;
|
||||||
|
}
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,22 +3,19 @@ import type { PropertyValues } from "lit";
|
|||||||
import { css, html, LitElement, nothing } from "lit";
|
import { css, html, LitElement, nothing } from "lit";
|
||||||
import { customElement, property, state } from "lit/decorators";
|
import { customElement, property, state } from "lit/decorators";
|
||||||
import { classMap } from "lit/directives/class-map";
|
import { classMap } from "lit/directives/class-map";
|
||||||
import { computeDomain } from "../../../../common/entity/compute_domain";
|
|
||||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
|
||||||
import type { DataTableRowData } from "../../../../components/data-table/ha-data-table";
|
|
||||||
import "../../../../components/ha-fab";
|
import "../../../../components/ha-fab";
|
||||||
import "../../../../components/ha-svg-icon";
|
import "../../../../components/ha-svg-icon";
|
||||||
|
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
||||||
import type { HomeAssistant } from "../../../../types";
|
import type { HomeAssistant } from "../../../../types";
|
||||||
import { computeUnusedEntities } from "../../common/compute-unused-entities";
|
import { computeUnusedEntities } from "../../common/compute-unused-entities";
|
||||||
import type { Lovelace } from "../../types";
|
|
||||||
import "../card-editor/hui-entity-picker-table";
|
|
||||||
import { showSuggestCardDialog } from "../card-editor/show-suggest-card-dialog";
|
|
||||||
import { showSelectViewDialog } from "../select-view/show-select-view-dialog";
|
|
||||||
import type { LovelaceConfig } from "../../../../data/lovelace/config/types";
|
|
||||||
import {
|
import {
|
||||||
computeCards,
|
computeCards,
|
||||||
computeSection,
|
computeSection,
|
||||||
} from "../../common/generate-lovelace-config";
|
} from "../../common/generate-lovelace-config";
|
||||||
|
import type { Lovelace } from "../../types";
|
||||||
|
import "../card-editor/hui-entity-picker-table";
|
||||||
|
import { showSuggestCardDialog } from "../card-editor/show-suggest-card-dialog";
|
||||||
|
import { showSelectViewDialog } from "../select-view/show-select-view-dialog";
|
||||||
|
|
||||||
@customElement("hui-unused-entities")
|
@customElement("hui-unused-entities")
|
||||||
export class HuiUnusedEntities extends LitElement {
|
export class HuiUnusedEntities extends LitElement {
|
||||||
@ -80,17 +77,7 @@ export class HuiUnusedEntities extends LitElement {
|
|||||||
<hui-entity-picker-table
|
<hui-entity-picker-table
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.narrow=${this.narrow}
|
.narrow=${this.narrow}
|
||||||
.entities=${this._unusedEntities.map((entity) => {
|
.entities=${this._unusedEntities}
|
||||||
const stateObj = this.hass!.states[entity];
|
|
||||||
return {
|
|
||||||
icon: "",
|
|
||||||
entity_id: entity,
|
|
||||||
stateObj,
|
|
||||||
name: stateObj ? computeStateName(stateObj) : "Unavailable",
|
|
||||||
domain: computeDomain(entity),
|
|
||||||
last_changed: stateObj?.last_changed,
|
|
||||||
};
|
|
||||||
}) as DataTableRowData[]}
|
|
||||||
@selected-changed=${this._handleSelectedChanged}
|
@selected-changed=${this._handleSelectedChanged}
|
||||||
></hui-entity-picker-table>
|
></hui-entity-picker-table>
|
||||||
</div>
|
</div>
|
||||||
|
Loading…
x
Reference in New Issue
Block a user