mirror of
https://github.com/home-assistant/frontend.git
synced 2025-04-19 19:07:23 +00:00
Separate entity, device and area name in more info dialog header (#21951)
* Separate entity, device and area name in more info dialog header * Use has_entity_name * Separate entity, device and area name in entity picker * Fix entity name with has entity name * Fix compute entity name * Add full name * Add floor * Improve code quality * Use compute entity name in device entities card * Use context functions * Remove floor * Use state name provided by backend * Use breadcrumb for more info * Revert entity picker changes * Use new logic in device page * Use breadcrumb * Use join directive * Add comments * Use secondary text color * Update compute_entity_name.ts Co-authored-by: Bram Kragten <mail@bramkragten.nl> * Remove html join * Improve computeDeviceNameDisplay * Fallback to original name * Simplify more info logic * Include breadcrumb for child view (voice assistant) --------- Co-authored-by: Bram Kragten <mail@bramkragten.nl>
This commit is contained in:
parent
f6467a35db
commit
53bb8251fa
@ -1,12 +1,17 @@
|
||||
const { existsSync } = require("fs");
|
||||
const path = require("path");
|
||||
const rspack = require("@rspack/core");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { RsdoctorRspackPlugin } = require("@rsdoctor/rspack-plugin");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { StatsWriterPlugin } = require("webpack-stats-plugin");
|
||||
const filterStats = require("@bundle-stats/plugin-webpack-filter");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const TerserPlugin = require("terser-webpack-plugin");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const { WebpackManifestPlugin } = require("rspack-manifest-plugin");
|
||||
const log = require("fancy-log");
|
||||
// eslint-disable-next-line @typescript-eslint/naming-convention
|
||||
const WebpackBar = require("webpackbar/rspack");
|
||||
const paths = require("./paths.cjs");
|
||||
const bundle = require("./bundle.cjs");
|
||||
@ -190,6 +195,7 @@ const createRspackConfig = ({
|
||||
"lit/directives/if-defined$": "lit/directives/if-defined.js",
|
||||
"lit/directives/guard$": "lit/directives/guard.js",
|
||||
"lit/directives/cache$": "lit/directives/cache.js",
|
||||
"lit/directives/join$": "lit/directives/join.js",
|
||||
"lit/directives/repeat$": "lit/directives/repeat.js",
|
||||
"lit/directives/live$": "lit/directives/live.js",
|
||||
"lit/directives/keyed$": "lit/directives/keyed.js",
|
||||
|
4
src/common/entity/compute_area_name.ts
Normal file
4
src/common/entity/compute_area_name.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import type { AreaRegistryEntry } from "../../data/area_registry";
|
||||
|
||||
export const computeAreaName = (area: AreaRegistryEntry): string | undefined =>
|
||||
area.name?.trim();
|
38
src/common/entity/compute_device_name.ts
Normal file
38
src/common/entity/compute_device_name.ts
Normal file
@ -0,0 +1,38 @@
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import type {
|
||||
EntityRegistryDisplayEntry,
|
||||
EntityRegistryEntry,
|
||||
} from "../../data/entity_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { computeStateName } from "./compute_state_name";
|
||||
|
||||
export const computeDeviceName = (
|
||||
device: DeviceRegistryEntry
|
||||
): string | undefined => (device.name_by_user || device.name)?.trim();
|
||||
|
||||
export const computeDeviceNameDisplay = (
|
||||
device: DeviceRegistryEntry,
|
||||
hass: HomeAssistant,
|
||||
entities?: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
|
||||
) =>
|
||||
computeDeviceName(device) ||
|
||||
(entities && fallbackDeviceName(hass, entities)) ||
|
||||
hass.localize("ui.panel.config.devices.unnamed_device", {
|
||||
type: hass.localize(
|
||||
`ui.panel.config.devices.type.${device.entry_type || "device"}`
|
||||
),
|
||||
});
|
||||
|
||||
export const fallbackDeviceName = (
|
||||
hass: HomeAssistant,
|
||||
entities: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
|
||||
) => {
|
||||
for (const entity of entities || []) {
|
||||
const entityId = typeof entity === "string" ? entity : entity.entity_id;
|
||||
const stateObj = hass.states[entityId];
|
||||
if (stateObj) {
|
||||
return computeStateName(stateObj);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
};
|
52
src/common/entity/compute_entity_name.ts
Normal file
52
src/common/entity/compute_entity_name.ts
Normal file
@ -0,0 +1,52 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type {
|
||||
EntityRegistryDisplayEntry,
|
||||
EntityRegistryEntry,
|
||||
} from "../../data/entity_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { computeDeviceName } from "./compute_device_name";
|
||||
import { computeStateName } from "./compute_state_name";
|
||||
import { stripPrefixFromEntityName } from "./strip_prefix_from_entity_name";
|
||||
|
||||
export const computeEntityName = (
|
||||
stateObj: HassEntity,
|
||||
hass: HomeAssistant
|
||||
): string | undefined => {
|
||||
const entry = hass.entities[stateObj.entity_id] as
|
||||
| EntityRegistryDisplayEntry
|
||||
| undefined;
|
||||
|
||||
if (!entry) {
|
||||
// Fall back to state name if not in the entity registry (friendly name)
|
||||
return computeStateName(stateObj);
|
||||
}
|
||||
return computeEntityEntryName(entry, hass);
|
||||
};
|
||||
|
||||
export const computeEntityEntryName = (
|
||||
entry: EntityRegistryDisplayEntry | EntityRegistryEntry,
|
||||
hass: HomeAssistant
|
||||
): string | undefined => {
|
||||
const name =
|
||||
entry.name || ("original_name" in entry ? entry.original_name : undefined);
|
||||
|
||||
const device = entry.device_id ? hass.devices[entry.device_id] : undefined;
|
||||
|
||||
if (!device) {
|
||||
return name;
|
||||
}
|
||||
|
||||
const deviceName = computeDeviceName(device);
|
||||
|
||||
// If the device name is the same as the entity name, consider empty entity name
|
||||
if (deviceName === name) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
// Remove the device name from the entity name if it starts with it
|
||||
if (deviceName && name) {
|
||||
return stripPrefixFromEntityName(name, deviceName) || name;
|
||||
}
|
||||
|
||||
return name;
|
||||
};
|
4
src/common/entity/compute_floor_name.ts
Normal file
4
src/common/entity/compute_floor_name.ts
Normal file
@ -0,0 +1,4 @@
|
||||
import type { FloorRegistryEntry } from "../../data/floor_registry";
|
||||
|
||||
export const computeFloorName = (floor: FloorRegistryEntry): string =>
|
||||
floor.name?.trim();
|
18
src/common/entity/get_area_context.ts
Normal file
18
src/common/entity/get_area_context.ts
Normal file
@ -0,0 +1,18 @@
|
||||
import type { AreaRegistryEntry } from "../../data/area_registry";
|
||||
import type { FloorRegistryEntry } from "../../data/floor_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
|
||||
interface AreaContext {
|
||||
floor: FloorRegistryEntry | null;
|
||||
}
|
||||
export const getAreaContext = (
|
||||
area: AreaRegistryEntry,
|
||||
hass: HomeAssistant
|
||||
): AreaContext => {
|
||||
const floorId = area.floor_id;
|
||||
const floor = floorId ? hass.floors[floorId] : null;
|
||||
|
||||
return {
|
||||
floor: floor,
|
||||
};
|
||||
};
|
24
src/common/entity/get_device_context.ts
Normal file
24
src/common/entity/get_device_context.ts
Normal file
@ -0,0 +1,24 @@
|
||||
import type { AreaRegistryEntry } from "../../data/area_registry";
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import type { FloorRegistryEntry } from "../../data/floor_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
|
||||
interface DeviceContext {
|
||||
area: AreaRegistryEntry | null;
|
||||
floor: FloorRegistryEntry | null;
|
||||
}
|
||||
|
||||
export const getDeviceContext = (
|
||||
device: DeviceRegistryEntry,
|
||||
hass: HomeAssistant
|
||||
): DeviceContext => {
|
||||
const areaId = device.area_id;
|
||||
const area = areaId ? hass.areas[areaId] : null;
|
||||
const floorId = area?.floor_id;
|
||||
const floor = floorId ? hass.floors[floorId] : null;
|
||||
|
||||
return {
|
||||
area: area,
|
||||
floor: floor,
|
||||
};
|
||||
};
|
34
src/common/entity/get_entity_context.ts
Normal file
34
src/common/entity/get_entity_context.ts
Normal file
@ -0,0 +1,34 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { AreaRegistryEntry } from "../../data/area_registry";
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import type { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import type { FloorRegistryEntry } from "../../data/floor_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
|
||||
interface EntityContext {
|
||||
device: DeviceRegistryEntry | null;
|
||||
area: AreaRegistryEntry | null;
|
||||
floor: FloorRegistryEntry | null;
|
||||
}
|
||||
|
||||
export const getEntityContext = (
|
||||
stateObj: HassEntity,
|
||||
hass: HomeAssistant
|
||||
): EntityContext => {
|
||||
const entry = hass.entities[stateObj.entity_id] as
|
||||
| EntityRegistryDisplayEntry
|
||||
| undefined;
|
||||
|
||||
const deviceId = entry?.device_id;
|
||||
const device = deviceId ? hass.devices[deviceId] : null;
|
||||
const areaId = entry?.area_id || device?.area_id;
|
||||
const area = areaId ? hass.areas[areaId] : null;
|
||||
const floorId = area?.floor_id;
|
||||
const floor = floorId ? hass.floors[floorId] : null;
|
||||
|
||||
return {
|
||||
device: device,
|
||||
area: area,
|
||||
floor: floor,
|
||||
};
|
||||
};
|
@ -1,17 +1,17 @@
|
||||
const SUFFIXES = [" ", ": "];
|
||||
const SUFFIXES = [" ", ": ", " - "];
|
||||
|
||||
/**
|
||||
* Strips a device name from an entity name.
|
||||
* @param entityName the entity name
|
||||
* @param lowerCasedPrefix the prefix to strip, lower cased
|
||||
* @param prefix the prefix to strip
|
||||
* @returns
|
||||
*/
|
||||
export const stripPrefixFromEntityName = (
|
||||
entityName: string,
|
||||
lowerCasedPrefix: string
|
||||
prefix: string
|
||||
) => {
|
||||
const lowerCasedEntityName = entityName.toLowerCase();
|
||||
|
||||
const lowerCasedPrefix = prefix.toLowerCase();
|
||||
for (const suffix of SUFFIXES) {
|
||||
const lowerCasedPrefixWithSuffix = `${lowerCasedPrefix}${suffix}`;
|
||||
|
||||
|
@ -5,6 +5,7 @@ import { LitElement, html } from "lit";
|
||||
import { customElement, property, query, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { stringCompare } from "../../common/string/compare";
|
||||
import type { ScorableTextItem } from "../../common/string/filter/sequence-matching";
|
||||
@ -13,10 +14,7 @@ import type {
|
||||
DeviceEntityDisplayLookup,
|
||||
DeviceRegistryEntry,
|
||||
} from "../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
getDeviceEntityDisplayLookup,
|
||||
} from "../../data/device_registry";
|
||||
import { getDeviceEntityDisplayLookup } from "../../data/device_registry";
|
||||
import type { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import type { HomeAssistant, ValueChangedEvent } from "../../types";
|
||||
import "../ha-combo-box";
|
||||
@ -214,7 +212,7 @@ export class HaDevicePicker extends LitElement {
|
||||
}
|
||||
|
||||
const outputDevices = inputDevices.map((device) => {
|
||||
const name = computeDeviceName(
|
||||
const name = computeDeviceNameDisplay(
|
||||
device,
|
||||
this.hass,
|
||||
deviceEntityLookup[device.id]
|
||||
|
@ -5,8 +5,8 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../common/entity/compute_device_name";
|
||||
import { stringCompare } from "../common/string/compare";
|
||||
import { computeDeviceName } from "../data/device_registry";
|
||||
import type { RelatedResult } from "../data/search";
|
||||
import { findRelated } from "../data/search";
|
||||
import { haStyleScrollbar } from "../resources/styles";
|
||||
@ -95,7 +95,7 @@ export class HaFilterDevices extends LitElement {
|
||||
.value=${device.id}
|
||||
.selected=${this.value?.includes(device.id) ?? false}
|
||||
>
|
||||
${computeDeviceName(device, this.hass)}
|
||||
${computeDeviceNameDisplay(device, this.hass)}
|
||||
</ha-check-list-item>`;
|
||||
|
||||
private _handleItemClick(ev) {
|
||||
@ -142,12 +142,14 @@ export class HaFilterDevices extends LitElement {
|
||||
.filter(
|
||||
(device) =>
|
||||
!filter ||
|
||||
computeDeviceName(device, this.hass).toLowerCase().includes(filter)
|
||||
computeDeviceNameDisplay(device, this.hass)
|
||||
.toLowerCase()
|
||||
.includes(filter)
|
||||
)
|
||||
.sort((a, b) =>
|
||||
stringCompare(
|
||||
computeDeviceName(a, this.hass),
|
||||
computeDeviceName(b, this.hass),
|
||||
computeDeviceNameDisplay(a, this.hass),
|
||||
computeDeviceNameDisplay(b, this.hass),
|
||||
this.hass.locale.language
|
||||
)
|
||||
);
|
||||
|
@ -26,12 +26,12 @@ import { computeCssColor } from "../common/color/compute-color";
|
||||
import { hex2rgb } from "../common/color/convert-color";
|
||||
import { fireEvent } from "../common/dom/fire_event";
|
||||
import { stopPropagation } from "../common/dom/stop_propagation";
|
||||
import { computeDeviceNameDisplay } from "../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../common/entity/compute_domain";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import { isValidEntityId } from "../common/entity/valid_entity_id";
|
||||
import type { AreaRegistryEntry } from "../data/area_registry";
|
||||
import type { DeviceRegistryEntry } from "../data/device_registry";
|
||||
import { computeDeviceName } from "../data/device_registry";
|
||||
import type { EntityRegistryDisplayEntry } from "../data/entity_registry";
|
||||
import type { LabelRegistryEntry } from "../data/label_registry";
|
||||
import { subscribeLabelRegistry } from "../data/label_registry";
|
||||
@ -150,7 +150,9 @@ export class HaTargetPicker extends SubscribeMixin(LitElement) {
|
||||
return this._renderChip(
|
||||
"device_id",
|
||||
device_id,
|
||||
device ? computeDeviceName(device, this.hass) : device_id,
|
||||
device
|
||||
? computeDeviceNameDisplay(device, this.hass)
|
||||
: device_id,
|
||||
undefined,
|
||||
undefined,
|
||||
mdiDevices
|
||||
|
@ -65,20 +65,6 @@ export const fallbackDeviceName = (
|
||||
return undefined;
|
||||
};
|
||||
|
||||
export const computeDeviceName = (
|
||||
device: DeviceRegistryEntry,
|
||||
hass: HomeAssistant,
|
||||
entities?: EntityRegistryEntry[] | EntityRegistryDisplayEntry[] | string[]
|
||||
) =>
|
||||
device.name_by_user ||
|
||||
device.name ||
|
||||
(entities && fallbackDeviceName(hass, entities)) ||
|
||||
hass.localize("ui.panel.config.devices.unnamed_device", {
|
||||
type: hass.localize(
|
||||
`ui.panel.config.devices.type.${device.entry_type || "device"}`
|
||||
),
|
||||
});
|
||||
|
||||
export const devicesInArea = (devices: DeviceRegistryEntry[], areaId: string) =>
|
||||
devices.filter((device) => device.area_id === areaId);
|
||||
|
||||
|
@ -24,6 +24,7 @@ export interface EntityRegistryDisplayEntry {
|
||||
translation_key?: string;
|
||||
platform?: string;
|
||||
display_precision?: number;
|
||||
has_entity_name?: boolean;
|
||||
}
|
||||
|
||||
export interface EntityRegistryDisplayEntryResponse {
|
||||
@ -39,6 +40,7 @@ export interface EntityRegistryDisplayEntryResponse {
|
||||
tk?: string;
|
||||
hb?: boolean;
|
||||
dp?: number;
|
||||
hn?: boolean;
|
||||
}[];
|
||||
entity_categories: Record<number, EntityCategory>;
|
||||
}
|
||||
|
@ -1,6 +1,7 @@
|
||||
import { ensureArray } from "../common/array/ensure-array";
|
||||
import { formatNumericDuration } from "../common/datetime/format_duration";
|
||||
import secondsToDuration from "../common/datetime/seconds_to_duration";
|
||||
import { computeDeviceNameDisplay } from "../common/entity/compute_device_name";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
import { formatListWithAnds } from "../common/string/format-list";
|
||||
import { isTemplate } from "../common/string/has-template";
|
||||
@ -8,7 +9,6 @@ import type { HomeAssistant } from "../types";
|
||||
import type { Condition } from "./automation";
|
||||
import { describeCondition } from "./automation_i18n";
|
||||
import { localizeDeviceAutomationAction } from "./device_automation";
|
||||
import { computeDeviceName } from "./device_registry";
|
||||
import type { EntityRegistryEntry } from "./entity_registry";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
@ -147,7 +147,7 @@ const tryDescribeAction = <T extends ActionType>(
|
||||
} else if (key === "device_id") {
|
||||
const device = hass.devices[targetThing];
|
||||
if (device) {
|
||||
targets.push(computeDeviceName(device, hass));
|
||||
targets.push(computeDeviceNameDisplay(device, hass));
|
||||
} else {
|
||||
targets.push(
|
||||
hass.localize(
|
||||
|
@ -4,22 +4,20 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import "../../components/ha-area-picker";
|
||||
import { assistSatelliteSupportsSetupFlow } from "../../data/assist_satellite";
|
||||
import type { DataEntryFlowStepCreateEntry } from "../../data/data_entry_flow";
|
||||
import type { DeviceRegistryEntry } from "../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
updateDeviceRegistryEntry,
|
||||
} from "../../data/device_registry";
|
||||
import { updateDeviceRegistryEntry } from "../../data/device_registry";
|
||||
import type { EntityRegistryDisplayEntry } from "../../data/entity_registry";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { showAlertDialog } from "../generic/show-dialog-box";
|
||||
import { showVoiceAssistantSetupDialog } from "../voice-assistant-setup/show-voice-assistant-setup-dialog";
|
||||
import type { FlowConfig } from "./show-dialog-data-entry-flow";
|
||||
import { configFlowContentStyles } from "./styles";
|
||||
import { navigate } from "../../common/navigate";
|
||||
|
||||
@customElement("step-flow-create-entry")
|
||||
class StepFlowCreateEntry extends LitElement {
|
||||
@ -124,7 +122,8 @@ class StepFlowCreateEntry extends LitElement {
|
||||
(device) => html`
|
||||
<div class="device">
|
||||
<div>
|
||||
<b>${computeDeviceName(device, this.hass)}</b><br />
|
||||
<b>${computeDeviceNameDisplay(device, this.hass)}</b
|
||||
><br />
|
||||
${!device.model && !device.manufacturer
|
||||
? html` `
|
||||
: html`${device.model}
|
||||
|
@ -14,11 +14,15 @@ import type { PropertyValues } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { cache } from "lit/directives/cache";
|
||||
import { join } from "lit/directives/join";
|
||||
import { dynamicElement } from "../../common/dom/dynamic-element-directive";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { stopPropagation } from "../../common/dom/stop_propagation";
|
||||
import { computeAreaName } from "../../common/entity/compute_area_name";
|
||||
import { computeDeviceName } from "../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { computeEntityName } from "../../common/entity/compute_entity_name";
|
||||
import { getEntityContext } from "../../common/entity/get_entity_context";
|
||||
import { shouldHandleRequestSelectedEvent } from "../../common/mwc/handle-request-selected-event";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import "../../components/ha-button-menu";
|
||||
@ -34,7 +38,9 @@ import type {
|
||||
} from "../../data/entity_registry";
|
||||
import { getExtendedEntityRegistryEntry } from "../../data/entity_registry";
|
||||
import { lightSupportsFavoriteColors } from "../../data/light";
|
||||
import type { ItemType } from "../../data/search";
|
||||
import { SearchableDomains } from "../../data/search";
|
||||
import { getSensorNumericDeviceClasses } from "../../data/sensor";
|
||||
import { haStyleDialog } from "../../resources/styles";
|
||||
import "../../state-summary/state-card-content";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
@ -50,7 +56,6 @@ import "./ha-more-info-history-and-logbook";
|
||||
import "./ha-more-info-info";
|
||||
import "./ha-more-info-settings";
|
||||
import "./more-info-content";
|
||||
import { getSensorNumericDeviceClasses } from "../../data/sensor";
|
||||
|
||||
export interface MoreInfoDialogParams {
|
||||
entityId: string | null;
|
||||
@ -278,19 +283,31 @@ export class MoreInfoDialog extends LitElement {
|
||||
const stateObj = this.hass.states[entityId] as HassEntity | undefined;
|
||||
|
||||
const domain = computeDomain(entityId);
|
||||
const name = (stateObj && computeStateName(stateObj)) || entityId;
|
||||
|
||||
const isAdmin = this.hass.user!.is_admin;
|
||||
|
||||
const deviceId = this._getDeviceId();
|
||||
|
||||
const title = this._childView?.viewTitle ?? name;
|
||||
|
||||
const isDefaultView = this._currView === DEFAULT_VIEW && !this._childView;
|
||||
const isSpecificInitialView =
|
||||
this._initialView !== DEFAULT_VIEW && !this._childView;
|
||||
const showCloseIcon = isDefaultView || isSpecificInitialView;
|
||||
|
||||
const context = stateObj ? getEntityContext(stateObj, this.hass) : null;
|
||||
|
||||
const entityName = stateObj
|
||||
? computeEntityName(stateObj, this.hass)
|
||||
: undefined;
|
||||
const deviceName = context?.device
|
||||
? computeDeviceName(context.device)
|
||||
: undefined;
|
||||
const areaName = context?.area ? computeAreaName(context.area) : undefined;
|
||||
|
||||
const breadcrumb = [areaName, deviceName, entityName].filter(
|
||||
(v): v is string => Boolean(v)
|
||||
);
|
||||
const title = this._childView?.viewTitle || breadcrumb.pop();
|
||||
|
||||
return html`
|
||||
<ha-dialog
|
||||
open
|
||||
@ -320,8 +337,20 @@ export class MoreInfoDialog extends LitElement {
|
||||
)}
|
||||
></ha-icon-button-prev>
|
||||
`}
|
||||
<span slot="title" .title=${title} @click=${this._enlarge}>
|
||||
${title}
|
||||
<span
|
||||
slot="title"
|
||||
.title=${title}
|
||||
@click=${this._enlarge}
|
||||
class="title"
|
||||
>
|
||||
${breadcrumb.length > 0
|
||||
? html`
|
||||
<p class="breadcrumb">
|
||||
${join(breadcrumb, html`<ha-icon-next></ha-icon-next>`)}
|
||||
</p>
|
||||
`
|
||||
: nothing}
|
||||
<p class="main">${title}</p>
|
||||
</span>
|
||||
${isDefaultView
|
||||
? html`
|
||||
@ -512,7 +541,7 @@ export class MoreInfoDialog extends LitElement {
|
||||
.hass=${this.hass}
|
||||
.itemId=${entityId}
|
||||
.itemType=${SearchableDomains.has(domain)
|
||||
? domain
|
||||
? (domain as ItemType)
|
||||
: "entity"}
|
||||
></ha-related-items>
|
||||
`
|
||||
@ -610,6 +639,36 @@ export class MoreInfoDialog extends LitElement {
|
||||
--mdc-dialog-max-width: 90vw;
|
||||
}
|
||||
}
|
||||
|
||||
.title {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
}
|
||||
|
||||
.title p {
|
||||
margin: 0;
|
||||
min-width: 0;
|
||||
width: 100%;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.title .main {
|
||||
color: var(--primary-text-color);
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
}
|
||||
|
||||
.title .breadcrumb {
|
||||
color: var(--secondary-text-color);
|
||||
font-size: 14px;
|
||||
line-height: 16px;
|
||||
margin-top: -6px;
|
||||
}
|
||||
|
||||
.title .breadcrumb {
|
||||
--mdc-icon-size: 16px;
|
||||
}
|
||||
`,
|
||||
];
|
||||
}
|
||||
|
@ -19,16 +19,17 @@ import { canShowPage } from "../../common/config/can_show_page";
|
||||
import { componentsWithService } from "../../common/config/components_with_service";
|
||||
import { isComponentLoaded } from "../../common/config/is_component_loaded";
|
||||
import { fireEvent } from "../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../common/entity/compute_device_name";
|
||||
import { computeStateName } from "../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../common/navigate";
|
||||
import { caseInsensitiveStringCompare } from "../../common/string/compare";
|
||||
import type { ScorableTextItem } from "../../common/string/filter/sequence-matching";
|
||||
import { fuzzyFilterSort } from "../../common/string/filter/sequence-matching";
|
||||
import { debounce } from "../../common/util/debounce";
|
||||
import "../../components/ha-spinner";
|
||||
import "../../components/ha-icon-button";
|
||||
import "../../components/ha-label";
|
||||
import "../../components/ha-list-item";
|
||||
import "../../components/ha-spinner";
|
||||
import "../../components/ha-textfield";
|
||||
import { fetchHassioAddonsInfo } from "../../data/hassio/addon";
|
||||
import { domainToName } from "../../data/integration";
|
||||
@ -40,7 +41,6 @@ import { loadVirtualizer } from "../../resources/virtualizer";
|
||||
import type { HomeAssistant } from "../../types";
|
||||
import { showConfirmationDialog } from "../generic/show-dialog-box";
|
||||
import { QuickBarMode, type QuickBarParams } from "./show-dialog-quick-bar";
|
||||
import { computeDeviceName } from "../../data/device_registry";
|
||||
|
||||
interface QuickBarItem extends ScorableTextItem {
|
||||
primaryText: string;
|
||||
@ -529,9 +529,7 @@ export class QuickBar extends LitElement {
|
||||
? this.hass.areas[device.area_id]
|
||||
: undefined;
|
||||
const deviceItem = {
|
||||
primaryText:
|
||||
computeDeviceName(device, this.hass) ||
|
||||
this.hass.localize("ui.components.device-picker.unnamed_device"),
|
||||
primaryText: computeDeviceNameDisplay(device, this.hass),
|
||||
deviceId: device.id,
|
||||
area: area?.name,
|
||||
action: () => navigate(`/config/devices/device/${device.id}`),
|
||||
|
@ -1,7 +1,7 @@
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { consume } from "@lit-labs/context";
|
||||
import "@material/mwc-button";
|
||||
import "@material/mwc-list";
|
||||
import "@material/mwc-list/mwc-list-item";
|
||||
import { mdiDelete, mdiDotsVertical, mdiImagePlus, mdiPencil } from "@mdi/js";
|
||||
import type { HassEntity } from "home-assistant-js-websocket/dist/types";
|
||||
import type { CSSResultGroup } from "lit";
|
||||
@ -10,16 +10,17 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { caseInsensitiveStringCompare } from "../../../common/string/compare";
|
||||
import { groupBy } from "../../../common/util/group-by";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-tooltip";
|
||||
import type { AreaRegistryEntry } from "../../../data/area_registry";
|
||||
import {
|
||||
@ -29,10 +30,7 @@ import {
|
||||
import type { AutomationEntity } from "../../../data/automation";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
sortDeviceRegistryByName,
|
||||
} from "../../../data/device_registry";
|
||||
import { sortDeviceRegistryByName } from "../../../data/device_registry";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import {
|
||||
computeEntityRegistryName,
|
||||
@ -166,7 +164,7 @@ class HaConfigAreaPage extends LitElement {
|
||||
// Pre-compute the entity and device names, so we can sort by them
|
||||
if (devices) {
|
||||
devices.forEach((entry) => {
|
||||
entry.name = computeDeviceName(entry, this.hass);
|
||||
entry.name = computeDeviceNameDisplay(entry, this.hass);
|
||||
});
|
||||
sortDeviceRegistryByName(devices, this.hass.locale.language);
|
||||
}
|
||||
|
@ -7,16 +7,14 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { ifDefined } from "lit/directives/if-defined";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
|
||||
import "../../../components/entity/state-badge";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-spinner";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-spinner";
|
||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../data/device_registry";
|
||||
import { subscribeDeviceRegistry } from "../../../data/device_registry";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { subscribeEntityRegistry } from "../../../data/entity_registry";
|
||||
import type { UpdateEntity } from "../../../data/update";
|
||||
@ -114,7 +112,7 @@ class HaConfigUpdates extends SubscribeMixin(LitElement) {
|
||||
: ""}
|
||||
<span
|
||||
>${deviceEntry
|
||||
? computeDeviceName(deviceEntry, this.hass)
|
||||
? computeDeviceNameDisplay(deviceEntry, this.hass)
|
||||
: entity.attributes.friendly_name}</span
|
||||
>
|
||||
<span slot="secondary">
|
||||
|
@ -4,7 +4,7 @@ import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { until } from "lit/directives/until";
|
||||
import { computeStateName } from "../../../../common/entity/compute_state_name";
|
||||
import { computeEntityName } from "../../../../common/entity/compute_entity_name";
|
||||
import { stripPrefixFromEntityName } from "../../../../common/entity/strip_prefix_from_entity_name";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-icon";
|
||||
@ -15,17 +15,17 @@ import { entryIcon } from "../../../../data/icons";
|
||||
import { showMoreInfoDialog } from "../../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { HuiErrorCard } from "../../../lovelace/cards/hui-error-card";
|
||||
import { createRowElement } from "../../../lovelace/create-element/create-row-element";
|
||||
import { addEntitiesToLovelaceView } from "../../../lovelace/editor/add-entities-to-view";
|
||||
import type {
|
||||
LovelaceRowConfig,
|
||||
LovelaceRow,
|
||||
} from "../../../lovelace/entity-rows/types";
|
||||
import type { EntityRegistryStateEntry } from "../ha-config-device-page";
|
||||
import {
|
||||
computeCards,
|
||||
computeSection,
|
||||
} from "../../../lovelace/common/generate-lovelace-config";
|
||||
import { createRowElement } from "../../../lovelace/create-element/create-row-element";
|
||||
import { addEntitiesToLovelaceView } from "../../../lovelace/editor/add-entities-to-view";
|
||||
import type {
|
||||
LovelaceRow,
|
||||
LovelaceRowConfig,
|
||||
} from "../../../lovelace/entity-rows/types";
|
||||
import type { EntityRegistryStateEntry } from "../ha-config-device-page";
|
||||
|
||||
@customElement("ha-device-entities-card")
|
||||
export class HaDeviceEntitiesCard extends LitElement {
|
||||
@ -171,18 +171,7 @@ export class HaDeviceEntitiesCard extends LitElement {
|
||||
element.hass = this.hass;
|
||||
const stateObj = this.hass.states[entry.entity_id];
|
||||
|
||||
let name = entry.name
|
||||
? stripPrefixFromEntityName(entry.name, this.deviceName.toLowerCase())
|
||||
: entry.has_entity_name
|
||||
? entry.original_name || this.deviceName
|
||||
: stripPrefixFromEntityName(
|
||||
computeStateName(stateObj),
|
||||
this.deviceName.toLowerCase()
|
||||
);
|
||||
|
||||
if (!name) {
|
||||
name = computeStateName(stateObj);
|
||||
}
|
||||
let name = computeEntityName(stateObj, this.hass) || this.deviceName;
|
||||
|
||||
if (entry.hidden_by) {
|
||||
name += ` (${this.hass.localize(
|
||||
@ -216,8 +205,7 @@ export class HaDeviceEntitiesCard extends LitElement {
|
||||
<ha-icon slot="graphic" .icon=${icon}></ha-icon>
|
||||
<div class="name">
|
||||
${name
|
||||
? stripPrefixFromEntityName(name, this.deviceName.toLowerCase()) ||
|
||||
name
|
||||
? stripPrefixFromEntityName(name, this.deviceName) || name
|
||||
: entry.entity_id}
|
||||
</div>
|
||||
</ha-list-item>
|
||||
|
@ -1,10 +1,10 @@
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name";
|
||||
import { titleCase } from "../../../../common/string/title-case";
|
||||
import "../../../../components/ha-card";
|
||||
import type { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import { haStyle } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
|
||||
@ -56,7 +56,9 @@ export class HaDeviceCard extends LitElement {
|
||||
<span class="hub"
|
||||
><a
|
||||
href="/config/devices/device/${this.device.via_device_id}"
|
||||
>${this._computeDeviceName(this.device.via_device_id)}</a
|
||||
>${this._computeDeviceNameDislay(
|
||||
this.device.via_device_id
|
||||
)}</a
|
||||
></span
|
||||
>
|
||||
</div>
|
||||
@ -118,10 +120,10 @@ export class HaDeviceCard extends LitElement {
|
||||
);
|
||||
}
|
||||
|
||||
private _computeDeviceName(deviceId) {
|
||||
private _computeDeviceNameDislay(deviceId) {
|
||||
const device = this.hass.devices[deviceId];
|
||||
return device
|
||||
? computeDeviceName(device, this.hass)
|
||||
? computeDeviceNameDisplay(device, this.hass)
|
||||
: `<${this.hass.localize(
|
||||
"ui.panel.config.integrations.config_entry.unknown_via_device"
|
||||
)}>`;
|
||||
|
@ -2,11 +2,11 @@ import "@material/mwc-list/mwc-list-item";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name";
|
||||
import { caseInsensitiveStringCompare } from "../../../../common/string/compare";
|
||||
import "../../../../components/ha-card";
|
||||
import "../../../../components/ha-icon-next";
|
||||
import type { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
|
||||
const MAX_VISIBLE_VIA_DEVICES = 10;
|
||||
@ -28,8 +28,8 @@ export class HaDeviceViaDevicesCard extends LitElement {
|
||||
.filter((device) => device.via_device_id === deviceId)
|
||||
.sort((d1, d2) =>
|
||||
caseInsensitiveStringCompare(
|
||||
computeDeviceName(d1, this.hass),
|
||||
computeDeviceName(d2, this.hass),
|
||||
computeDeviceNameDisplay(d1, this.hass),
|
||||
computeDeviceNameDisplay(d2, this.hass),
|
||||
this.hass.locale.language
|
||||
)
|
||||
)
|
||||
@ -56,7 +56,7 @@ export class HaDeviceViaDevicesCard extends LitElement {
|
||||
(viaDevice) => html`
|
||||
<a href=${`/config/devices/device/${viaDevice.id}`}>
|
||||
<mwc-list-item hasMeta>
|
||||
${computeDeviceName(viaDevice, this.hass)}
|
||||
${computeDeviceNameDisplay(viaDevice, this.hass)}
|
||||
<ha-icon-next slot="meta"></ha-icon-next>
|
||||
</mwc-list-item>
|
||||
</a>
|
||||
|
@ -2,12 +2,12 @@ import "@material/mwc-button/mwc-button";
|
||||
import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, state } from "lit/decorators";
|
||||
import { computeDeviceNameDisplay } from "../../../../../../common/entity/compute_device_name";
|
||||
import { computeStateName } from "../../../../../../common/entity/compute_state_name";
|
||||
import "../../../../../../components/ha-dialog";
|
||||
import "../../../../../../components/ha-formfield";
|
||||
import "../../../../../../components/ha-switch";
|
||||
import type { HaSwitch } from "../../../../../../components/ha-switch";
|
||||
import { computeDeviceName } from "../../../../../../data/device_registry";
|
||||
import type { MQTTDeviceDebugInfo } from "../../../../../../data/mqtt";
|
||||
import { fetchMQTTDebugInfo } from "../../../../../../data/mqtt";
|
||||
import { haStyleDialog } from "../../../../../../resources/styles";
|
||||
@ -48,7 +48,7 @@ class DialogMQTTDeviceDebugInfo extends LitElement {
|
||||
@closed=${this._close}
|
||||
.heading=${this.hass!.localize(
|
||||
"ui.dialogs.mqtt_device_debug_info.title",
|
||||
{ device: computeDeviceName(this._params.device, this.hass) }
|
||||
{ device: computeDeviceNameDisplay(this._params.device, this.hass) }
|
||||
)}
|
||||
>
|
||||
<h4>
|
||||
|
@ -3,6 +3,7 @@ import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name";
|
||||
import "../../../../components/ha-alert";
|
||||
import "../../../../components/ha-area-picker";
|
||||
import "../../../../components/ha-dialog";
|
||||
@ -10,7 +11,6 @@ import "../../../../components/ha-labels-picker";
|
||||
import type { HaSwitch } from "../../../../components/ha-switch";
|
||||
import "../../../../components/ha-textfield";
|
||||
import type { DeviceRegistryEntry } from "../../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import { haStyle, haStyleDialog } from "../../../../resources/styles";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
import type { DeviceRegistryDetailDialogParams } from "./show-dialog-device-registry-detail";
|
||||
@ -60,7 +60,7 @@ class DialogDeviceRegistryDetail extends LitElement {
|
||||
<ha-dialog
|
||||
open
|
||||
@closed=${this.closeDialog}
|
||||
.heading=${computeDeviceName(device, this.hass)}
|
||||
.heading=${computeDeviceNameDisplay(device, this.hass)}
|
||||
>
|
||||
<div>
|
||||
${this._error
|
||||
|
@ -16,7 +16,9 @@ import { ifDefined } from "lit/directives/if-defined";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { isComponentLoaded } from "../../../common/config/is_component_loaded";
|
||||
import { ASSIST_ENTITIES, SENSOR_ENTITIES } from "../../../common/const";
|
||||
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeEntityEntryName } from "../../../common/entity/compute_entity_name";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { stringCompare } from "../../../common/string/compare";
|
||||
@ -25,11 +27,12 @@ import { groupBy } from "../../../common/util/group-by";
|
||||
import "../../../components/entity/ha-battery-icon";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-icon-next";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-expansion-panel";
|
||||
import "../../../components/ha-tooltip";
|
||||
import { assistSatelliteSupportsSetupFlow } from "../../../data/assist_satellite";
|
||||
import { getSignedPath } from "../../../data/auth";
|
||||
import type {
|
||||
ConfigEntry,
|
||||
@ -42,7 +45,6 @@ import {
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
removeConfigEntryFromDevice,
|
||||
updateDeviceRegistryEntry,
|
||||
} from "../../../data/device_registry";
|
||||
@ -68,6 +70,7 @@ import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showVoiceAssistantSetupDialog } from "../../../dialogs/voice-assistant-setup/show-voice-assistant-setup-dialog";
|
||||
import "../../../layouts/hass-error-screen";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
@ -83,8 +86,6 @@ import {
|
||||
loadDeviceRegistryDetailDialog,
|
||||
showDeviceRegistryDetailDialog,
|
||||
} from "./device-registry-detail/show-dialog-device-registry-detail";
|
||||
import { showVoiceAssistantSetupDialog } from "../../../dialogs/voice-assistant-setup/show-voice-assistant-setup-dialog";
|
||||
import { assistSatelliteSupportsSetupFlow } from "../../../data/assist_satellite";
|
||||
|
||||
export interface EntityRegistryStateEntry extends EntityRegistryEntry {
|
||||
stateName?: string | null;
|
||||
@ -310,7 +311,7 @@ export class HaConfigDevicePage extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
const deviceName = computeDeviceName(device, this.hass);
|
||||
const deviceName = computeDeviceNameDisplay(device, this.hass);
|
||||
const integrations = this._integrations(
|
||||
device,
|
||||
this.entries,
|
||||
@ -1155,11 +1156,11 @@ export class HaConfigDevicePage extends LitElement {
|
||||
}
|
||||
|
||||
private _computeEntityName(entity: EntityRegistryEntry) {
|
||||
if (entity.name) {
|
||||
return entity.name;
|
||||
}
|
||||
const entityState = this.hass.states[entity.entity_id];
|
||||
return entityState ? computeStateName(entityState) : null;
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
return (
|
||||
computeEntityEntryName(entity, this.hass) ||
|
||||
computeDeviceNameDisplay(device, this.hass)
|
||||
);
|
||||
}
|
||||
|
||||
private _onImageLoad(ev) {
|
||||
|
@ -18,6 +18,7 @@ import { computeCssColor } from "../../../common/color/compute-color";
|
||||
import { formatShortDateTime } from "../../../common/datetime/format_date_time";
|
||||
import { storage } from "../../../common/decorators/storage";
|
||||
import type { HASSDomEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
|
||||
import { computeStateDomain } from "../../../common/entity/compute_state_domain";
|
||||
import {
|
||||
PROTOCOL_INTEGRATIONS,
|
||||
@ -40,7 +41,6 @@ import "../../../components/entity/ha-battery-icon";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-check-list-item";
|
||||
import "../../../components/ha-md-divider";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-filter-devices";
|
||||
import "../../../components/ha-filter-floor-areas";
|
||||
@ -48,6 +48,7 @@ import "../../../components/ha-filter-integrations";
|
||||
import "../../../components/ha-filter-labels";
|
||||
import "../../../components/ha-filter-states";
|
||||
import "../../../components/ha-icon-button";
|
||||
import "../../../components/ha-md-divider";
|
||||
import "../../../components/ha-md-menu-item";
|
||||
import "../../../components/ha-sub-menu";
|
||||
import { createAreaRegistryEntry } from "../../../data/area_registry";
|
||||
@ -63,10 +64,7 @@ import type {
|
||||
DeviceEntityLookup,
|
||||
DeviceRegistryEntry,
|
||||
} from "../../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
updateDeviceRegistryEntry,
|
||||
} from "../../../data/device_registry";
|
||||
import { updateDeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import {
|
||||
findBatteryChargingEntity,
|
||||
@ -426,7 +424,7 @@ export class HaConfigDeviceDashboard extends SubscribeMixin(LitElement) {
|
||||
|
||||
return {
|
||||
...device,
|
||||
name: computeDeviceName(
|
||||
name: computeDeviceNameDisplay(
|
||||
device,
|
||||
this.hass,
|
||||
deviceEntityLookup[device.id]
|
||||
|
@ -6,15 +6,13 @@ import type { CSSResultGroup, TemplateResult } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../../../common/entity/compute_device_name";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import "../../../../../components/ha-expansion-panel";
|
||||
import "../../../../../components/ha-help-tooltip";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import {
|
||||
computeDeviceName,
|
||||
subscribeDeviceRegistry,
|
||||
} from "../../../../../data/device_registry";
|
||||
import { subscribeDeviceRegistry } from "../../../../../data/device_registry";
|
||||
import type {
|
||||
ZWaveJSNodeStatisticsUpdatedMessage,
|
||||
ZWaveJSRouteStatistics,
|
||||
@ -419,7 +417,10 @@ class DialogZWaveJSNodeStatistics extends LitElement {
|
||||
(devices: DeviceRegistryEntry[]) => {
|
||||
const devicesIdToName = {};
|
||||
devices.forEach((device) => {
|
||||
devicesIdToName[device.id] = computeDeviceName(device, this.hass);
|
||||
devicesIdToName[device.id] = computeDeviceNameDisplay(
|
||||
device,
|
||||
this.hass
|
||||
);
|
||||
});
|
||||
this._deviceIDsToName = devicesIdToName;
|
||||
}
|
||||
|
@ -4,10 +4,10 @@ import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import "../../../../../components/ha-spinner";
|
||||
import { computeDeviceNameDisplay } from "../../../../../common/entity/compute_device_name";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import "../../../../../components/ha-spinner";
|
||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../../../data/device_registry";
|
||||
import type { ZWaveJSNetwork } from "../../../../../data/zwave_js";
|
||||
import {
|
||||
fetchZwaveNetworkStatus,
|
||||
@ -68,9 +68,9 @@ class DialogZWaveJSRebuildNodeRoutes extends LitElement {
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_node_routes.introduction",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
device: html`<em>
|
||||
${computeDeviceNameDisplay(this.device, this.hass!)}
|
||||
</em>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
@ -102,9 +102,9 @@ class DialogZWaveJSRebuildNodeRoutes extends LitElement {
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_node_routes.in_progress",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
device: html`<em>
|
||||
${computeDeviceNameDisplay(this.device, this.hass!)}
|
||||
</em>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
@ -128,7 +128,10 @@ class DialogZWaveJSRebuildNodeRoutes extends LitElement {
|
||||
"ui.panel.config.zwave_js.rebuild_node_routes.rebuilding_routes_failed",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>${computeDeviceNameDisplay(
|
||||
this.device,
|
||||
this.hass!
|
||||
)}</em
|
||||
>`,
|
||||
}
|
||||
)}
|
||||
@ -161,9 +164,9 @@ class DialogZWaveJSRebuildNodeRoutes extends LitElement {
|
||||
${this.hass.localize(
|
||||
"ui.panel.config.zwave_js.rebuild_node_routes.rebuilding_routes_complete",
|
||||
{
|
||||
device: html`<em
|
||||
>${computeDeviceName(this.device, this.hass!)}</em
|
||||
>`,
|
||||
device: html`<em>
|
||||
${computeDeviceNameDisplay(this.device, this.hass!)}
|
||||
</em>`,
|
||||
}
|
||||
)}
|
||||
</p>
|
||||
|
@ -6,13 +6,13 @@ import type { CSSResultGroup } from "lit";
|
||||
import { css, html, LitElement, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../../../common/entity/compute_device_name";
|
||||
import { createCloseHeading } from "../../../../../components/ha-dialog";
|
||||
import "../../../../../components/ha-file-upload";
|
||||
import "../../../../../components/ha-form/ha-form";
|
||||
import type { HaFormSchema } from "../../../../../components/ha-form/types";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import type { DeviceRegistryEntry } from "../../../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../../../data/device_registry";
|
||||
import type {
|
||||
ZWaveJSControllerFirmwareUpdateFinishedMessage,
|
||||
ZWaveJSFirmwareUpdateProgressMessage,
|
||||
@ -78,7 +78,7 @@ class DialogZWaveJSUpdateFirmwareNode extends LitElement {
|
||||
private _deviceName?: string;
|
||||
|
||||
public showDialog(params: ZWaveJSUpdateFirmwareNodeDialogParams): void {
|
||||
this._deviceName = computeDeviceName(params.device, this.hass!);
|
||||
this._deviceName = computeDeviceNameDisplay(params.device, this.hass!);
|
||||
this.device = params.device;
|
||||
this._fetchData();
|
||||
this._subscribeNodeStatus();
|
||||
|
@ -10,17 +10,18 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../../../common/entity/compute_device_name";
|
||||
import { groupBy } from "../../../../../common/util/group-by";
|
||||
import "../../../../../components/buttons/ha-progress-button";
|
||||
import type { HaProgressButton } from "../../../../../components/buttons/ha-progress-button";
|
||||
import "../../../../../components/ha-alert";
|
||||
import "../../../../../components/ha-card";
|
||||
import "../../../../../components/ha-select";
|
||||
import "../../../../../components/ha-selector/ha-selector-boolean";
|
||||
import "../../../../../components/ha-settings-row";
|
||||
import "../../../../../components/ha-svg-icon";
|
||||
import "../../../../../components/ha-textfield";
|
||||
import "../../../../../components/ha-selector/ha-selector-boolean";
|
||||
import "../../../../../components/buttons/ha-progress-button";
|
||||
import type { HaProgressButton } from "../../../../../components/buttons/ha-progress-button";
|
||||
import { computeDeviceName } from "../../../../../data/device_registry";
|
||||
import type {
|
||||
ZWaveJSNodeCapabilities,
|
||||
ZWaveJSNodeConfigParam,
|
||||
@ -35,6 +36,7 @@ import {
|
||||
invokeZWaveCCApi,
|
||||
setZwaveNodeConfigParameter,
|
||||
} from "../../../../../data/zwave_js";
|
||||
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
import "../../../../../layouts/hass-error-screen";
|
||||
import "../../../../../layouts/hass-loading-screen";
|
||||
import "../../../../../layouts/hass-tabs-subpage";
|
||||
@ -43,8 +45,6 @@ import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import "../../../ha-config-section";
|
||||
import { configTabs } from "./zwave_js-config-router";
|
||||
import "./zwave_js-custom-param";
|
||||
import { showConfirmationDialog } from "../../../../../dialogs/generic/show-dialog-box";
|
||||
import { fireEvent } from "../../../../../common/dom/fire_event";
|
||||
|
||||
const icons = {
|
||||
accepted: mdiCheckCircle,
|
||||
@ -105,7 +105,9 @@ class ZWaveJSNodeConfig extends LitElement {
|
||||
|
||||
const device = this.hass.devices[this.deviceId];
|
||||
|
||||
const deviceName = device ? computeDeviceName(device, this.hass) : "";
|
||||
const deviceName = device
|
||||
? computeDeviceNameDisplay(device, this.hass)
|
||||
: "";
|
||||
|
||||
return html`
|
||||
<hass-tabs-subpage
|
||||
|
@ -4,8 +4,8 @@ import type { CSSResultGroup, PropertyValues, TemplateResult } from "lit";
|
||||
import { LitElement, css, html, nothing } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import { dynamicElement } from "../../../../../common/dom/dynamic-element-directive";
|
||||
import { computeDeviceNameDisplay } from "../../../../../common/entity/compute_device_name";
|
||||
import "../../../../../components/ha-card";
|
||||
import { computeDeviceName } from "../../../../../data/device_registry";
|
||||
import type {
|
||||
ZWaveJSNodeCapabilities,
|
||||
ZwaveJSNodeMetadata,
|
||||
@ -20,10 +20,10 @@ import "../../../../../layouts/hass-subpage";
|
||||
import { haStyle } from "../../../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../../../types";
|
||||
import "../../../ha-config-section";
|
||||
import "./capability-controls/zwave_js-capability-control-color-switch";
|
||||
import "./capability-controls/zwave_js-capability-control-door-lock";
|
||||
import "./capability-controls/zwave_js-capability-control-multilevel-switch";
|
||||
import "./capability-controls/zwave_js-capability-control-thermostat-setback";
|
||||
import "./capability-controls/zwave_js-capability-control-door-lock";
|
||||
import "./capability-controls/zwave_js-capability-control-color-switch";
|
||||
|
||||
const CAPABILITY_CONTROLS = {
|
||||
38: "multilevel_switch",
|
||||
@ -109,7 +109,7 @@ class ZWaveJSNodeInstaller extends LitElement {
|
||||
${device
|
||||
? html`
|
||||
<div class="device-info">
|
||||
<h2>${computeDeviceName(device, this.hass)}</h2>
|
||||
<h2>${computeDeviceNameDisplay(device, this.hass)}</h2>
|
||||
<p>${device.manufacturer} ${device.model}</p>
|
||||
</div>
|
||||
`
|
||||
|
@ -1,6 +1,6 @@
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import { consume } from "@lit-labs/context";
|
||||
import "@material/mwc-list/mwc-list";
|
||||
import type { ActionDetail } from "@material/mwc-list/mwc-list-foundation";
|
||||
import {
|
||||
mdiCog,
|
||||
mdiContentDuplicate,
|
||||
@ -21,19 +21,18 @@ import { customElement, property, state } from "lit/decorators";
|
||||
import { classMap } from "lit/directives/class-map";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { computeDeviceNameDisplay } from "../../../common/entity/compute_device_name";
|
||||
import { computeDomain } from "../../../common/entity/compute_domain";
|
||||
import { computeStateName } from "../../../common/entity/compute_state_name";
|
||||
import { navigate } from "../../../common/navigate";
|
||||
import { computeRTL } from "../../../common/util/compute_rtl";
|
||||
import { afterNextRender } from "../../../common/util/render-status";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import "../../../components/device/ha-device-picker";
|
||||
import "../../../components/entity/ha-entities-picker";
|
||||
import "../../../components/ha-area-picker";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-alert";
|
||||
import "../../../components/ha-area-picker";
|
||||
import "../../../components/ha-button";
|
||||
import "../../../components/ha-button-menu";
|
||||
import "../../../components/ha-card";
|
||||
import "../../../components/ha-fab";
|
||||
import "../../../components/ha-icon-button";
|
||||
@ -41,8 +40,8 @@ import "../../../components/ha-icon-picker";
|
||||
import "../../../components/ha-list-item";
|
||||
import "../../../components/ha-svg-icon";
|
||||
import "../../../components/ha-textfield";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
import type { DeviceRegistryEntry } from "../../../data/device_registry";
|
||||
import { computeDeviceName } from "../../../data/device_registry";
|
||||
import type { EntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import { updateEntityRegistryEntry } from "../../../data/entity_registry";
|
||||
import type {
|
||||
@ -65,14 +64,15 @@ import {
|
||||
showAlertDialog,
|
||||
showConfirmationDialog,
|
||||
} from "../../../dialogs/generic/show-dialog-box";
|
||||
import { showMoreInfoDialog } from "../../../dialogs/more-info/show-ha-more-info-dialog";
|
||||
import "../../../layouts/hass-subpage";
|
||||
import { KeyboardShortcutMixin } from "../../../mixins/keyboard-shortcut-mixin";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { haStyle } from "../../../resources/styles";
|
||||
import type { HomeAssistant, Route } from "../../../types";
|
||||
import { showToast } from "../../../util/toast";
|
||||
import { showAssignCategoryDialog } from "../category/show-dialog-assign-category";
|
||||
import "../ha-config-section";
|
||||
import { PreventUnsavedMixin } from "../../../mixins/prevent-unsaved-mixin";
|
||||
import { fullEntitiesContext } from "../../../data/context";
|
||||
|
||||
interface DeviceEntities {
|
||||
id: string;
|
||||
@ -175,7 +175,7 @@ export class HaSceneEditor extends PreventUnsavedMixin(
|
||||
const device = deviceLookup[deviceId];
|
||||
const deviceEntities: string[] = deviceEntityLookup[deviceId] || [];
|
||||
outputDevices.push({
|
||||
name: computeDeviceName(
|
||||
name: computeDeviceNameDisplay(
|
||||
device,
|
||||
this.hass,
|
||||
this._deviceEntityLookup[device.id]
|
||||
|
@ -2,6 +2,7 @@ import type { PropertyValues } from "lit";
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators";
|
||||
import memoizeOne from "memoize-one";
|
||||
import { computeDeviceNameDisplay } from "../../../../common/entity/compute_device_name";
|
||||
import { navigate } from "../../../../common/navigate";
|
||||
import type { LocalizeFunc } from "../../../../common/translations/localize";
|
||||
import "../../../../components/data-table/ha-data-table";
|
||||
@ -14,7 +15,6 @@ import {
|
||||
listAssistDevices,
|
||||
listAssistPipelines,
|
||||
} from "../../../../data/assist_pipeline";
|
||||
import { computeDeviceName } from "../../../../data/device_registry";
|
||||
import "../../../../layouts/hass-subpage";
|
||||
import type { HomeAssistant } from "../../../../types";
|
||||
|
||||
@ -87,7 +87,7 @@ class AssistDevicesPage extends LitElement {
|
||||
|
||||
return {
|
||||
...assistDevice,
|
||||
name: device ? computeDeviceName(device, this.hass) : "",
|
||||
name: device ? computeDeviceNameDisplay(device, this.hass) : "",
|
||||
pipeline: isPreferred
|
||||
? localize("ui.components.pipeline-picker.preferred", {
|
||||
preferred: pipelineName,
|
||||
|
@ -1,7 +1,8 @@
|
||||
import type { HassEntity } from "home-assistant-js-websocket";
|
||||
import type { TemplateResult } from "lit";
|
||||
import { html, LitElement, nothing } from "lit";
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators";
|
||||
import { join } from "lit/directives/join";
|
||||
import { ensureArray } from "../common/array/ensure-array";
|
||||
import { computeStateDomain } from "../common/entity/compute_state_domain";
|
||||
import { computeStateName } from "../common/entity/compute_state_name";
|
||||
@ -182,12 +183,7 @@ class StateDisplay extends LitElement {
|
||||
return html`${this.hass!.formatEntityState(stateObj)}`;
|
||||
}
|
||||
|
||||
return html`
|
||||
${values.map(
|
||||
(value, index, array) =>
|
||||
html`${value}${index < array.length - 1 ? " ⸱ " : nothing}`
|
||||
)}
|
||||
`;
|
||||
return join(values, " ⸱ ");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -247,6 +247,7 @@ export const connectionMixin = <T extends Constructor<HassBaseEl>>(
|
||||
entity.ec !== undefined
|
||||
? entityReg.entity_categories[entity.ec]
|
||||
: undefined,
|
||||
has_entity_name: entity.hn,
|
||||
name: entity.en,
|
||||
icon: entity.ic,
|
||||
hidden: entity.hb,
|
||||
|
Loading…
x
Reference in New Issue
Block a user