From 4719775926384776f98bf2672b418a5f23b1b790 Mon Sep 17 00:00:00 2001 From: Paul Bottein Date: Mon, 5 Aug 2024 17:14:10 +0200 Subject: [PATCH] Allow name in state content for badges (#21576) --- .../entity/ha-entity-state-content-picker.ts | 91 +++++++++++-------- .../ha-selector-ui-state-content.ts | 1 + src/data/selector.ts | 1 + .../lovelace/badges/hui-entity-badge.ts | 1 + src/panels/lovelace/cards/hui-tile-card.ts | 1 + .../hui-entity-badge-editor.ts | 4 +- src/state-display/state-display.ts | 5 + src/translations/en.json | 1 + 8 files changed, 66 insertions(+), 39 deletions(-) diff --git a/src/components/entity/ha-entity-state-content-picker.ts b/src/components/entity/ha-entity-state-content-picker.ts index b4e1001932..bdc75c9c3a 100644 --- a/src/components/entity/ha-entity-state-content-picker.ts +++ b/src/components/entity/ha-entity-state-content-picker.ts @@ -81,6 +81,9 @@ class HaEntityStatePicker extends LitElement { @property({ type: Boolean }) public required = false; + @property({ type: Boolean, attribute: "allow-name" }) public allowName = + false; + @property() public label?: string; @property() public value?: string[] | string; @@ -95,43 +98,55 @@ class HaEntityStatePicker extends LitElement { return !(!changedProps.has("_opened") && this._opened); } - private options = memoizeOne((entityId?: string, stateObj?: HassEntity) => { - const domain = entityId ? computeDomain(entityId) : undefined; - return [ - { - label: this.hass.localize("ui.components.state-content-picker.state"), - value: "state", - }, - { - label: this.hass.localize( - "ui.components.state-content-picker.last_changed" - ), - value: "last_changed", - }, - { - label: this.hass.localize( - "ui.components.state-content-picker.last_updated" - ), - value: "last_updated", - }, - ...(domain - ? STATE_DISPLAY_SPECIAL_CONTENT.filter((content) => - STATE_DISPLAY_SPECIAL_CONTENT_DOMAINS[domain]?.includes(content) - ).map((content) => ({ - label: this.hass.localize( - `ui.components.state-content-picker.${content}` - ), - value: content, - })) - : []), - ...Object.keys(stateObj?.attributes ?? {}) - .filter((a) => !HIDDEN_ATTRIBUTES.includes(a)) - .map((attribute) => ({ - value: attribute, - label: this.hass.formatEntityAttributeName(stateObj!, attribute), - })), - ]; - }); + private options = memoizeOne( + (entityId?: string, stateObj?: HassEntity, allowName?: boolean) => { + const domain = entityId ? computeDomain(entityId) : undefined; + return [ + { + label: this.hass.localize("ui.components.state-content-picker.state"), + value: "state", + }, + ...(allowName + ? [ + { + label: this.hass.localize( + "ui.components.state-content-picker.name" + ), + value: "name", + }, + ] + : []), + { + label: this.hass.localize( + "ui.components.state-content-picker.last_changed" + ), + value: "last_changed", + }, + { + label: this.hass.localize( + "ui.components.state-content-picker.last_updated" + ), + value: "last_updated", + }, + ...(domain + ? STATE_DISPLAY_SPECIAL_CONTENT.filter((content) => + STATE_DISPLAY_SPECIAL_CONTENT_DOMAINS[domain]?.includes(content) + ).map((content) => ({ + label: this.hass.localize( + `ui.components.state-content-picker.${content}` + ), + value: content, + })) + : []), + ...Object.keys(stateObj?.attributes ?? {}) + .filter((a) => !HIDDEN_ATTRIBUTES.includes(a)) + .map((attribute) => ({ + value: attribute, + label: this.hass.formatEntityAttributeName(stateObj!, attribute), + })), + ]; + } + ); private _filter = ""; @@ -146,7 +161,7 @@ class HaEntityStatePicker extends LitElement { ? this.hass.states[this.entityId] : undefined; - const options = this.options(this.entityId, stateObj); + const options = this.options(this.entityId, stateObj, this.allowName); const optionItems = options.filter( (option) => !this._value.includes(option.value) ); diff --git a/src/components/ha-selector/ha-selector-ui-state-content.ts b/src/components/ha-selector/ha-selector-ui-state-content.ts index c0d521b939..179671e84f 100644 --- a/src/components/ha-selector/ha-selector-ui-state-content.ts +++ b/src/components/ha-selector/ha-selector-ui-state-content.ts @@ -36,6 +36,7 @@ export class HaSelectorUiStateContent extends SubscribeMixin(LitElement) { .helper=${this.helper} .disabled=${this.disabled} .required=${this.required} + .allowName=${this.selector.ui_state_content?.allow_name} > `; } diff --git a/src/data/selector.ts b/src/data/selector.ts index c4b385b136..13aa16647e 100644 --- a/src/data/selector.ts +++ b/src/data/selector.ts @@ -461,6 +461,7 @@ export interface UiStateContentSelector { // eslint-disable-next-line @typescript-eslint/ban-types ui_state_content: { entity_id?: string; + allow_name?: boolean; } | null; } diff --git a/src/panels/lovelace/badges/hui-entity-badge.ts b/src/panels/lovelace/badges/hui-entity-badge.ts index 05a6839da0..e448646ab0 100644 --- a/src/panels/lovelace/badges/hui-entity-badge.ts +++ b/src/panels/lovelace/badges/hui-entity-badge.ts @@ -144,6 +144,7 @@ export class HuiEntityBadge extends LitElement implements LovelaceBadge { .stateObj=${stateObj} .hass=${this.hass} .content=${this._config.state_content} + .name=${this._config.name} > `; diff --git a/src/panels/lovelace/cards/hui-tile-card.ts b/src/panels/lovelace/cards/hui-tile-card.ts index 19ece5430b..c015c22f3c 100644 --- a/src/panels/lovelace/cards/hui-tile-card.ts +++ b/src/panels/lovelace/cards/hui-tile-card.ts @@ -251,6 +251,7 @@ export class HuiTileCard extends LitElement implements LovelaceCard { .stateObj=${stateObj} .hass=${this.hass} .content=${this._config.state_content} + .name=${this._config.name} > `; diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts index d1000fbb5d..64944fbe2f 100644 --- a/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts +++ b/src/panels/lovelace/editor/config-elements/hui-entity-badge-editor.ts @@ -122,7 +122,9 @@ export class HuiEntityBadgeEditor { name: "state_content", selector: { - ui_state_content: {}, + ui_state_content: { + allow_name: true, + }, }, context: { filter_entity: "entity", diff --git a/src/state-display/state-display.ts b/src/state-display/state-display.ts index a1042681a8..aaf54014d2 100644 --- a/src/state-display/state-display.ts +++ b/src/state-display/state-display.ts @@ -55,6 +55,8 @@ class StateDisplay extends LitElement { @property({ attribute: false }) public content?: StateContent; + @property({ attribute: false }) public name?: string; + protected createRenderRoot() { return this; } @@ -88,6 +90,9 @@ class StateDisplay extends LitElement { return this.hass!.formatEntityState(stateObj); } + if (content === "name") { + return html`${this.name || stateObj.attributes.friendly_name}`; + } // Check last-changed for backwards compatibility if (content === "last_changed" || content === "last-changed") { return html` diff --git a/src/translations/en.json b/src/translations/en.json index 7524fc65c3..f6e588e775 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1026,6 +1026,7 @@ }, "state-content-picker": { "state": "State", + "name": "Name", "last_changed": "Last changed", "last_updated": "Last updated", "remaining_time": "Remaining time",