diff --git a/src/data/script.ts b/src/data/script.ts index 807d368ead08..34d9065e9415 100644 --- a/src/data/script.ts +++ b/src/data/script.ts @@ -40,7 +40,7 @@ export const baseActionStruct = object({ enabled: optional(boolean()), }); -const targetStruct = object({ +export const targetStruct = object({ entity_id: optional(union([string(), array(string())])), device_id: optional(union([string(), array(string())])), area_id: optional(union([string(), array(string())])), diff --git a/src/panels/lovelace/cards/hui-logbook-card.ts b/src/panels/lovelace/cards/hui-logbook-card.ts index fbac8b6d22b4..b01c25ed284f 100644 --- a/src/panels/lovelace/cards/hui-logbook-card.ts +++ b/src/panels/lovelace/cards/hui-logbook-card.ts @@ -2,6 +2,8 @@ import type { CSSResultGroup, PropertyValues } from "lit"; import { css, html, LitElement, nothing } from "lit"; import { customElement, property, state } from "lit/decorators"; import { classMap } from "lit/directives/class-map"; +import memoizeOne from "memoize-one"; +import type { HassServiceTarget } from "home-assistant-js-websocket"; import { isComponentLoaded } from "../../../common/config/is_component_loaded"; import { applyThemesOnElement } from "../../../common/dom/apply_themes_on_element"; import "../../../components/ha-card"; @@ -14,6 +16,8 @@ import "../components/hui-warning"; import type { EntityConfig } from "../entity-rows/types"; import type { LovelaceCard, LovelaceCardEditor } from "../types"; import type { LogbookCardConfig } from "./types"; +import { resolveEntityIDs } from "../../../data/selector"; +import { ensureArray } from "../../../common/array/ensure-array"; export const DEFAULT_HOURS_TO_SHOW = 24; @@ -40,7 +44,9 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { ); return { - entities: foundEntities, + target: { + entity_id: foundEntities, + }, }; } @@ -50,15 +56,53 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { @state() private _time?: HaLogbook["time"]; - @state() private _entityId?: string[]; + @state() private _targetPickerValue: HassServiceTarget = {}; public getCardSize(): number { return 9 + (this._config?.title ? 1 : 0); } + public validateTarget( + config: LogbookCardConfig + ): HassServiceTarget | undefined { + if ( + (config.entities && !config.entities.length) || + (config.target && + !config.target.area_id?.length && + !config.target.device_id?.length && + !config.target.entity_id?.length && + !config.target.floor_id?.length && + !config.target.label_id?.length) + ) { + return undefined; + } + + if (config.entities) { + return { + entity_id: processConfigEntities(config.entities).map( + (entity) => entity.entity + ), + }; + } + + if (config.target?.entity_id) { + return { + ...config.target, + entity_id: processConfigEntities( + ensureArray(config.target!.entity_id) + ).map((entity) => entity.entity), + }; + } + + return config.target; + } + public setConfig(config: LogbookCardConfig): void { - if (!config.entities.length) { - throw new Error("Entities must be specified"); + const target = this.validateTarget(config); + if (!target) { + throw new Error( + "The provided target in the logbook card has no entities. Targets can include entities, devices, labels, or areas, with devices, areas, and labels resolving to entities." + ); } this._config = { @@ -68,11 +112,33 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { this._time = { recent: this._config!.hours_to_show! * 60 * 60, }; - this._entityId = processConfigEntities(config.entities).map( - (entity) => entity.entity + + this._targetPickerValue = target; + } + + private _getEntityIds(): string[] | undefined { + const entities = this._getMemoizedEntityIds( + this._targetPickerValue, + this.hass.entities, + this.hass.devices, + this.hass.areas ); + if (entities.length === 0) { + return undefined; + } + return entities; } + private _getMemoizedEntityIds = memoizeOne( + ( + targetPickerValue: HassServiceTarget, + entities: HomeAssistant["entities"], + devices: HomeAssistant["devices"], + areas: HomeAssistant["areas"] + ): string[] => + resolveEntityIDs(this.hass, targetPickerValue, entities, devices, areas) + ); + protected updated(changedProperties: PropertyValues) { super.updated(changedProperties); if (!this._config || !this.hass) { @@ -116,7 +182,7 @@ export class HuiLogbookCard extends LitElement implements LovelaceCard { -

- ${`${this.hass!.localize( - "ui.panel.lovelace.editor.card.generic.entities" - )} (${this.hass!.localize( - "ui.panel.lovelace.editor.card.config.required" - )})`} -

- - + > `; } private _entitiesChanged(ev: CustomEvent): void { - this._config = { ...this._config!, entities: ev.detail.value }; + this._config = { ...this._config!, target: ev.detail.value }; fireEvent(this, "config-changed", { config: this._config }); }