diff --git a/src/panels/lovelace/components/hui-card-options.ts b/src/panels/lovelace/components/hui-card-options.ts index 8bf2af28eb..7b18f8119e 100644 --- a/src/panels/lovelace/components/hui-card-options.ts +++ b/src/panels/lovelace/components/hui-card-options.ts @@ -21,8 +21,8 @@ export class HuiCardOptions extends LitElement { registeredDialog = true; fireEvent(this, "register-dialog", { dialogShowEvent: "show-edit-card", - dialogTag: "ha-dialog-edit-card", - dialogImport: () => import("./ha-dialog-edit-card"), + dialogTag: "hui-dialog-edit-card", + dialogImport: () => import("../editor/hui-dialog-edit-card"), }); } } diff --git a/src/panels/lovelace/components/ha-dialog-edit-card.ts b/src/panels/lovelace/editor/hui-dialog-edit-card.ts similarity index 68% rename from src/panels/lovelace/components/ha-dialog-edit-card.ts rename to src/panels/lovelace/editor/hui-dialog-edit-card.ts index 6e5a368c29..adae0b17e8 100644 --- a/src/panels/lovelace/components/ha-dialog-edit-card.ts +++ b/src/panels/lovelace/editor/hui-dialog-edit-card.ts @@ -3,6 +3,7 @@ import { fireEvent } from "../../../common/dom/fire_event.js"; import "@polymer/paper-button/paper-button.js"; import "@polymer/paper-input/paper-textarea.js"; +import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable.js"; import "@polymer/paper-dialog/paper-dialog.js"; // This is not a duplicate import, one is for types, one is for element. // tslint:disable-next-line @@ -10,7 +11,13 @@ import { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog.js"; import { HomeAssistant } from "../../../types"; import { getCardConfig, updateCardConfig } from "../common/data"; -export class HuiEditCardModal extends LitElement { +import "./hui-yaml-editor"; +import "./hui-yaml-card-preview"; +// This is not a duplicate import, one is for types, one is for element. +// tslint:disable-next-line +import { HuiYAMLCardPreview } from "./hui-yaml-card-preview"; + +export class HuiDialogEditCard extends LitElement { protected hass?: HomeAssistant; private _cardId?: string; private _cardConfig?: string; @@ -31,6 +38,7 @@ export class HuiEditCardModal extends LitElement { this.hass = hass; this._cardId = cardId; this._reloadLovelace = reloadLovelace; + this._cardConfig = ""; this._loadConfig(); // Wait till dialog is rendered. await this.updateComplete; @@ -41,6 +49,10 @@ export class HuiEditCardModal extends LitElement { return this.shadowRoot!.querySelector("paper-dialog")!; } + private get _previewEl(): HuiYAMLCardPreview { + return this.shadowRoot!.querySelector("hui-yaml-card-preview")!; + } + protected render() { return html`

Card Configuration

- + + + +
Cancel Save @@ -61,6 +80,10 @@ export class HuiEditCardModal extends LitElement { `; } + private _handleYamlChanged(ev) { + this._previewEl.yaml = ev.detail.yaml; + } + private _closeDialog() { this._dialog.close(); } @@ -73,8 +96,8 @@ export class HuiEditCardModal extends LitElement { } private async _updateConfig() { - const newCardConfig = this.shadowRoot!.querySelector("paper-textarea")! - .value; + const newCardConfig = this.shadowRoot!.querySelector("hui-yaml-editor")! + .yaml; if (this._cardConfig === newCardConfig) { this._dialog.close(); @@ -92,8 +115,8 @@ export class HuiEditCardModal extends LitElement { declare global { interface HTMLElementTagNameMap { - "ha-dialog-edit-card": HuiEditCardModal; + "hui-dialog-edit-card": HuiDialogEditCard; } } -customElements.define("ha-dialog-edit-card", HuiEditCardModal); +customElements.define("hui-dialog-edit-card", HuiDialogEditCard); diff --git a/src/panels/lovelace/editor/hui-yaml-card-preview.ts b/src/panels/lovelace/editor/hui-yaml-card-preview.ts new file mode 100644 index 0000000000..67ce7f1d6b --- /dev/null +++ b/src/panels/lovelace/editor/hui-yaml-card-preview.ts @@ -0,0 +1,52 @@ +import yaml from "js-yaml"; + +import "@polymer/paper-input/paper-textarea.js"; + +import createCardElement from "../common/create-card-element"; +import createErrorCardConfig from "../common/create-error-card-config"; +import { HomeAssistant } from "../../../types"; +import { LovelaceCard } from "../types"; + +export class HuiYAMLCardPreview extends HTMLElement { + private _hass?: HomeAssistant; + + set hass(value: HomeAssistant) { + this._hass = value; + if (this.lastChild) { + (this.lastChild as LovelaceCard).hass = value; + } + } + + set yaml(value: string) { + if (this.lastChild) { + this.removeChild(this.lastChild); + } + + if (value === "") { + return; + } + + let conf; + try { + conf = yaml.safeLoad(value); + } catch (err) { + conf = createErrorCardConfig(`Invalid YAML: ${err.message}`, undefined); + } + + const element = createCardElement(conf); + + if (this._hass) { + element.hass = this._hass; + } + + this.appendChild(element); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-yaml-card-preview": HuiYAMLCardPreview; + } +} + +customElements.define("hui-yaml-card-preview", HuiYAMLCardPreview); diff --git a/src/panels/lovelace/editor/hui-yaml-editor.ts b/src/panels/lovelace/editor/hui-yaml-editor.ts new file mode 100644 index 0000000000..170a08b3cb --- /dev/null +++ b/src/panels/lovelace/editor/hui-yaml-editor.ts @@ -0,0 +1,41 @@ +import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element"; +import { fireEvent } from "../../../common/dom/fire_event.js"; + +import "@polymer/paper-input/paper-textarea.js"; + +export class HuiYAMLEditor extends LitElement { + public yaml?: string; + + static get properties(): PropertyDeclarations { + return { + yaml: {}, + }; + } + + protected render() { + return html` + + + `; + } + + private _valueChanged(ev) { + this.yaml = ev.target.value; + fireEvent(this, "yaml-changed", { yaml: ev.target.value }); + } +} + +declare global { + interface HTMLElementTagNameMap { + "hui-yaml-editor": HuiYAMLEditor; + } +} + +customElements.define("hui-yaml-editor", HuiYAMLEditor);