mirror of
https://github.com/home-assistant/frontend.git
synced 2026-04-02 00:27:49 +01:00
Replace computeLovelaceEntityName with hass.formatEntityName (#30351)
This commit is contained in:
committed by
Bram Kragten
parent
0f9d48a03d
commit
1132cdb364
@@ -29,14 +29,18 @@ export interface EntityNameOptions {
|
||||
|
||||
export const computeEntityNameDisplay = (
|
||||
stateObj: HassEntity,
|
||||
name: EntityNameItem | EntityNameItem[] | undefined,
|
||||
name: string | EntityNameItem | EntityNameItem[] | undefined,
|
||||
entities: HomeAssistant["entities"],
|
||||
devices: HomeAssistant["devices"],
|
||||
areas: HomeAssistant["areas"],
|
||||
floors: HomeAssistant["floors"],
|
||||
options?: EntityNameOptions
|
||||
) => {
|
||||
let items = ensureArray(name || DEFAULT_ENTITY_NAME);
|
||||
if (typeof name === "string") {
|
||||
return name;
|
||||
}
|
||||
|
||||
let items = ensureArray(name ?? DEFAULT_ENTITY_NAME);
|
||||
|
||||
const separator = options?.separator ?? DEFAULT_SEPARATOR;
|
||||
|
||||
|
||||
@@ -19,7 +19,6 @@ import { cameraUrlWithWidthHeight } from "../../../data/camera";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -175,11 +174,7 @@ export class HuiEntityBadge extends LitElement implements LovelaceBadge {
|
||||
"--badge-color": color,
|
||||
};
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const stateDisplay = html`
|
||||
<state-display
|
||||
|
||||
@@ -28,7 +28,6 @@ import {
|
||||
subscribeEntityRegistry,
|
||||
} from "../../../data/entity/entity_registry";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type { LovelaceCard } from "../types";
|
||||
@@ -233,11 +232,7 @@ class HuiAlarmPanelCard extends LitElement implements LovelaceCard {
|
||||
|
||||
const defaultCode = this._entry?.options?.alarm_control_panel?.default_code;
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<ha-card>
|
||||
|
||||
@@ -41,7 +41,6 @@ import type { FrontendLocaleData } from "../../../data/translation";
|
||||
import type { Themes } from "../../../data/ws-themes";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasAction } from "../common/has-action";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -52,6 +51,21 @@ import type {
|
||||
} from "../types";
|
||||
import type { ButtonCardConfig } from "./types";
|
||||
|
||||
const EMPTY_STATE_OBJ = {
|
||||
state: "unavailable",
|
||||
attributes: {
|
||||
friendly_name: "",
|
||||
},
|
||||
entity_id: "___.empty",
|
||||
context: {
|
||||
id: "",
|
||||
parent_id: null,
|
||||
user_id: null,
|
||||
},
|
||||
last_changed: "",
|
||||
last_updated: "",
|
||||
} satisfies HassEntity;
|
||||
|
||||
export const getEntityDefaultButtonAction = (entityId?: string) =>
|
||||
entityId && DOMAINS_TOGGLE.has(computeDomain(entityId))
|
||||
? "toggle"
|
||||
@@ -183,9 +197,8 @@ export class HuiButtonCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
const name = this.hass.formatEntityName(
|
||||
stateObj || EMPTY_STATE_OBJ,
|
||||
this._config.name
|
||||
);
|
||||
|
||||
|
||||
@@ -12,7 +12,6 @@ import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { normalizeValueBySIPrefix } from "../../../common/number/normalize-by-si-prefix";
|
||||
import { MobileAwareMixin } from "../../../mixins/mobile-aware-mixin";
|
||||
import type { EntityNameItem } from "../../../common/entity/compute_entity_name_display";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import "../../../components/chips/ha-assist-chip";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-segmented-bar";
|
||||
@@ -240,7 +239,7 @@ export class HuiDistributionCard
|
||||
const color = entity.color
|
||||
? computeCssColor(entity.color)
|
||||
: getGraphColorByIndex(entity.originalIndex, computedStyles);
|
||||
const name = computeLovelaceEntityName(this.hass!, stateObj, entity.name);
|
||||
const name = this.hass!.formatEntityName(stateObj, entity.name);
|
||||
const formattedValue = this.hass!.formatEntityState(stateObj);
|
||||
|
||||
segments.push({
|
||||
@@ -276,7 +275,7 @@ export class HuiDistributionCard
|
||||
const isZeroOrNegative = !stateObj || value <= 0 || isNaN(value);
|
||||
|
||||
const name = stateObj
|
||||
? computeLovelaceEntityName(this.hass!, stateObj, entity.name)
|
||||
? this.hass!.formatEntityName(stateObj, entity.name)
|
||||
: entity.entity;
|
||||
|
||||
const formattedValue = stateObj
|
||||
|
||||
@@ -25,7 +25,6 @@ import { handleAction } from "../common/handle-action";
|
||||
import { hasAction, hasAnyAction } from "../common/has-action";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -146,11 +145,7 @@ export class HuiEntityCard extends LitElement implements LovelaceCard {
|
||||
const indexValue = stateParts.findIndex((part) => part.type === "value");
|
||||
const reversedOrder = indexUnit !== -1 && indexUnit < indexValue;
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const colored = stateObj && this._getStateColor(stateObj, this._config);
|
||||
|
||||
|
||||
@@ -14,7 +14,6 @@ import { UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction, hasAnyAction } from "../common/has-action";
|
||||
@@ -124,11 +123,7 @@ class HuiGaugeCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
// Use `stateObj.state` as value to keep formatting (e.g trailing zeros)
|
||||
// for consistent value display across gauge, entity, entity-row, etc.
|
||||
|
||||
@@ -18,7 +18,6 @@ import type {
|
||||
import { SENSOR_DEVICE_CLASS_TIMESTAMP } from "../../../data/sensor";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction, hasAnyAction } from "../common/has-action";
|
||||
@@ -252,11 +251,7 @@ export class HuiGlanceCard extends LitElement implements LovelaceCard {
|
||||
</div>`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
entityConf.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, entityConf.name);
|
||||
|
||||
return html`
|
||||
<div
|
||||
|
||||
@@ -19,7 +19,6 @@ import {
|
||||
import { fetchStatistics } from "../../../data/recorder";
|
||||
import { getSensorNumericDeviceClasses } from "../../../data/sensor";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntitiesChanged } from "../common/has-changed";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
import type { EntityConfig } from "../entity-rows/types";
|
||||
@@ -106,7 +105,7 @@ export class HuiHistoryGraphCard extends LitElement implements LovelaceCard {
|
||||
this._entities.forEach((entity) => {
|
||||
const stateObj = this.hass!.states[entity.entity];
|
||||
this._names[entity.entity] = stateObj
|
||||
? computeLovelaceEntityName(this.hass!, stateObj, entity.name)
|
||||
? this.hass!.formatEntityName(stateObj, entity.name)
|
||||
: entity.entity;
|
||||
});
|
||||
}
|
||||
|
||||
@@ -14,7 +14,6 @@ import "../../../state-control/humidifier/ha-state-control-humidifier-humidity";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "../card-features/hui-card-features";
|
||||
import type { LovelaceCardFeatureContext } from "../card-features/types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type {
|
||||
@@ -133,11 +132,7 @@ export class HuiHumidifierCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const color = stateColorCss(stateObj);
|
||||
|
||||
|
||||
@@ -17,7 +17,6 @@ import { lightSupportsBrightness } from "../../../data/light";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -92,11 +91,7 @@ export class HuiLightCard extends LitElement implements LovelaceCard {
|
||||
((stateObj.attributes.brightness || 0) / 255) * 100
|
||||
);
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<ha-card>
|
||||
|
||||
@@ -36,7 +36,6 @@ import {
|
||||
mediaPlayerPlayMedia,
|
||||
} from "../../../data/media-player";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-marquee";
|
||||
@@ -242,8 +241,7 @@ export class HuiMediaControlCard extends LitElement implements LovelaceCard {
|
||||
.hass=${this.hass}
|
||||
></ha-state-icon>
|
||||
<div>
|
||||
${computeLovelaceEntityName(
|
||||
this.hass,
|
||||
${this.hass.formatEntityName(
|
||||
this.hass!.states[this._config!.entity],
|
||||
this._config.name
|
||||
)}
|
||||
|
||||
@@ -13,7 +13,6 @@ import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { PersonEntity } from "../../../data/person";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -126,11 +125,7 @@ class HuiPictureEntityCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
const entityState = this.hass.formatEntityState(stateObj);
|
||||
|
||||
let footer: TemplateResult | string = "";
|
||||
|
||||
@@ -15,7 +15,6 @@ import "../../../components/ha-card";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -119,7 +118,7 @@ class HuiPlantStatusCard extends LitElement implements LovelaceCard {
|
||||
style="background-image:url(${stateObj.attributes.entity_picture})"
|
||||
>
|
||||
<div class="header">
|
||||
${computeLovelaceEntityName(this.hass, stateObj, this._config.name)}
|
||||
${this.hass.formatEntityName(stateObj, this._config.name)}
|
||||
</div>
|
||||
</div>
|
||||
<div class="content">
|
||||
|
||||
@@ -23,7 +23,6 @@ import {
|
||||
} from "../../../data/recorder";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeCardSize } from "../common/compute-card-size";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import { createHeaderFooterElement } from "../create-element/create-header-footer-element";
|
||||
@@ -200,7 +199,7 @@ export class HuiStatisticCard extends LitElement implements LovelaceCard {
|
||||
const stateObj = this.hass.states[this._config.entity];
|
||||
const name =
|
||||
(this._config.name
|
||||
? computeLovelaceEntityName(this.hass, stateObj, this._config.name)
|
||||
? this.hass.formatEntityName(stateObj, this._config.name)
|
||||
: "") ||
|
||||
getStatisticLabel(this.hass, this._config.entity, this._metadata);
|
||||
|
||||
|
||||
@@ -24,7 +24,6 @@ import {
|
||||
getStatisticMetadata,
|
||||
} from "../../../data/recorder";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { hasConfigOrEntitiesChanged } from "../common/has-changed";
|
||||
import { processConfigEntities } from "../common/process-config-entities";
|
||||
@@ -189,8 +188,7 @@ export class HuiStatisticsGraphCard extends LitElement implements LovelaceCard {
|
||||
this._entities.forEach((config) => {
|
||||
const stateObj = this.hass!.states[config.entity];
|
||||
this._names[config.entity] =
|
||||
computeLovelaceEntityName(this.hass!, stateObj, config.name) ||
|
||||
config.entity;
|
||||
this.hass!.formatEntityName(stateObj, config.name) || config.entity;
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -15,7 +15,6 @@ import "../../../state-control/water_heater/ha-state-control-water_heater-temper
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "../card-features/hui-card-features";
|
||||
import type { LovelaceCardFeatureContext } from "../card-features/types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
import type {
|
||||
@@ -132,11 +131,7 @@ export class HuiThermostatCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
const domain = computeDomain(stateObj.entity_id);
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const color = stateColorCss(stateObj);
|
||||
|
||||
|
||||
@@ -23,7 +23,6 @@ import "../../../state-display/state-display";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import "../card-features/hui-card-features";
|
||||
import type { LovelaceCardFeatureContext } from "../card-features/types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -252,11 +251,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const active = stateActive(stateObj);
|
||||
const color = this._computeStateColor(stateObj, this._config.color);
|
||||
|
||||
@@ -29,7 +29,6 @@ import {
|
||||
} from "../../../data/weather";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -231,7 +230,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
return html`
|
||||
<ha-card class="unavailable" @click=${this._handleAction}>
|
||||
${this.hass.localize("ui.panel.lovelace.warning.entity_unavailable", {
|
||||
entity: `${computeLovelaceEntityName(this.hass, stateObj, this._config.name)} (${this._config.entity})`,
|
||||
entity: `${this.hass.formatEntityName(stateObj, this._config.name)} (${this._config.entity})`,
|
||||
})}
|
||||
</ha-card>
|
||||
`;
|
||||
@@ -262,11 +261,7 @@ class HuiWeatherForecastCard extends LitElement implements LovelaceCard {
|
||||
const dayNight = forecastData?.type === "twice_daily";
|
||||
|
||||
const weatherStateIcon = getWeatherStateIcon(stateObj.state, this);
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
const temperatureFractionDigits = this._config.round_temperature
|
||||
? 0
|
||||
|
||||
@@ -155,7 +155,7 @@ export interface AreaCardConfig extends LovelaceCardConfig {
|
||||
|
||||
export interface ButtonCardConfig extends LovelaceCardConfig {
|
||||
entity?: string;
|
||||
name?: string;
|
||||
name?: string | EntityNameItem | EntityNameItem[];
|
||||
show_name?: boolean;
|
||||
icon?: string;
|
||||
icon_height?: string;
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { ensureArray } from "../../../../common/array/ensure-array";
|
||||
import {
|
||||
DEFAULT_ENTITY_NAME,
|
||||
type EntityNameItem,
|
||||
} from "../../../../common/entity/compute_entity_name_display";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
|
||||
/**
|
||||
* Computes the display name for an entity in Lovelace (cards and badges).
|
||||
*
|
||||
* @param hass - The Home Assistant instance
|
||||
* @param stateObj - The entity state object
|
||||
* @param config - The name configuration (string for override, or EntityNameItem[] for structured naming)
|
||||
* @returns The computed entity name
|
||||
*/
|
||||
export const computeLovelaceEntityName = (
|
||||
hass: HomeAssistant,
|
||||
stateObj: HassEntity | undefined,
|
||||
config: string | EntityNameItem | EntityNameItem[] | undefined
|
||||
): string => {
|
||||
if (typeof config === "string") {
|
||||
return config;
|
||||
}
|
||||
if (stateObj) {
|
||||
return hass.formatEntityName(stateObj, config ?? DEFAULT_ENTITY_NAME);
|
||||
}
|
||||
if (!config) {
|
||||
return "";
|
||||
}
|
||||
// If entity is not found, fall back to text parts in config
|
||||
// This allows for static names even when the entity is missing
|
||||
// e.g. for a card that doesn't require an entity
|
||||
const textParts = ensureArray(config)
|
||||
.filter((item) => item.type === "text")
|
||||
.map((item) => ("text" in item ? item.text : ""));
|
||||
if (textParts.length) {
|
||||
return textParts.join(" ");
|
||||
}
|
||||
return "";
|
||||
};
|
||||
@@ -32,7 +32,6 @@ import type {
|
||||
} from "../cards/types";
|
||||
import type { EntityConfig } from "../entity-rows/types";
|
||||
import type { ButtonsHeaderFooterConfig } from "../header-footer/types";
|
||||
import { computeLovelaceEntityName } from "./entity/compute-lovelace-entity-name";
|
||||
|
||||
const HIDE_DOMAIN = new Set([
|
||||
"ai_task",
|
||||
@@ -271,14 +270,14 @@ export const computeCards = (
|
||||
? computeStateName(states[a])
|
||||
: ""
|
||||
: states[a.entity]
|
||||
? computeLovelaceEntityName(hass, states[a.entity], a.name)
|
||||
? hass.formatEntityName(states[a.entity], a.name)
|
||||
: "",
|
||||
typeof b === "string"
|
||||
? states[b]
|
||||
? computeStateName(states[b])
|
||||
: ""
|
||||
: states[b.entity]
|
||||
? computeLovelaceEntityName(hass, states[b.entity], b.name)
|
||||
? hass.formatEntityName(states[b.entity], b.name)
|
||||
: ""
|
||||
);
|
||||
});
|
||||
|
||||
@@ -18,7 +18,6 @@ import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { EntitiesCardEntityConfig } from "../cards/types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction, hasAnyAction } from "../common/has-action";
|
||||
import { createEntityNotFoundWarning } from "./hui-warning";
|
||||
@@ -66,11 +65,7 @@ export class HuiGenericEntityRow extends LitElement {
|
||||
const pointer = hasAnyAction(this.config);
|
||||
|
||||
const hasSecondary = this.secondaryText || this.config.secondary_info;
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this.config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this.config.name);
|
||||
|
||||
return html`
|
||||
<div
|
||||
|
||||
@@ -7,7 +7,6 @@ import "../../../components/ha-time-input";
|
||||
import { setDateTimeValue } from "../../../data/datetime";
|
||||
import { isUnavailableState, UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import type { HomeAssistant, ValueChangedEvent } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -53,11 +52,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
|
||||
const time = dateObj ? format(dateObj, "HH:mm:ss") : undefined;
|
||||
const date = dateObj ? format(dateObj, "yyyy-MM-dd") : undefined;
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -9,7 +9,6 @@ import {
|
||||
stateToIsoDateString,
|
||||
} from "../../../data/input_datetime";
|
||||
import type { HomeAssistant, ValueChangedEvent } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -47,11 +46,7 @@ class HuiInputDatetimeEntityRow extends LitElement implements LovelaceRow {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { InputSelectEntity } from "../../../data/input_select";
|
||||
import { setInputSelectOption } from "../../../data/input_select";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { EntitiesCardEntityConfig } from "../cards/types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -50,11 +49,7 @@ class HuiInputSelectEntityRow extends LitElement implements LovelaceRow {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -5,7 +5,6 @@ import "../../../components/ha-textfield";
|
||||
import { isUnavailableState, UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import { setValue } from "../../../data/input_text";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -43,11 +42,7 @@ class HuiInputTextEntityRow extends LitElement implements LovelaceRow {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -9,7 +9,6 @@ import type { SelectEntity } from "../../../data/select";
|
||||
import { setSelectOption } from "../../../data/select";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { EntitiesCardEntityConfig } from "../cards/types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -68,11 +67,7 @@ class HuiSelectEntityRow extends LitElement implements LovelaceRow {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -6,7 +6,6 @@ import { isUnavailableState, UNAVAILABLE } from "../../../data/entity/entity";
|
||||
import type { TextEntity } from "../../../data/text";
|
||||
import { setValue } from "../../../data/text";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
import "../components/hui-generic-entity-row";
|
||||
import { createEntityNotFoundWarning } from "../components/hui-warning";
|
||||
@@ -46,11 +45,7 @@ class HuiTextEntityRow extends LitElement implements LovelaceRow {
|
||||
`;
|
||||
}
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<hui-generic-entity-row
|
||||
|
||||
@@ -17,7 +17,6 @@ import {
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import type { EntitiesCardEntityConfig } from "../cards/types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction, hasAnyAction } from "../common/has-action";
|
||||
import { hasConfigOrEntityChanged } from "../common/has-changed";
|
||||
@@ -119,11 +118,7 @@ class HuiWeatherEntityRow extends LitElement implements LovelaceRow {
|
||||
const forecastData = getForecast(stateObj.attributes, this._forecastEvent);
|
||||
const forecast = forecastData?.forecast;
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass!.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<div
|
||||
|
||||
@@ -15,7 +15,6 @@ import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import "../../../state-display/state-display";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { findEntities } from "../common/find-entities";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
@@ -154,11 +153,7 @@ export class HuiEntityHeadingBadge
|
||||
"--icon-color": color,
|
||||
};
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass,
|
||||
stateObj,
|
||||
this._config.name
|
||||
);
|
||||
const name = this.hass.formatEntityName(stateObj, this._config.name);
|
||||
|
||||
return html`
|
||||
<ha-heading-badge
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { DOMAINS_TOGGLE } from "../../../common/const";
|
||||
@@ -7,11 +8,25 @@ import "../../../components/ha-state-icon";
|
||||
import type { ActionHandlerEvent } from "../../../data/lovelace/action_handler";
|
||||
import type { HomeAssistant } from "../../../types";
|
||||
import { actionHandler } from "../common/directives/action-handler-directive";
|
||||
import { computeLovelaceEntityName } from "../common/entity/compute-lovelace-entity-name";
|
||||
import { handleAction } from "../common/handle-action";
|
||||
import { hasAction } from "../common/has-action";
|
||||
import type { ButtonRowConfig, LovelaceRow } from "../entity-rows/types";
|
||||
|
||||
const EMPTY_STATE_OBJ = {
|
||||
state: "unavailable",
|
||||
attributes: {
|
||||
friendly_name: "",
|
||||
},
|
||||
entity_id: "___.empty",
|
||||
context: {
|
||||
id: "",
|
||||
parent_id: null,
|
||||
user_id: null,
|
||||
},
|
||||
last_changed: "",
|
||||
last_updated: "",
|
||||
} satisfies HassEntity;
|
||||
|
||||
@customElement("hui-button-row")
|
||||
export class HuiButtonRow extends LitElement implements LovelaceRow {
|
||||
public hass?: HomeAssistant;
|
||||
@@ -49,9 +64,8 @@ export class HuiButtonRow extends LitElement implements LovelaceRow {
|
||||
? this.hass.states[this._config.entity]
|
||||
: undefined;
|
||||
|
||||
const name = computeLovelaceEntityName(
|
||||
this.hass!,
|
||||
stateObj,
|
||||
const name = this.hass!.formatEntityName(
|
||||
stateObj || EMPTY_STATE_OBJ,
|
||||
this._config.name
|
||||
);
|
||||
|
||||
|
||||
@@ -309,7 +309,7 @@ export interface HomeAssistant {
|
||||
formatEntityAttributeName(stateObj: HassEntity, attribute: string): string;
|
||||
formatEntityName(
|
||||
stateObj: HassEntity,
|
||||
type: EntityNameItem | EntityNameItem[],
|
||||
type: string | EntityNameItem | EntityNameItem[] | undefined,
|
||||
separator?: EntityNameOptions
|
||||
): string;
|
||||
}
|
||||
|
||||
@@ -13,6 +13,27 @@ import {
|
||||
} from "./context/context-mock";
|
||||
|
||||
describe("computeEntityNameDisplay", () => {
|
||||
it("returns string name directly", () => {
|
||||
const stateObj = mockStateObj({ entity_id: "light.kitchen" });
|
||||
const hass = {
|
||||
entities: {},
|
||||
devices: {},
|
||||
areas: {},
|
||||
floors: {},
|
||||
} as unknown as HomeAssistant;
|
||||
|
||||
const result = computeEntityNameDisplay(
|
||||
stateObj,
|
||||
"Custom Name",
|
||||
hass.entities,
|
||||
hass.devices,
|
||||
hass.areas,
|
||||
hass.floors
|
||||
);
|
||||
|
||||
expect(result).toBe("Custom Name");
|
||||
});
|
||||
|
||||
it("returns text when all items are text", () => {
|
||||
const stateObj = mockStateObj({ entity_id: "light.kitchen" });
|
||||
const hass = {
|
||||
|
||||
@@ -1,152 +0,0 @@
|
||||
import { describe, expect, it, vi } from "vitest";
|
||||
import { computeLovelaceEntityName } from "../../../../../src/panels/lovelace/common/entity/compute-lovelace-entity-name";
|
||||
import type { HomeAssistant } from "../../../../../src/types";
|
||||
import { mockStateObj } from "../../../../common/entity/context/context-mock";
|
||||
|
||||
const createMockHass = (
|
||||
mockFormatEntityName: ReturnType<typeof vi.fn>
|
||||
): HomeAssistant =>
|
||||
({
|
||||
formatEntityName: mockFormatEntityName,
|
||||
}) as unknown as HomeAssistant;
|
||||
|
||||
describe("computeLovelaceEntityName", () => {
|
||||
it("returns the string directly when nameConfig is a string", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const stateObj = mockStateObj({ entity_id: "light.kitchen" });
|
||||
|
||||
const result = computeLovelaceEntityName(hass, stateObj, "Custom Name");
|
||||
|
||||
expect(result).toBe("Custom Name");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns empty string when nameConfig is empty string", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const stateObj = mockStateObj({
|
||||
entity_id: "light.kitchen",
|
||||
attributes: { friendly_name: "Kitchen Light" },
|
||||
});
|
||||
|
||||
const result = computeLovelaceEntityName(hass, stateObj, "");
|
||||
|
||||
expect(result).toBe("");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("calls formatEntityName with DEFAULT_ENTITY_NAME when nameConfig is undefined", () => {
|
||||
const mockFormatEntityName = vi.fn(() => "Formatted Name");
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const stateObj = mockStateObj({
|
||||
entity_id: "light.kitchen",
|
||||
attributes: { friendly_name: "Kitchen Light" },
|
||||
});
|
||||
|
||||
const result = computeLovelaceEntityName(hass, stateObj, undefined);
|
||||
|
||||
expect(result).toBe("Formatted Name");
|
||||
expect(mockFormatEntityName).toHaveBeenCalledTimes(1);
|
||||
expect(mockFormatEntityName).toHaveBeenCalledWith(stateObj, [
|
||||
{ type: "device" },
|
||||
{ type: "entity" },
|
||||
]);
|
||||
});
|
||||
|
||||
it("calls formatEntityName with EntityNameItem config", () => {
|
||||
const mockFormatEntityName = vi.fn(() => "Formatted Name");
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const stateObj = mockStateObj({ entity_id: "light.bedroom" });
|
||||
const nameConfig = { type: "device" as const };
|
||||
|
||||
const result = computeLovelaceEntityName(hass, stateObj, nameConfig);
|
||||
|
||||
expect(result).toBe("Formatted Name");
|
||||
expect(mockFormatEntityName).toHaveBeenCalledTimes(1);
|
||||
expect(mockFormatEntityName).toHaveBeenCalledWith(stateObj, nameConfig);
|
||||
});
|
||||
|
||||
it("calls formatEntityName with array of EntityNameItems", () => {
|
||||
const mockFormatEntityName = vi.fn(() => "Formatted Name");
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const stateObj = mockStateObj({ entity_id: "light.kitchen" });
|
||||
const nameConfig = [
|
||||
{ type: "device" as const },
|
||||
{ type: "entity" as const },
|
||||
];
|
||||
|
||||
const result = computeLovelaceEntityName(hass, stateObj, nameConfig);
|
||||
|
||||
expect(result).toBe("Formatted Name");
|
||||
expect(mockFormatEntityName).toHaveBeenCalledTimes(1);
|
||||
expect(mockFormatEntityName).toHaveBeenCalledWith(stateObj, nameConfig);
|
||||
});
|
||||
|
||||
describe("when stateObj is undefined", () => {
|
||||
it("returns empty string when nameConfig is undefined", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
|
||||
const result = computeLovelaceEntityName(hass, undefined, undefined);
|
||||
|
||||
expect(result).toBe("");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns text from single text EntityNameItem", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const nameConfig = { type: "text" as const, text: "Custom Text" };
|
||||
|
||||
const result = computeLovelaceEntityName(hass, undefined, nameConfig);
|
||||
|
||||
expect(result).toBe("Custom Text");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns joined text from multiple text EntityNameItems", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const nameConfig = [
|
||||
{ type: "text" as const, text: "First" },
|
||||
{ type: "text" as const, text: "Second" },
|
||||
];
|
||||
|
||||
const result = computeLovelaceEntityName(hass, undefined, nameConfig);
|
||||
|
||||
expect(result).toBe("First Second");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns only text items when mixed with non-text items", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const nameConfig = [
|
||||
{ type: "text" as const, text: "Prefix" },
|
||||
{ type: "device" as const },
|
||||
{ type: "text" as const, text: "Suffix" },
|
||||
{ type: "entity" as const },
|
||||
];
|
||||
|
||||
const result = computeLovelaceEntityName(hass, undefined, nameConfig);
|
||||
|
||||
expect(result).toBe("Prefix Suffix");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
|
||||
it("returns empty string when no text items in config", () => {
|
||||
const mockFormatEntityName = vi.fn();
|
||||
const hass = createMockHass(mockFormatEntityName);
|
||||
const nameConfig = [
|
||||
{ type: "device" as const },
|
||||
{ type: "entity" as const },
|
||||
];
|
||||
|
||||
const result = computeLovelaceEntityName(hass, undefined, nameConfig);
|
||||
|
||||
expect(result).toBe("");
|
||||
expect(mockFormatEntityName).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user