From a0a4fcaf5f40b88956145b7de624a859bb3fc4e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Thomas=20Lov=C3=A9n?= Date: Tue, 31 Mar 2020 16:20:09 +0200 Subject: [PATCH] Allow custom cards in card picker (#5122) * Allow custom cards in card picker * Lint. "Custom:" prefix to card names * Address review comments * Simplifications. Translation fixes. * Less magic * Move CUSTOM_TYPE_PREFIX * Update hui-card-picker.ts Co-authored-by: Bram Kragten --- src/data/lovelace_custom_cards.ts | 23 +++++++ .../create-element/create-element-base.ts | 2 +- .../editor/card-editor/hui-card-picker.ts | 62 ++++++++++++++----- src/translations/en.json | 4 ++ 4 files changed, 76 insertions(+), 15 deletions(-) create mode 100644 src/data/lovelace_custom_cards.ts diff --git a/src/data/lovelace_custom_cards.ts b/src/data/lovelace_custom_cards.ts new file mode 100644 index 0000000000..2e021e7a6f --- /dev/null +++ b/src/data/lovelace_custom_cards.ts @@ -0,0 +1,23 @@ +export interface CustomCardEntry { + type: string; + name?: string; + description?: string; + preview?: boolean; +} + +export interface CustomCardsWindow { + customCards?: CustomCardEntry[]; +} + +export const CUSTOM_TYPE_PREFIX = "custom:"; + +const customCardsWindow = window as CustomCardsWindow; + +if (!("customCards" in customCardsWindow)) { + customCardsWindow.customCards = []; +} + +export const customCards = customCardsWindow.customCards!; + +export const getCustomCardEntry = (type: string) => + customCards.find((card) => card.type === type); diff --git a/src/panels/lovelace/create-element/create-element-base.ts b/src/panels/lovelace/create-element/create-element-base.ts index 4c8879b93c..c2c01cb279 100644 --- a/src/panels/lovelace/create-element/create-element-base.ts +++ b/src/panels/lovelace/create-element/create-element-base.ts @@ -17,8 +17,8 @@ import { fireEvent } from "../../../common/dom/fire_event"; import { LovelaceElementConfig, LovelaceElement } from "../elements/types"; import { LovelaceRow, LovelaceRowConfig } from "../entity-rows/types"; import { LovelaceHeaderFooterConfig } from "../header-footer/types"; +import { CUSTOM_TYPE_PREFIX } from "../../../data/lovelace_custom_cards"; -const CUSTOM_TYPE_PREFIX = "custom:"; const TIMEOUT = 2000; interface CreateElementConfigTypes { diff --git a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts index 374c650016..b69ab18973 100644 --- a/src/panels/lovelace/editor/card-editor/hui-card-picker.ts +++ b/src/panels/lovelace/editor/card-editor/hui-card-picker.ts @@ -23,6 +23,11 @@ import { calcUnusedEntities, } from "../../common/compute-unused-entities"; import { UNKNOWN, UNAVAILABLE } from "../../../../data/entity"; +import { + customCards, + getCustomCardEntry, + CUSTOM_TYPE_PREFIX, +} from "../../../../data/lovelace_custom_cards"; const previewCards: string[] = [ "alarm-panel", @@ -100,6 +105,24 @@ export class HuiCardPicker extends LitElement { `; })} + ${customCards.length + ? html` +
+ ${customCards.map((card) => { + return html` + ${until( + this._renderCardElement(card.type, true, true), + html` +
+ +
+ ` + )} + `; + })} +
+ ` + : ""}
{ + const customCard = isCustom ? getCustomCardEntry(type) : undefined; + if (isCustom) { + type = `${CUSTOM_TYPE_PREFIX}${type}`; + } + let element: LovelaceCard | undefined; let cardConfig: LovelaceCardConfig = { type }; @@ -262,7 +291,7 @@ export class HuiCardPicker extends LitElement { this._usedEntities! ); - if (!noElement) { + if (!noElement || customCard?.preview) { element = this._createCardElement(cardConfig); } } @@ -274,20 +303,25 @@ export class HuiCardPicker extends LitElement { description: !element || element.tagName === "HUI-ERROR-CARD", })}" > - ${!element || element.tagName === "HUI-ERROR-CARD" - ? html` - ${this.hass!.localize( - `ui.panel.lovelace.editor.card.${cardConfig.type}.description` - )} - ` - : html` - ${element} - `} + ${element && element.tagName !== "HUI-ERROR-CARD" + ? element + : customCard + ? customCard.description || + this.hass!.localize( + `ui.panel.lovelace.editor.cardpicker.no_description` + ) + : this.hass!.localize( + `ui.panel.lovelace.editor.card.${cardConfig.type}.description` + )}
- ${this.hass!.localize( - `ui.panel.lovelace.editor.card.${cardConfig.type}.name` - )} + ${customCard + ? `${this.hass!.localize( + "ui.panel.lovelace.editor.cardpicker.custom_card" + )}: ${customCard.name || customCard.type}` + : this.hass!.localize( + `ui.panel.lovelace.editor.card.${cardConfig.type}.name` + )}
`; diff --git a/src/translations/en.json b/src/translations/en.json index 277ae98ded..bf785cde5b 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -2159,6 +2159,10 @@ "description": "This renders the first card at full width; other cards in this view will not be rendered.", "warning_multiple_cards": "This view contains more than one card, but a panel view can only show 1 card." } + }, + "cardpicker": { + "no_description": "No description available.", + "custom_card": "Custom" } }, "warning": {