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 <mail@bramkragten.nl>
This commit is contained in:
Thomas Lovén 2020-03-31 16:20:09 +02:00 committed by GitHub
parent 454d81facc
commit a0a4fcaf5f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 76 additions and 15 deletions

View File

@ -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);

View File

@ -17,8 +17,8 @@ import { fireEvent } from "../../../common/dom/fire_event";
import { LovelaceElementConfig, LovelaceElement } from "../elements/types"; import { LovelaceElementConfig, LovelaceElement } from "../elements/types";
import { LovelaceRow, LovelaceRowConfig } from "../entity-rows/types"; import { LovelaceRow, LovelaceRowConfig } from "../entity-rows/types";
import { LovelaceHeaderFooterConfig } from "../header-footer/types"; import { LovelaceHeaderFooterConfig } from "../header-footer/types";
import { CUSTOM_TYPE_PREFIX } from "../../../data/lovelace_custom_cards";
const CUSTOM_TYPE_PREFIX = "custom:";
const TIMEOUT = 2000; const TIMEOUT = 2000;
interface CreateElementConfigTypes { interface CreateElementConfigTypes {

View File

@ -23,6 +23,11 @@ import {
calcUnusedEntities, calcUnusedEntities,
} from "../../common/compute-unused-entities"; } from "../../common/compute-unused-entities";
import { UNKNOWN, UNAVAILABLE } from "../../../../data/entity"; import { UNKNOWN, UNAVAILABLE } from "../../../../data/entity";
import {
customCards,
getCustomCardEntry,
CUSTOM_TYPE_PREFIX,
} from "../../../../data/lovelace_custom_cards";
const previewCards: string[] = [ const previewCards: string[] = [
"alarm-panel", "alarm-panel",
@ -100,6 +105,24 @@ export class HuiCardPicker extends LitElement {
`; `;
})} })}
</div> </div>
${customCards.length
? html`
<div class="cards-container">
${customCards.map((card) => {
return html`
${until(
this._renderCardElement(card.type, true, true),
html`
<div class="card spinner">
<paper-spinner active alt="Loading"></paper-spinner>
</div>
`
)}
`;
})}
</div>
`
: ""}
<div class="cards-container"> <div class="cards-container">
<div <div
class="card" class="card"
@ -249,8 +272,14 @@ export class HuiCardPicker extends LitElement {
private async _renderCardElement( private async _renderCardElement(
type: string, type: string,
noElement: boolean = false noElement: boolean = false,
isCustom: boolean = false
): Promise<TemplateResult> { ): Promise<TemplateResult> {
const customCard = isCustom ? getCustomCardEntry(type) : undefined;
if (isCustom) {
type = `${CUSTOM_TYPE_PREFIX}${type}`;
}
let element: LovelaceCard | undefined; let element: LovelaceCard | undefined;
let cardConfig: LovelaceCardConfig = { type }; let cardConfig: LovelaceCardConfig = { type };
@ -262,7 +291,7 @@ export class HuiCardPicker extends LitElement {
this._usedEntities! this._usedEntities!
); );
if (!noElement) { if (!noElement || customCard?.preview) {
element = this._createCardElement(cardConfig); element = this._createCardElement(cardConfig);
} }
} }
@ -274,20 +303,25 @@ export class HuiCardPicker extends LitElement {
description: !element || element.tagName === "HUI-ERROR-CARD", description: !element || element.tagName === "HUI-ERROR-CARD",
})}" })}"
> >
${!element || element.tagName === "HUI-ERROR-CARD" ${element && element.tagName !== "HUI-ERROR-CARD"
? html` ? element
${this.hass!.localize( : customCard
`ui.panel.lovelace.editor.card.${cardConfig.type}.description` ? customCard.description ||
)} this.hass!.localize(
` `ui.panel.lovelace.editor.cardpicker.no_description`
: html` )
${element} : this.hass!.localize(
`} `ui.panel.lovelace.editor.card.${cardConfig.type}.description`
)}
</div> </div>
<div class="card-header"> <div class="card-header">
${this.hass!.localize( ${customCard
`ui.panel.lovelace.editor.card.${cardConfig.type}.name` ? `${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`
)}
</div> </div>
</div> </div>
`; `;

View File

@ -2159,6 +2159,10 @@
"description": "This renders the first card at full width; other cards in this view will not be rendered.", "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." "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": { "warning": {