A bit of cleanup in the card editor (#2984)

* edit-card shouldn't need to know about the path

* fix

* Store config as object at all times, convert when necessary

* Hidden is not a property of mwc-button. No need to hide anyway...
This commit is contained in:
Thomas Lovén 2019-03-26 23:31:43 +01:00 committed by Paulus Schoutsen
parent 9a4215b5d5
commit 44eaa3abad
2 changed files with 65 additions and 75 deletions

View File

@ -12,6 +12,7 @@ import { LovelaceCardConfig } from "../../../../data/lovelace";
import "./hui-edit-card"; import "./hui-edit-card";
import "./hui-dialog-pick-card"; import "./hui-dialog-pick-card";
import { EditCardDialogParams } from "./show-edit-card-dialog"; import { EditCardDialogParams } from "./show-edit-card-dialog";
import { addCard, replaceCard } from "../config-util";
declare global { declare global {
// for fire event // for fire event
@ -32,19 +33,22 @@ export class HuiDialogEditCard extends LitElement {
@property() private _cardConfig?: LovelaceCardConfig; @property() private _cardConfig?: LovelaceCardConfig;
@property() private _newCard?: boolean;
constructor() { constructor() {
super(); super();
this._cardPicked = this._cardPicked.bind(this); this._cardPicked = this._cardPicked.bind(this);
this._cancel = this._cancel.bind(this); this._cancel = this._cancel.bind(this);
this._save = this._save.bind(this);
} }
public async showDialog(params: EditCardDialogParams): Promise<void> { public async showDialog(params: EditCardDialogParams): Promise<void> {
this._params = params; this._params = params;
const [view, card] = params.path;
this._newCard = card !== undefined ? false : true;
this._cardConfig = this._cardConfig =
params.path.length === 2 card !== undefined
? (this._cardConfig = params.lovelace.config.views[ ? params.lovelace.config.views[view].cards![card]
params.path[0]
].cards![params.path[1]])
: undefined; : undefined;
} }
@ -66,9 +70,10 @@ export class HuiDialogEditCard extends LitElement {
<hui-edit-card <hui-edit-card
.hass="${this.hass}" .hass="${this.hass}"
.lovelace="${this._params.lovelace}" .lovelace="${this._params.lovelace}"
.path="${this._params.path}"
.cardConfig="${this._cardConfig}" .cardConfig="${this._cardConfig}"
.closeDialog="${this._cancel}" .closeDialog="${this._cancel}"
.saveCard="${this._save}"
.newCard="${this._newCard}"
> >
</hui-edit-card> </hui-edit-card>
`; `;
@ -82,6 +87,19 @@ export class HuiDialogEditCard extends LitElement {
this._params = undefined; this._params = undefined;
this._cardConfig = undefined; this._cardConfig = undefined;
} }
private async _save(cardConf: LovelaceCardConfig): Promise<void> {
const lovelace = this._params!.lovelace;
await lovelace.saveConfig(
this._params!.path.length === 1
? addCard(lovelace.config, this._params!.path as [number], cardConf)
: replaceCard(
lovelace.config,
this._params!.path as [number, number],
cardConf
)
);
}
} }
declare global { declare global {

View File

@ -33,10 +33,9 @@ import "./hui-card-preview";
// tslint:disable-next-line // tslint:disable-next-line
import { HuiCardPreview } from "./hui-card-preview"; import { HuiCardPreview } from "./hui-card-preview";
import { LovelaceCardEditor, Lovelace } from "../../types"; import { LovelaceCardEditor, Lovelace } from "../../types";
import { ConfigValue, ConfigError } from "../types"; import { ConfigError } from "../types";
import { EntityConfig } from "../../entity-rows/types"; import { EntityConfig } from "../../entity-rows/types";
import { getCardElementTag } from "../../common/get-card-element-tag"; import { getCardElementTag } from "../../common/get-card-element-tag";
import { addCard, replaceCard } from "../config-util";
import { afterNextRender } from "../../../../common/util/render-status"; import { afterNextRender } from "../../../../common/util/render-status";
declare global { declare global {
@ -58,15 +57,17 @@ export class HuiEditCard extends LitElement {
public lovelace?: Lovelace; public lovelace?: Lovelace;
public path?: [number] | [number, number];
public closeDialog?: () => void; public closeDialog?: () => void;
public saveCard?: (cardConf: LovelaceCardConfig) => Promise<void>;
public newCard?: boolean;
@property() private _configElement?: LovelaceCardEditor | null; @property() private _configElement?: LovelaceCardEditor | null;
@property() private _uiEditor?: boolean; @property() private _uiEditor?: boolean;
@property() private _configValue?: ConfigValue; @property() private _cardConfig?: LovelaceCardConfig;
@property() private _configState?: string; @property() private _configState?: string;
@ -76,8 +77,6 @@ export class HuiEditCard extends LitElement {
@property() private _errorMsg?: TemplateResult; @property() private _errorMsg?: TemplateResult;
private _cardType?: string;
private get _dialog(): PaperDialogElement { private get _dialog(): PaperDialogElement {
return this.shadowRoot!.querySelector("paper-dialog")!; return this.shadowRoot!.querySelector("paper-dialog")!;
} }
@ -86,6 +85,20 @@ export class HuiEditCard extends LitElement {
return this.shadowRoot!.querySelector("hui-card-preview")!; return this.shadowRoot!.querySelector("hui-card-preview")!;
} }
// tslint:disable-next-line
private __cardYaml: string | undefined;
private get _cardYaml(): string | undefined {
if (!this.__cardYaml) {
this.__cardYaml = yaml.safeDump(this._cardConfig);
}
return this.__cardYaml;
}
private set _cardYaml(yml: string | undefined) {
this.__cardYaml = yml;
}
public constructor() { public constructor() {
super(); super();
this._saving = false; this._saving = false;
@ -98,7 +111,8 @@ export class HuiEditCard extends LitElement {
return; return;
} }
this._configValue = { format: "yaml", value: undefined }; this._cardConfig = undefined;
this._cardYaml = undefined;
this._configState = "OK"; this._configState = "OK";
this._uiEditor = true; this._uiEditor = true;
this._errorMsg = undefined; this._errorMsg = undefined;
@ -119,7 +133,7 @@ export class HuiEditCard extends LitElement {
: html` : html`
<hui-yaml-editor <hui-yaml-editor
.hass="${this.hass}" .hass="${this.hass}"
.value="${this._configValue!.value}" .value="${this._cardYaml}"
@yaml-changed="${this._handleYamlChanged}" @yaml-changed="${this._handleYamlChanged}"
@yaml-save="${this._save}" @yaml-save="${this._save}"
></hui-yaml-editor> ></hui-yaml-editor>
@ -162,7 +176,6 @@ export class HuiEditCard extends LitElement {
<div class="paper-dialog-buttons"> <div class="paper-dialog-buttons">
<mwc-button <mwc-button
class="toggle-button" class="toggle-button"
?hidden="${!this._configValue || !this._configValue.value}"
?disabled="${this._configElement === null || ?disabled="${this._configElement === null ||
this._configState !== "OK"}" this._configState !== "OK"}"
@click="${this._toggleEditor}" @click="${this._toggleEditor}"
@ -174,7 +187,6 @@ export class HuiEditCard extends LitElement {
>${this.hass!.localize("ui.common.cancel")}</mwc-button >${this.hass!.localize("ui.common.cancel")}</mwc-button
> >
<mwc-button <mwc-button
?hidden="${!this._configValue || !this._configValue.value}"
?disabled="${this._saving || this._configState !== "OK"}" ?disabled="${this._saving || this._configState !== "OK"}"
@click="${this._save}" @click="${this._save}"
> >
@ -222,22 +234,9 @@ export class HuiEditCard extends LitElement {
this._saving = true; this._saving = true;
const cardConf: LovelaceCardConfig =
this._configValue!.format === "yaml"
? yaml.safeLoad(this._configValue!.value!)
: this._configValue!.value!;
try { try {
const lovelace = this.lovelace!; await this.saveCard!(this._cardConfig!);
await lovelace.saveConfig( this._cardYaml = undefined;
this._creatingCard
? addCard(lovelace.config, this.path as [number], cardConf)
: replaceCard(
lovelace.config,
this.path as [number, number],
cardConf
)
);
this.closeDialog!(); this.closeDialog!();
} catch (err) { } catch (err) {
alert(`Saving failed: ${err.message}`); alert(`Saving failed: ${err.message}`);
@ -247,12 +246,9 @@ export class HuiEditCard extends LitElement {
} }
private _handleYamlChanged(ev: CustomEvent): void { private _handleYamlChanged(ev: CustomEvent): void {
this._configValue = { format: "yaml", value: ev.detail.value }; this._cardConfig = yaml.safeLoad(ev.detail.value);
try { try {
const config = yaml.safeLoad( this._updatePreview(this._cardConfig!);
this._configValue.value
) as LovelaceCardConfig;
this._updatePreview(config);
this._configState = "OK"; this._configState = "OK";
} catch (err) { } catch (err) {
this._configState = "YAML_ERROR"; this._configState = "YAML_ERROR";
@ -264,7 +260,7 @@ export class HuiEditCard extends LitElement {
} }
private _handleUIConfigChanged(value: LovelaceCardConfig): void { private _handleUIConfigChanged(value: LovelaceCardConfig): void {
this._configValue = { format: "json", value }; this._cardConfig = value;
this._updatePreview(value); this._updatePreview(value);
} }
@ -294,35 +290,23 @@ export class HuiEditCard extends LitElement {
} }
private async _toggleEditor(): Promise<void> { private async _toggleEditor(): Promise<void> {
if (this._uiEditor && this._configValue!.format === "json") { this._cardYaml = undefined;
this._configValue = { if (this._uiEditor) {
format: "yaml", this._uiEditor = false;
value: yaml.safeDump(this._configValue!.value), } else if (this._configElement) {
}; const success = await this._loadConfigElement(this._cardConfig!);
this._uiEditor = !this._uiEditor; if (!success) {
} else if (this._configElement && this._configValue!.format === "yaml") { this._loadedDialog();
const yamlConfig = this._configValue!.value;
const cardConfig = yaml.safeLoad(yamlConfig) as LovelaceCardConfig;
this._uiEditor = !this._uiEditor;
if (cardConfig.type !== this._cardType) {
const succes = await this._loadConfigElement(cardConfig);
if (!succes) {
this._loadedDialog();
}
this._cardType = cardConfig.type;
} else { } else {
this._configValue = { this._uiEditor = true;
format: "json", this._configElement.setConfig(this._cardConfig!);
value: cardConfig,
};
this._configElement.setConfig(cardConfig);
} }
} }
this._resizeDialog(); this._resizeDialog();
} }
private _isConfigValid(): boolean { private _isConfigValid(): boolean {
if (!this._configValue || !this._configValue.value) { if (!this._cardConfig) {
return false; return false;
} }
if (this._configState === "OK") { if (this._configState === "OK") {
@ -333,14 +317,10 @@ export class HuiEditCard extends LitElement {
} }
private _isConfigChanged(): boolean { private _isConfigChanged(): boolean {
if (this._creatingCard) { if (this.newCard) {
return true; return true;
} }
const configValue = return JSON.stringify(this._cardConfig) !== JSON.stringify(this.cardConfig);
this._configValue!.format === "yaml"
? yaml.safeLoad(this._configValue!.value)
: this._configValue!.value;
return JSON.stringify(configValue) !== JSON.stringify(this.cardConfig);
} }
private async _loadConfigElement(conf: LovelaceCardConfig): Promise<boolean> { private async _loadConfigElement(conf: LovelaceCardConfig): Promise<boolean> {
@ -357,10 +337,11 @@ export class HuiEditCard extends LitElement {
const elClass = customElements.get(tag); const elClass = customElements.get(tag);
let configElement; let configElement;
this._cardConfig = conf;
if (elClass && elClass.getConfigElement) { if (elClass && elClass.getConfigElement) {
configElement = await elClass.getConfigElement(); configElement = await elClass.getConfigElement();
} else { } else {
this._configValue = { format: "yaml", value: yaml.safeDump(conf) };
this._updatePreview(conf); this._updatePreview(conf);
this._uiEditor = false; this._uiEditor = false;
this._configElement = null; this._configElement = null;
@ -374,10 +355,6 @@ export class HuiEditCard extends LitElement {
Your config is not supported by the UI editor:<br /><b>${err.message}</b Your config is not supported by the UI editor:<br /><b>${err.message}</b
><br />Falling back to YAML editor. ><br />Falling back to YAML editor.
`; `;
this._configValue = {
format: "yaml",
value: yaml.safeDump(conf),
};
this._updatePreview(conf); this._updatePreview(conf);
this._uiEditor = false; this._uiEditor = false;
this._configElement = null; this._configElement = null;
@ -388,17 +365,12 @@ export class HuiEditCard extends LitElement {
configElement.addEventListener("config-changed", (ev) => configElement.addEventListener("config-changed", (ev) =>
this._handleUIConfigChanged(ev.detail.config) this._handleUIConfigChanged(ev.detail.config)
); );
this._configValue = { format: "json", value: conf };
this._configElement = configElement; this._configElement = configElement;
await this.updateComplete; await this.updateComplete;
this._updatePreview(conf); this._updatePreview(conf);
return true; return true;
} }
private get _creatingCard(): boolean {
return this.path!.length === 1;
}
private _openedChanged(ev): void { private _openedChanged(ev): void {
if (!ev.detail.value) { if (!ev.detail.value) {
this.closeDialog!(); this.closeDialog!();