mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-21 08:16:36 +00:00
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:
parent
454d81facc
commit
a0a4fcaf5f
23
src/data/lovelace_custom_cards.ts
Normal file
23
src/data/lovelace_custom_cards.ts
Normal 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);
|
@ -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 {
|
||||||
|
@ -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>
|
||||||
`;
|
`;
|
||||||
|
@ -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": {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user