diff --git a/src/panels/lovelace/cards/heading/hui-heading-entity.ts b/src/panels/lovelace/cards/heading/hui-heading-entity.ts index f64ae58448..d91f24fe91 100644 --- a/src/panels/lovelace/cards/heading/hui-heading-entity.ts +++ b/src/panels/lovelace/cards/heading/hui-heading-entity.ts @@ -24,6 +24,7 @@ import { attachConditionMediaQueriesListeners, checkConditionsMet, } from "../../common/validate-condition"; +import { DEFAULT_CONFIG } from "../../editor/heading-entity/hui-heading-entity-editor"; import type { HeadingEntityConfig } from "../types"; @customElement("hui-heading-entity") @@ -54,6 +55,7 @@ export class HuiHeadingEntity extends LitElement { : configOrString; return { + ...DEFAULT_CONFIG, tap_action: { action: "none", }, @@ -133,16 +135,24 @@ export class HuiHeadingEntity extends LitElement { role=${ifDefined(actionable ? "button" : undefined)} tabindex=${ifDefined(actionable ? "0" : undefined)} > - - + ${config.show_icon + ? html` + + ` + : nothing} + ${config.show_state + ? html` + + ` + : nothing} `; } diff --git a/src/panels/lovelace/cards/types.ts b/src/panels/lovelace/cards/types.ts index ca844ae039..6fb0a6fd90 100644 --- a/src/panels/lovelace/cards/types.ts +++ b/src/panels/lovelace/cards/types.ts @@ -505,8 +505,10 @@ export interface TileCardConfig extends LovelaceCardConfig { export interface HeadingEntityConfig { entity: string; - content?: string | string[]; + state_content?: string | string[]; icon?: string; + show_state?: boolean; + show_icon?: boolean; tap_action?: ActionConfig; visibility?: Condition[]; } diff --git a/src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts b/src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts index e331227463..5673ab2dce 100644 --- a/src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts +++ b/src/panels/lovelace/editor/heading-entity/hui-heading-entity-editor.ts @@ -1,4 +1,4 @@ -import { mdiEye, mdiGestureTap } from "@mdi/js"; +import { mdiEye, mdiGestureTap, mdiPalette } from "@mdi/js"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import memoizeOne from "memoize-one"; @@ -6,12 +6,14 @@ import { any, array, assert, + boolean, object, optional, string, union, } from "superstruct"; import { fireEvent } from "../../../../common/dom/fire_event"; +import { LocalizeFunc } from "../../../../common/translations/localize"; import "../../../../components/ha-expansion-panel"; import "../../../../components/ha-form/ha-form"; import type { @@ -26,14 +28,25 @@ import "../conditions/ha-card-conditions-editor"; import { configElementStyle } from "../config-elements/config-elements-style"; import { actionConfigStruct } from "../structs/action-struct"; +export const DEFAULT_CONFIG: Partial = { + show_state: true, + show_icon: true, +}; + const entityConfigStruct = object({ entity: string(), - content: optional(union([string(), array(string())])), icon: optional(string()), + state_content: optional(union([string(), array(string())])), + show_state: optional(boolean()), + show_icon: optional(boolean()), tap_action: optional(actionConfigStruct), visibility: optional(array(any())), }); +type FormData = HeadingEntityConfig & { + displayed_elements?: string[]; +}; + @customElement("hui-heading-entity-editor") export class HuiHeadingEntityEditor extends LitElement @@ -47,25 +60,59 @@ export class HuiHeadingEntityEditor public setConfig(config: HeadingEntityConfig): void { assert(config, entityConfigStruct); - this._config = config; + this._config = { + ...DEFAULT_CONFIG, + ...config, + }; } private _schema = memoizeOne( - () => + (localize: LocalizeFunc) => [ { name: "entity", selector: { entity: {} }, }, { - name: "icon", - selector: { icon: {} }, - context: { icon_entity: "entity" }, - }, - { - name: "content", - selector: { ui_state_content: {} }, - context: { filter_entity: "entity" }, + name: "appearance", + type: "expandable", + flatten: true, + iconPath: mdiPalette, + schema: [ + { + name: "icon", + selector: { icon: {} }, + context: { icon_entity: "entity" }, + }, + { + name: "displayed_elements", + selector: { + select: { + mode: "list", + multiple: true, + options: [ + { + value: "state", + label: localize( + `ui.panel.lovelace.editor.card.heading.entity_config.displayed_elements_options.state` + ), + }, + { + value: "icon", + label: localize( + `ui.panel.lovelace.editor.card.heading.entity_config.displayed_elements_options.icon` + ), + }, + ], + }, + }, + }, + { + name: "state_content", + selector: { ui_state_content: {} }, + context: { filter_entity: "entity" }, + }, + ], }, { name: "interactions", @@ -86,18 +133,30 @@ export class HuiHeadingEntityEditor ] as const satisfies readonly HaFormSchema[] ); + private _displayedElements = memoizeOne((config: HeadingEntityConfig) => { + const elements: string[] = []; + if (config.show_state) elements.push("state"); + if (config.show_icon) elements.push("icon"); + return elements; + }); + protected render() { if (!this.hass || !this._config) { return nothing; } - const schema = this._schema(); + const schema = this._schema(this.hass.localize); + + const data: FormData = { + ...this._config, + displayed_elements: this._displayedElements(this._config), + }; const conditions = this._config.visibility ?? []; return html` > ) => { switch (schema.name) { - case "content": + case "state_content": + case "displayed_elements": + case "appearance": return this.hass!.localize( `ui.panel.lovelace.editor.card.heading.entity_config.${schema.name}` ); diff --git a/src/translations/en.json b/src/translations/en.json index 46af0984bf..b9d4e7f24d 100644 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -6007,9 +6007,15 @@ }, "entities": "Entities", "entity_config": { - "content": "Content", "visibility": "Visibility", - "visibility_explanation": "The entity will be shown when ALL conditions below are fulfilled. If no conditions are set, the entity will always be shown." + "visibility_explanation": "The entity will be shown when ALL conditions below are fulfilled. If no conditions are set, the entity will always be shown.", + "appearance": "Appearance", + "state_content": "State content", + "displayed_elements": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements%]", + "displayed_elements_options": { + "icon": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements_options::icon%]", + "state": "[%key:ui::panel::lovelace::editor::badge::entity::displayed_elements_options::state%]" + } }, "default_heading": "Kitchen" },