From 67b23f4dea68118799d22f50ee1fa293f0418fa8 Mon Sep 17 00:00:00 2001 From: Quentame Date: Tue, 14 May 2024 01:22:27 +0000 Subject: [PATCH] Add entity-filter editor config --- .../lovelace/cards/hui-entity-filter-card.ts | 7 +- .../hui-entity-filter-card-editor.ts | 154 ++++++++++++++++++ 2 files changed, 160 insertions(+), 1 deletion(-) create mode 100644 src/panels/lovelace/editor/config-elements/hui-entity-filter-card-editor.ts diff --git a/src/panels/lovelace/cards/hui-entity-filter-card.ts b/src/panels/lovelace/cards/hui-entity-filter-card.ts index ab6fb943b265..4bf5b929e392 100644 --- a/src/panels/lovelace/cards/hui-entity-filter-card.ts +++ b/src/panels/lovelace/cards/hui-entity-filter-card.ts @@ -13,7 +13,7 @@ import { } from "../common/validate-condition"; import { createCardElement } from "../create-element/create-card-element"; import { EntityFilterEntityConfig } from "../entity-rows/types"; -import { LovelaceCard } from "../types"; +import { LovelaceCard, LovelaceCardEditor } from "../types"; import { EntityFilterCardConfig } from "./types"; @customElement("hui-entity-filter-card") @@ -21,6 +21,11 @@ export class HuiEntityFilterCard extends ReactiveElement implements LovelaceCard { + public static async getConfigElement(): Promise { + await import("../editor/config-elements/hui-entity-filter-card-editor"); + return document.createElement("hui-entity-filter-card-editor"); + } + public static getStubConfig( hass: HomeAssistant, entities: string[], diff --git a/src/panels/lovelace/editor/config-elements/hui-entity-filter-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-entity-filter-card-editor.ts new file mode 100644 index 000000000000..1d9c035a2602 --- /dev/null +++ b/src/panels/lovelace/editor/config-elements/hui-entity-filter-card-editor.ts @@ -0,0 +1,154 @@ +import "@material/mwc-tab-bar/mwc-tab-bar"; +import "@material/mwc-tab/mwc-tab"; +import { LitElement, html, nothing } from "lit"; +import { customElement, property, query, state } from "lit/decorators"; +import { + any, + array, + assert, + assign, + literal, + number, + object, + optional, + string, + union, +} from "superstruct"; +import { storage } from "../../../../common/decorators/storage"; +import { fireEvent } from "../../../../common/dom/fire_event"; +import "../../../../components/ha-button"; +import "../../../../components/ha-list-item"; +import "../../../../components/ha-svg-icon"; +import { LovelaceCardConfig } from "../../../../data/lovelace/config/card"; +import { LovelaceConfig } from "../../../../data/lovelace/config/types"; +import type { HomeAssistant } from "../../../../types"; +import type { EntityFilterCardConfig } from "../../cards/types"; +import type { EntityFilterEntityConfig } from "../../entity-rows/types"; +import type { LovelaceCardEditor } from "../../types"; +import "../card-editor/hui-card-element-editor"; +import type { HuiCardElementEditor } from "../card-editor/hui-card-element-editor"; +import "../card-editor/hui-card-picker"; +import "../conditions/ha-card-conditions-editor"; +import "../hui-element-editor"; +import { baseLovelaceCardConfig } from "../structs/base-card-struct"; +import { entitiesConfigStruct } from "../structs/entities-struct"; +import { SchemaUnion } from "../../../../components/ha-form/types"; +import { processEditorEntities } from "../process-editor-entities"; + +const cardConfigStruct = assign( + baseLovelaceCardConfig, + object({ + card: optional( + object({ + title: optional(union([string(), number()])), + type: optional(union([literal("entities"), literal("glance")])), + }) + ), + entities: array(entitiesConfigStruct), + conditions: optional(array(any())), + }) +); + +const SCHEMA = [ + { name: "title", selector: { text: {} } }, + { name: "type", selector: { text: {} } }, +] as const; + +@customElement("hui-entity-filter-card-editor") +export class HuiEntityFilterCardEditor + extends LitElement + implements LovelaceCardEditor +{ + @property({ attribute: false }) public hass?: HomeAssistant; + + @property({ attribute: false }) public lovelace?: LovelaceConfig; + + @storage({ + key: "lovelaceClipboard", + state: false, + subscribe: false, + storage: "sessionStorage", + }) + protected _clipboard?: LovelaceCardConfig; + + @state() private _config?: EntityFilterCardConfig; + + @state() private _configEntities?: EntityFilterEntityConfig[]; + + @query("hui-card-element-editor") + private _cardEditorEl?: HuiCardElementEditor; + + public setConfig(config: EntityFilterCardConfig): void { + assert(config, cardConfigStruct); + this._config = config; + } + + public focusYamlEditor() { + this._cardEditorEl?.focusYamlEditor(); + } + + protected render() { + if (!this.hass || !this._config) { + return nothing; + } + + return html` + + + + + `; + } + + private _valueChanged(ev: CustomEvent): void { + const config = ev.detail.value; + fireEvent(this, "config-changed", { config }); + } + + private _entitiesChanged(ev: CustomEvent): void { + let config = this._config!; + config = { ...config, entities: ev.detail.entities! }; + + this._configEntities = processEditorEntities(this._config!.entities); + fireEvent(this, "config-changed", { config }); + } + + private _conditionChanged(ev: CustomEvent) { + ev.stopPropagation(); + if (!this._config) { + return; + } + const conditions = ev.detail.value; + this._config = { ...this._config, conditions }; + fireEvent(this, "config-changed", { config: this._config }); + } + + private _computeLabelCallback = (schema: SchemaUnion) => { + switch (schema.name) { + default: + return this.hass!.localize( + `ui.panel.lovelace.editor.card.generic.${schema.name}` + ); + } + }; +} + +declare global { + interface HTMLElementTagNameMap { + "hui-entity-filter-card-editor": HuiEntityFilterCardEditor; + } +}