Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions src/common/util/uid.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
function s4() {
return Math.floor((1 + Math.random()) * 0x10000)
.toString(16)
.substring(1);
}

export default function uid() {
Comment thread
bramkragten marked this conversation as resolved.
Outdated
return s4() + s4() + s4() + s4() + s4();
}
21 changes: 17 additions & 4 deletions src/data/lovelace.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,12 +33,12 @@ export const migrateConfig = (hass: HomeAssistant): Promise<void> =>
export const saveConfig = (
hass: HomeAssistant,
config: LovelaceConfig | string,
configFormat: "json" | "yaml"
format: "json" | "yaml"
): Promise<void> =>
hass.callWS({
type: "lovelace/config/save",
config,
format: configFormat,
format,
});

export const getCardConfig = (
Expand All @@ -54,13 +54,13 @@ export const updateCardConfig = (
hass: HomeAssistant,
cardId: string,
config: LovelaceCardConfig | string,
configFormat: "json" | "yaml"
format: "json" | "yaml"
): Promise<void> =>
hass.callWS({
type: "lovelace/config/card/update",
card_id: cardId,
card_config: config,
format: configFormat,
format,
});

export const deleteCard = (
Expand All @@ -71,3 +71,16 @@ export const deleteCard = (
type: "lovelace/config/card/delete",
card_id: cardId,
});

export const addCard = (
hass: HomeAssistant,
viewId: string,
config: LovelaceCardConfig | string,
format: "json" | "yaml"
): Promise<void> =>
hass.callWS({
type: "lovelace/config/card/add",
view_id: viewId,
card_config: config,
format,
});
5 changes: 5 additions & 0 deletions src/panels/lovelace/cards/hui-entities-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,11 @@ class HuiEntitiesCard extends hassLocalizeLitMixin(LitElement)
await import("../editor/config-elements/hui-entities-card-editor");
return document.createElement("hui-entities-card-editor");
}

public static getStubConfig(hass: HomeAssistant): LovelaceCardConfig {
Comment thread
bramkragten marked this conversation as resolved.
Outdated
return { type: "entities", entities: [] };
}

protected _hass?: HomeAssistant;
protected _config?: Config;
protected _configEntities?: ConfigEntity[];
Expand Down
3 changes: 3 additions & 0 deletions src/panels/lovelace/cards/hui-glance-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ export class HuiGlanceCard extends hassLocalizeLitMixin(LitElement)
await import("../editor/config-elements/hui-glance-card-editor");
return document.createElement("hui-glance-card-editor");
}
public static getStubConfig(hass: HomeAssistant): LovelaceCardConfig {
return { type: "glance", entities: [] };
}

public hass?: HomeAssistant;
private _config?: Config;
Expand Down
7 changes: 7 additions & 0 deletions src/panels/lovelace/common/get-element-tag.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
const CUSTOM_TYPE_PREFIX = "custom:";

export function getElementTag(type: string): string {
Comment thread
bramkragten marked this conversation as resolved.
Outdated
return type.startsWith(CUSTOM_TYPE_PREFIX)
? type.substr(CUSTOM_TYPE_PREFIX.length)
: `hui-${type}-card`;
}
20 changes: 4 additions & 16 deletions src/panels/lovelace/components/hui-card-options.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,7 @@
import "@polymer/paper-button/paper-button";
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
import "@polymer/paper-button/paper-button";
import { fireEvent } from "../../../common/dom/fire_event";
import {
showEditCardDialog,
registerEditCardDialog,
} from "../editor/hui-dialog-edit-card";
import { showEditCardDialog } from "../editor/hui-dialog-edit-card";

import { confDeleteCard } from "../editor/delete-card";
import { HomeAssistant } from "../../../types";
Expand All @@ -14,14 +11,13 @@ declare global {
// for fire event
interface HASSDomEvents {
"show-edit-card": {
cardConfig: LovelaceCardConfig;
cardConfig?: LovelaceCardConfig;
viewId?: string | number;
reloadLovelace: () => void;
};
}
}

let registeredDialog = false;

