Trim device name from entities on device page (#10285)

This commit is contained in:
Paulus Schoutsen 2021-10-25 03:56:33 -07:00 committed by GitHub
parent f77339ad85
commit 279f3e1183
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 56 additions and 21 deletions

View File

@ -0,0 +1,24 @@
/**
* Strips a device name from an entity name.
* @param entityName the entity name
* @param lowerCasedPrefixWithSpaceSuffix the prefix to strip, lower cased with a space suffix
* @returns
*/
export const stripPrefixFromEntityName = (
entityName: string,
lowerCasedPrefixWithSpaceSuffix: string
) => {
if (!entityName.toLowerCase().startsWith(lowerCasedPrefixWithSpaceSuffix)) {
return undefined;
}
const newName = entityName.substring(lowerCasedPrefixWithSpaceSuffix.length);
// If first word already has an upper case letter (e.g. from brand name)
// leave as-is, otherwise capitalize the first word.
return hasUpperCase(newName.substr(0, newName.indexOf(" ")))
? newName
: newName[0].toUpperCase() + newName.slice(1);
};
const hasUpperCase = (str: string): boolean => str.toLowerCase() !== str;

View File

@ -15,18 +15,23 @@ import { domainIcon } from "../../../../common/entity/domain_icon";
import "../../../../components/entity/state-badge"; import "../../../../components/entity/state-badge";
import "../../../../components/ha-card"; import "../../../../components/ha-card";
import "../../../../components/ha-icon"; import "../../../../components/ha-icon";
import { HomeAssistant } from "../../../../types"; import type { LovelaceRowConfig } from "../../../lovelace/entity-rows/types";
import { HuiErrorCard } from "../../../lovelace/cards/hui-error-card"; import type { HomeAssistant } from "../../../../types";
import type { HuiErrorCard } from "../../../lovelace/cards/hui-error-card";
import { createRowElement } from "../../../lovelace/create-element/create-row-element"; import { createRowElement } from "../../../lovelace/create-element/create-row-element";
import { addEntitiesToLovelaceView } from "../../../lovelace/editor/add-entities-to-view"; import { addEntitiesToLovelaceView } from "../../../lovelace/editor/add-entities-to-view";
import { LovelaceRow } from "../../../lovelace/entity-rows/types"; import { LovelaceRow } from "../../../lovelace/entity-rows/types";
import { showEntityEditorDialog } from "../../entities/show-dialog-entity-editor"; import { showEntityEditorDialog } from "../../entities/show-dialog-entity-editor";
import { EntityRegistryStateEntry } from "../ha-config-device-page"; import { EntityRegistryStateEntry } from "../ha-config-device-page";
import { computeStateName } from "../../../../common/entity/compute_state_name";
import { stripPrefixFromEntityName } from "../../../../common/entity/strip_prefix_from_entity_name";
@customElement("ha-device-entities-card") @customElement("ha-device-entities-card")
export class HaDeviceEntitiesCard extends LitElement { export class HaDeviceEntitiesCard extends LitElement {
@property() public header!: string; @property() public header!: string;
@property() public deviceName!: string;
@property({ attribute: false }) public hass!: HomeAssistant; @property({ attribute: false }) public hass!: HomeAssistant;
@property() public entities!: EntityRegistryStateEntry[]; @property() public entities!: EntityRegistryStateEntry[];
@ -119,9 +124,21 @@ export class HaDeviceEntitiesCard extends LitElement {
} }
private _renderEntity(entry: EntityRegistryStateEntry): TemplateResult { private _renderEntity(entry: EntityRegistryStateEntry): TemplateResult {
const element = createRowElement({ entity: entry.entity_id }); const config: LovelaceRowConfig = {
entity: entry.entity_id,
};
const element = createRowElement(config);
if (this.hass) { if (this.hass) {
element.hass = this.hass; element.hass = this.hass;
const state = this.hass.states[entry.entity_id];
const name = stripPrefixFromEntityName(
computeStateName(state),
`${this.deviceName} `.toLowerCase()
);
if (name) {
config.name = name;
}
} }
// @ts-ignore // @ts-ignore
element.entry = entry; element.entry = entry;

View File

@ -179,6 +179,7 @@ export class HaConfigDevicePage extends LitElement {
`; `;
} }
const deviceName = computeDeviceName(device, this.hass);
const integrations = this._integrations(device, this.entries); const integrations = this._integrations(device, this.entries);
const entities = this._entities(this.deviceId, this.entities); const entities = this._entities(this.deviceId, this.entities);
const entitiesByCategory = this._entitiesByCategory(entities); const entitiesByCategory = this._entitiesByCategory(entities);
@ -204,9 +205,7 @@ export class HaConfigDevicePage extends LitElement {
${ ${
this.narrow this.narrow
? html` ? html`
<span slot="header"> <span slot="header">${deviceName}</span>
${computeDeviceName(device, this.hass)}
</span>
<ha-icon-button <ha-icon-button
slot="toolbar-icon" slot="toolbar-icon"
.path=${mdiPencil} .path=${mdiPencil}
@ -230,7 +229,7 @@ export class HaConfigDevicePage extends LitElement {
: html` : html`
<div class="header-name"> <div class="header-name">
<div> <div>
<h1>${computeDeviceName(device, this.hass)}</h1> <h1>${deviceName}</h1>
${area ${area
? html` ? html`
<a href="/config/areas/area/${area.area_id}" <a href="/config/areas/area/${area.area_id}"
@ -353,6 +352,7 @@ export class HaConfigDevicePage extends LitElement {
.header=${this.hass.localize( .header=${this.hass.localize(
`ui.panel.config.devices.entities.${category}` `ui.panel.config.devices.entities.${category}`
)} )}
.deviceName=${deviceName}
.entities=${entitiesByCategory[category]} .entities=${entitiesByCategory[category]}
.showDisabled=${device.disabled_by !== null} .showDisabled=${device.disabled_by !== null}
> >

View File

@ -3,6 +3,7 @@ import { computeDomain } from "../../../common/entity/compute_domain";
import { computeStateDomain } from "../../../common/entity/compute_state_domain"; import { computeStateDomain } from "../../../common/entity/compute_state_domain";
import { computeStateName } from "../../../common/entity/compute_state_name"; import { computeStateName } from "../../../common/entity/compute_state_name";
import { splitByGroups } from "../../../common/entity/split_by_groups"; import { splitByGroups } from "../../../common/entity/split_by_groups";
import { stripPrefixFromEntityName } from "../../../common/entity/strip_prefix_from_entity_name";
import { stringCompare } from "../../../common/string/compare"; import { stringCompare } from "../../../common/string/compare";
import { LocalizeFunc } from "../../../common/translations/localize"; import { LocalizeFunc } from "../../../common/translations/localize";
import type { AreaRegistryEntry } from "../../../data/area_registry"; import type { AreaRegistryEntry } from "../../../data/area_registry";
@ -92,7 +93,7 @@ export const computeCards = (
const entities: Array<string | LovelaceRowConfig> = []; const entities: Array<string | LovelaceRowConfig> = [];
const titlePrefix = entityCardOptions.title const titlePrefix = entityCardOptions.title
? `${entityCardOptions.title} ` ? `${entityCardOptions.title} `.toLowerCase()
: undefined; : undefined;
for (const [entityId, stateObj] of states) { for (const [entityId, stateObj] of states) {
@ -153,16 +154,18 @@ export const computeCards = (
) { ) {
// Do nothing. // Do nothing.
} else { } else {
let name: string; let name: string | undefined;
const entityConf = const entityConf =
titlePrefix && titlePrefix &&
stateObj && stateObj &&
// eslint-disable-next-line no-cond-assign // eslint-disable-next-line no-cond-assign
(name = computeStateName(stateObj)) !== titlePrefix && (name = stripPrefixFromEntityName(
name.startsWith(titlePrefix) computeStateName(stateObj),
titlePrefix
))
? { ? {
entity: entityId, entity: entityId,
name: adjustName(name.substr(titlePrefix.length)), name,
} }
: entityId; : entityId;
@ -181,15 +184,6 @@ export const computeCards = (
return cards; return cards;
}; };
const hasUpperCase = (str: string): boolean => str.toLowerCase() !== str;
const adjustName = (name: string): string =>
// If first word already has an upper case letter (e.g. from brand name)
// leave as-is, otherwise capitalize the first word.
hasUpperCase(name.substr(0, name.indexOf(" ")))
? name
: name[0].toUpperCase() + name.slice(1);
const computeDefaultViewStates = ( const computeDefaultViewStates = (
entities: HassEntities, entities: HassEntities,
entityEntries: EntityRegistryEntry[] entityEntries: EntityRegistryEntry[]