Compare commits

...

1 Commits

Author SHA1 Message Date
Paul Bottein
5be7bad176 Allow to add context to tile card secondary line (#28995) 2026-01-14 19:48:27 +01:00
7 changed files with 97 additions and 6 deletions

View File

@@ -7,6 +7,7 @@ import memoizeOne from "memoize-one";
import { ensureArray } from "../../common/array/ensure-array";
import { fireEvent } from "../../common/dom/fire_event";
import { computeDomain } from "../../common/entity/compute_domain";
import { getEntityContext } from "../../common/entity/context/get_entity_context";
import {
STATE_DISPLAY_SPECIAL_CONTENT,
STATE_DISPLAY_SPECIAL_CONTENT_DOMAINS,
@@ -95,6 +96,9 @@ export class HaStateContentPicker extends LitElement {
@property({ type: Boolean, attribute: "allow-name" }) public allowName =
false;
@property({ type: Boolean, attribute: "allow-context" }) public allowContext =
false;
@property() public label?: string;
@property() public value?: string[] | string;
@@ -106,7 +110,12 @@ export class HaStateContentPicker extends LitElement {
private _editIndex?: number;
private _getItems = memoizeOne(
(entityId?: string, stateObj?: HassEntity, allowName?: boolean) => {
(
entityId?: string,
stateObj?: HassEntity,
allowName?: boolean,
allowContext?: boolean
) => {
const domain = entityId ? computeDomain(entityId) : undefined;
const items: PickerComboBoxItem[] = [
{
@@ -149,6 +158,52 @@ export class HaStateContentPicker extends LitElement {
"ui.components.state-content-picker.last_updated"
),
},
...(allowContext && stateObj
? (() => {
const context = getEntityContext(
stateObj,
this.hass.entities,
this.hass.devices,
this.hass.areas,
this.hass.floors
);
const contextItems: PickerComboBoxItem[] = [];
if (context.device) {
contextItems.push({
id: "device_name",
primary: this.hass.localize(
"ui.components.state-content-picker.device_name"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.device_name"
),
});
}
if (context.area) {
contextItems.push({
id: "area_name",
primary: this.hass.localize(
"ui.components.state-content-picker.area_name"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.area_name"
),
});
}
if (context.floor) {
contextItems.push({
id: "floor_name",
primary: this.hass.localize(
"ui.components.state-content-picker.floor_name"
),
sorting_label: this.hass.localize(
"ui.components.state-content-picker.floor_name"
),
});
}
return contextItems;
})()
: []),
...(domain
? STATE_DISPLAY_SPECIAL_CONTENT.filter((content) =>
STATE_DISPLAY_SPECIAL_CONTENT_DOMAINS[domain]?.includes(content)
@@ -300,7 +355,8 @@ export class HaStateContentPicker extends LitElement {
const items = this._getItems(
this.entityId,
stateObjForItems,
this.allowName
this.allowName,
this.allowContext
);
return items.find((item) => item.id === value)?.primary;
}
@@ -343,7 +399,12 @@ export class HaStateContentPicker extends LitElement {
const stateObj = this.entityId
? this.hass.states[this.entityId]
: undefined;
const items = this._getItems(this.entityId, stateObj, this.allowName);
const items = this._getItems(
this.entityId,
stateObj,
this.allowName,
this.allowContext
);
const currentValue =
this._editIndex != null ? this._value[this._editIndex] : undefined;
@@ -367,7 +428,12 @@ export class HaStateContentPicker extends LitElement {
const stateObj = this.entityId
? this.hass.states[this.entityId]
: undefined;
const items = this._getItems(this.entityId, stateObj, this.allowName);
const items = this._getItems(
this.entityId,
stateObj,
this.allowName,
this.allowContext
);
// If the search string does not match with the id of any of the items,
// offer to add it as a custom attribute

View File

@@ -37,6 +37,7 @@ export class HaSelectorUiStateContent extends SubscribeMixin(LitElement) {
.disabled=${this.disabled}
.required=${this.required}
.allowName=${this.selector.ui_state_content?.allow_name || false}
.allowContext=${this.selector.ui_state_content?.allow_context || false}
></ha-entity-state-content-picker>
`;
}

View File

@@ -501,6 +501,7 @@ export interface UiStateContentSelector {
ui_state_content: {
entity_id?: string;
allow_name?: boolean;
allow_context?: boolean;
} | null;
}

View File

@@ -144,7 +144,9 @@ export class HuiTileCardEditor
{
name: "state_content",
selector: {
ui_state_content: {},
ui_state_content: {
allow_context: true,
},
},
context: {
filter_entity: "entity",

View File

@@ -83,6 +83,15 @@ export class CommonControlsSectionStrategy extends ReactiveElement {
({
type: "tile",
entity: entityId,
name: [
{
type: "device",
},
{
type: "entity",
},
],
state_content: ["state", "area_name"],
show_entity_picture: true,
}) satisfies TileCardConfig
)

View File

@@ -103,6 +103,15 @@ class StateDisplay extends LitElement {
return html`${this.name}`;
}
if (
content === "device_name" ||
content === "area_name" ||
content === "floor_name"
) {
const type = content.replace("_name", "") as "device" | "area" | "floor";
return this.hass.formatEntityName(stateObj, { type }) || undefined;
}
let relativeDateTime: string | Date | undefined;
// Check last-changed for backwards compatibility

View File

@@ -1298,7 +1298,10 @@
"last_changed": "Last changed",
"last_updated": "Last updated",
"remaining_time": "Remaining time",
"install_status": "Install status"
"install_status": "Install status",
"device_name": "Device name",
"area_name": "Area name",
"floor_name": "Floor name"
},
"multi-textfield": {
"add_item": "Add {item}"