export class HuiCardOptions extends LitElement {
public cardConfig?: LovelaceCardConfig;
protected hass?: HomeAssistant;
Expand All @@ -30,14 +26,6 @@ export class HuiCardOptions extends LitElement {
return { hass: {} };
}

public connectedCallback() {
super.connectedCallback();
if (!registeredDialog) {
registeredDialog = true;
registerEditCardDialog(this);
}
}

protected render() {
return html`
<style>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,10 +42,6 @@ const cardConfigStruct = struct({

export class HuiEntitiesCardEditor extends hassLocalizeLitMixin(LitElement)
implements LovelaceCardEditor {
public hass?: HomeAssistant;
private _config?: Config;
private _configEntities?: ConfigEntity[];

static get properties(): PropertyDeclarations {
return { hass: {}, _config: {}, _configEntities: {} };
}
Expand All @@ -58,6 +54,10 @@ export class HuiEntitiesCardEditor extends hassLocalizeLitMixin(LitElement)
return this._config!.theme || "Backend-selected";
}

public hass?: HomeAssistant;
private _config?: Config;
private _configEntities?: ConfigEntity[];

public setConfig(config: Config): void {
config = cardConfigStruct(config);

Expand Down
102 changes: 102 additions & 0 deletions src/panels/lovelace/editor/hui-card-picker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
import { html, LitElement } from "@polymer/lit-element";
import { TemplateResult } from "lit-html";
import "@polymer/paper-button/paper-button";

import { HomeAssistant } from "../../../types";
import { fireEvent } from "../../../common/dom/fire_event";
import { LovelaceCardConfig } from "../../../data/lovelace";
import { getElementTag } from "../common/get-element-tag";
import { CardPickTarget } from "./types";
import uid from "../../../common/util/uid";

const cards = [
{ name: "Alarm panel", type: "alarm-panel" },
{ name: "Conditional", type: "conditional" },
{ name: "Entities", type: "entities" },
{ name: "Entity Button", type: "entity-button" },
{ name: "Entity Filter", type: "entity-filter" },
{ name: "Gauge", type: "gauge" },
{ name: "Glance", type: "glance" },
{ name: "History Graph", type: "history-graph" },
{ name: "Horizontal Stack", type: "horizontal-graph" },
{ name: "iFrame", type: "iframe" },
{ name: "Light", type: "light" },
{ name: "Map", type: "map" },
{ name: "Markdown", type: "markdown" },
{ name: "Media Control", type: "media-control" },
{ name: "Picture", type: "picture" },
{ name: "Picture Elements", type: "picture-elements" },
{ name: "Picture Entity", type: "picture-entity" },
{ name: "Picture Glance", type: "picture-glance" },
{ name: "Plant Status", type: "plant-status" },
{ name: "Sensor", type: "sensor" },
{ name: "Shopping List", type: "shopping-list" },
{ name: "Thermostat", type: "thermostat" },
{ name: "Vertical Stack", type: "vertical-stack" },
{ name: "Weather Forecast", type: "weather-forecast" },
];

export class HuiCardPicker extends LitElement {
protected hass?: HomeAssistant;

protected render(): TemplateResult {
return html`
${this.renderStyle()}
<h3>Pick the card you want to add:</h3>
<div class="cards-container">
${
cards.map((card) => {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Idea: In the future we can add a global window object where custom cards can register so they can be shown in this list too.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah! I had that in mind!

return html`
<paper-button
raised
@click="${this._cardPicked}"
.type="${card.type}"
>${card.name}</paper-button
>
`;
})
}
</div>
`;
}

private renderStyle(): TemplateResult {
return html`
<style>
.cards-container {
display: flex;
flex-wrap: wrap;
margin-bottom: 10px;
}
.cards-container paper-button {
flex: 1 0 25%;
}
</style>
`;
}

private _cardPicked(ev: Event): void {
const type = (ev.currentTarget! as CardPickTarget).type;
const tag = getElementTag(type);

const elClass = customElements.get(tag);
let config: LovelaceCardConfig = { type, id: uid() };
Comment thread
bramkragten marked this conversation as resolved.

try {
const cardConfig = elClass.getStubConfig(this.hass);
Comment thread
bramkragten marked this conversation as resolved.
config = { ...config, ...cardConfig };
} finally {
fireEvent(this, "card-picked", {
config,
});
}
}
}

declare global {
interface HTMLElementTagNameMap {
"hui-card-picker": HuiCardPicker;
}
}

customElements.define("hui-card-picker", HuiCardPicker);
7 changes: 2 additions & 5 deletions src/panels/lovelace/editor/hui-card-preview.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,7 @@ import { HomeAssistant } from "../../../types";
import { LovelaceCardConfig } from "../../../data/lovelace";
import { LovelaceCard } from "../types";
import { ConfigError } from "./types";

const CUSTOM_TYPE_PREFIX = "custom:";
import { getElementTag } from "../common/get-element-tag";

export class HuiCardPreview extends HTMLElement {
private _hass?: HomeAssistant;
Expand Down Expand Up @@ -39,9 +38,7 @@ export class HuiCardPreview extends HTMLElement {
return;
}

const tag = configValue.type.startsWith(CUSTOM_TYPE_PREFIX)
? configValue.type.substr(CUSTOM_TYPE_PREFIX.length)
: `hui-${configValue.type}-card`;
const tag = getElementTag(configValue.type);

if (tag.toUpperCase() === this._element.tagName) {
this._element.setConfig(configValue);
Expand Down
9 changes: 7 additions & 2 deletions src/panels/lovelace/editor/hui-dialog-edit-card.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,8 @@ const dialogShowEvent = "show-edit-card";
const dialogTag = "hui-dialog-edit-card";

export interface EditCardDialogParams {
cardConfig: LovelaceCardConfig;
cardConfig?: LovelaceCardConfig;
viewId?: string | number;
reloadLovelace: () => void;
}

Expand Down Expand Up @@ -60,7 +61,10 @@ export class HuiDialogEditCard extends LitElement {
if (!this._params) {
return html``;
}
if (!this._params.cardConfig.id) {
if (
(this._params.cardConfig && !this._params.cardConfig.id) ||
(!this._params.cardConfig && !this._params.viewId)
) {
return html`
<hui-migrate-config
.hass="${this.hass}"
Expand All @@ -70,6 +74,7 @@ export class HuiDialogEditCard extends LitElement {
}
return html`
<hui-edit-card
.viewId="${this._params.viewId}"
.cardConfig="${this._params.cardConfig}"
.hass="${this.hass}"
@reload-lovelace="${this._params.reloadLovelace}"
Expand Down
Loading