Gui editor fixes (#5416)

* Gui editor fixes

* Fix

* Add change mode button to conditional card editor
This commit is contained in:
Bram Kragten 2020-04-02 17:47:01 +02:00 committed by GitHub
parent 793a704871
commit 4150ac045d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
26 changed files with 146 additions and 56 deletions

View File

@ -79,6 +79,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
@property() @property()
private _history?: HassEntity[][]; private _history?: HassEntity[][];
private _date?: Date; private _date?: Date;
private _loaded = false;
@property() @property()
private _config?: MapCardConfig; private _config?: MapCardConfig;
@ -282,6 +283,10 @@ class HuiMapCard extends LitElement implements LovelaceCard {
} }
private async loadMap(): Promise<void> { private async loadMap(): Promise<void> {
if (this._loaded) {
return;
}
this._loaded = true;
[this._leafletMap, this.Leaflet] = await setupLeafletMap( [this._leafletMap, this.Leaflet] = await setupLeafletMap(
this._mapEl, this._mapEl,
this._config !== undefined ? this._config.dark_mode === true : false this._config !== undefined ? this._config.dark_mode === true : false

View File

@ -25,15 +25,18 @@ import { EntityConfig } from "../../entity-rows/types";
import { getCardElementClass } from "../../create-element/create-card-element"; import { getCardElementClass } from "../../create-element/create-card-element";
import { GUIModeChangedEvent } from "../types"; import { GUIModeChangedEvent } from "../types";
export interface ConfigChangedEvent {
config: LovelaceCardConfig;
error?: string;
guiModeAvailable?: boolean;
}
declare global { declare global {
interface HASSDomEvents { interface HASSDomEvents {
"entities-changed": { "entities-changed": {
entities: EntityConfig[]; entities: EntityConfig[];
}; };
"config-changed": { "config-changed": ConfigChangedEvent;
config: LovelaceCardConfig;
error?: string;
};
"GUImode-changed": GUIModeChangedEvent; "GUImode-changed": GUIModeChangedEvent;
} }
} }
@ -75,6 +78,7 @@ export class HuiCardEditor extends LitElement {
fireEvent(this, "config-changed", { fireEvent(this, "config-changed", {
config: this.value!, config: this.value!,
error: this._error, error: this._error,
guiModeAvailable: !(this.hasWarning || this.hasError),
}); });
} }
@ -101,7 +105,10 @@ export class HuiCardEditor extends LitElement {
public set GUImode(guiMode: boolean) { public set GUImode(guiMode: boolean) {
this._GUImode = guiMode; this._GUImode = guiMode;
fireEvent(this as HTMLElement, "GUImode-changed", { guiMode }); fireEvent(this as HTMLElement, "GUImode-changed", {
guiMode,
guiModeAvailable: !(this.hasWarning || this.hasError),
});
} }
private get _yamlEditor(): HaCodeEditor { private get _yamlEditor(): HaCodeEditor {
@ -174,6 +181,13 @@ export class HuiCardEditor extends LitElement {
} }
fireEvent(this as HTMLElement, "iron-resize"); fireEvent(this as HTMLElement, "iron-resize");
} }
if (this._configElement && changedProperties.has("hass")) {
this._configElement.hass = this.hass;
}
if (this._configElement && changedProperties.has("lovelace")) {
this._configElement.lovelace = this.lovelace;
}
} }
private _refreshYamlEditor(focus = false) { private _refreshYamlEditor(focus = false) {
@ -232,6 +246,13 @@ export class HuiCardEditor extends LitElement {
this._configElement = configElement; this._configElement = configElement;
this._configElType = cardType; this._configElType = cardType;
// Perform final setup
this._configElement.hass = this.hass;
this._configElement.lovelace = this.lovelace;
this._configElement.addEventListener("config-changed", (ev) =>
this._handleUIConfigChanged(ev as UIConfigChangedEvent)
);
} }
// Setup GUI editor and check that it can handle the current config // Setup GUI editor and check that it can handle the current config
@ -240,16 +261,6 @@ export class HuiCardEditor extends LitElement {
} catch (err) { } catch (err) {
throw Error(`WARNING: ${err.message}`); throw Error(`WARNING: ${err.message}`);
} }
// Perform final setup
this._configElement!.hass = this.hass;
this._configElement!.lovelace = this.lovelace;
this._configElement!.addEventListener("config-changed", (ev) =>
this._handleUIConfigChanged(ev as UIConfigChangedEvent)
);
this.GUImode = true;
return;
} catch (err) { } catch (err) {
if (err.message.startsWith("WARNING:")) { if (err.message.startsWith("WARNING:")) {
this._warning = err.message.substr(8); this._warning = err.message.substr(8);

View File

@ -19,7 +19,7 @@ import {
} from "../../../../data/lovelace"; } from "../../../../data/lovelace";
import "./hui-card-editor"; import "./hui-card-editor";
// tslint:disable-next-line // tslint:disable-next-line
import { HuiCardEditor } from "./hui-card-editor"; import { HuiCardEditor, ConfigChangedEvent } from "./hui-card-editor";
import "./hui-card-preview"; import "./hui-card-preview";
import "./hui-card-picker"; import "./hui-card-picker";
import { EditCardDialogParams } from "./show-edit-card-dialog"; import { EditCardDialogParams } from "./show-edit-card-dialog";
@ -52,12 +52,15 @@ export class HuiDialogEditCard extends LitElement {
@property() private _saving: boolean = false; @property() private _saving: boolean = false;
@property() private _error?: string; @property() private _error?: string;
@property() private _guiModeAvailable? = true;
@query("hui-card-editor") private _cardEditorEl?: HuiCardEditor; @query("hui-card-editor") private _cardEditorEl?: HuiCardEditor;
@property() private _GUImode?: boolean; @property() private _GUImode = true;
public async showDialog(params: EditCardDialogParams): Promise<void> { public async showDialog(params: EditCardDialogParams): Promise<void> {
this._params = params; this._params = params;
this._GUImode = true;
this._guiModeAvailable = true;
const [view, card] = params.path; const [view, card] = params.path;
this._viewConfig = params.lovelaceConfig.views[view]; this._viewConfig = params.lovelaceConfig.views[view];
this._cardConfig = this._cardConfig =
@ -139,8 +142,7 @@ export class HuiDialogEditCard extends LitElement {
? html` ? html`
<mwc-button <mwc-button
@click=${this._toggleMode} @click=${this._toggleMode}
?disabled=${this._cardEditorEl?.hasWarning || .disabled=${!this._guiModeAvailable}
this._cardEditorEl?.hasError}
class="gui-mode-button" class="gui-mode-button"
> >
${this.hass!.localize( ${this.hass!.localize(
@ -288,9 +290,10 @@ export class HuiDialogEditCard extends LitElement {
this._error = ev.detail.error; this._error = ev.detail.error;
} }
private _handleConfigChanged(ev) { private _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
this._cardConfig = deepFreeze(ev.detail.config); this._cardConfig = deepFreeze(ev.detail.config);
this._error = ev.detail.error; this._error = ev.detail.error;
this._guiModeAvailable = ev.detail.guiModeAvailable;
} }
private _handleKeyUp(ev: KeyboardEvent) { private _handleKeyUp(ev: KeyboardEvent) {
@ -302,6 +305,7 @@ export class HuiDialogEditCard extends LitElement {
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void { private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
ev.stopPropagation(); ev.stopPropagation();
this._GUImode = ev.detail.guiMode; this._GUImode = ev.detail.guiMode;
this._guiModeAvailable = ev.detail.guiModeAvailable;
} }
private _toggleMode(): void { private _toggleMode(): void {

View File

@ -60,7 +60,7 @@ export class HuiAlarmPanelCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -88,7 +88,7 @@ export class HuiButtonCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -6,6 +6,7 @@ import {
property, property,
CSSResult, CSSResult,
css, css,
query,
} from "lit-element"; } from "lit-element";
import "@polymer/paper-tabs"; import "@polymer/paper-tabs";
@ -13,11 +14,16 @@ import { struct } from "../../common/structs/struct";
import { HomeAssistant } from "../../../../types"; import { HomeAssistant } from "../../../../types";
import { LovelaceCardEditor } from "../../types"; import { LovelaceCardEditor } from "../../types";
import { StackCardConfig } from "../../cards/types"; import { StackCardConfig } from "../../cards/types";
import { fireEvent } from "../../../../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { LovelaceConfig } from "../../../../data/lovelace"; import { LovelaceConfig } from "../../../../data/lovelace";
import "../../../../components/entity/ha-entity-picker"; import "../../../../components/entity/ha-entity-picker";
import "../../../../components/ha-switch"; import "../../../../components/ha-switch";
import {
HuiCardEditor,
ConfigChangedEvent,
} from "../card-editor/hui-card-editor";
import { GUIModeChangedEvent } from "../types";
const conditionStruct = struct({ const conditionStruct = struct({
entity: "string", entity: "string",
@ -36,7 +42,10 @@ export class HuiConditionalCardEditor extends LitElement
@property() public hass?: HomeAssistant; @property() public hass?: HomeAssistant;
@property() public lovelace?: LovelaceConfig; @property() public lovelace?: LovelaceConfig;
@property() private _config?: StackCardConfig; @property() private _config?: StackCardConfig;
@property() private _GUImode = true;
@property() private _guiModeAvailable? = true;
@property() private _cardTab: boolean = false; @property() private _cardTab: boolean = false;
@query("hui-card-editor") private _cardEditorEl?: HuiCardEditor;
public setConfig(config: StackCardConfig): void { public setConfig(config: StackCardConfig): void {
this._config = cardConfigStruct(config); this._config = cardConfigStruct(config);
@ -69,6 +78,17 @@ export class HuiConditionalCardEditor extends LitElement
${this._config.card.type ${this._config.card.type
? html` ? html`
<div class="card-options"> <div class="card-options">
<mwc-button
@click=${this._toggleMode}
.disabled=${!this._guiModeAvailable}
class="gui-mode-button"
>
${this.hass!.localize(
!this._cardEditorEl || this._GUImode
? "ui.panel.lovelace.editor.edit_card.show_code_editor"
: "ui.panel.lovelace.editor.edit_card.show_visual_editor"
)}
</mwc-button>
<mwc-button @click=${this._handleReplaceCard} <mwc-button @click=${this._handleReplaceCard}
>${this.hass!.localize( >${this.hass!.localize(
"ui.panel.lovelace.editor.card.conditional.change_type" "ui.panel.lovelace.editor.card.conditional.change_type"
@ -80,13 +100,14 @@ export class HuiConditionalCardEditor extends LitElement
.value=${this._config.card} .value=${this._config.card}
.lovelace=${this.lovelace} .lovelace=${this.lovelace}
@config-changed=${this._handleCardChanged} @config-changed=${this._handleCardChanged}
@GUImode-changed=${this._handleGUIModeChanged}
></hui-card-editor> ></hui-card-editor>
` `
: html` : html`
<hui-card-picker <hui-card-picker
.hass=${this.hass} .hass=${this.hass}
.lovelace=${this.lovelace} .lovelace=${this.lovelace}
@config-changed=${this._handleCardChanged} @config-changed=${this._handleCardPicked}
></hui-card-picker> ></hui-card-picker>
`} `}
</div> </div>
@ -162,14 +183,44 @@ export class HuiConditionalCardEditor extends LitElement
this._cardTab = parseInt((ev.target! as any).selected!, 10) === 1; this._cardTab = parseInt((ev.target! as any).selected!, 10) === 1;
} }
private _handleCardChanged(ev: CustomEvent): void { private _toggleMode(): void {
this._cardEditorEl?.toggleMode();
}
private _setMode(value: boolean): void {
this._GUImode = value;
if (this._cardEditorEl) {
this._cardEditorEl!.GUImode = value;
}
}
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
ev.stopPropagation();
this._GUImode = ev.detail.guiMode;
this._guiModeAvailable = ev.detail.guiModeAvailable;
}
private _handleCardPicked(ev: CustomEvent): void {
ev.stopPropagation();
if (!this._config) {
return;
}
this._setMode(true);
this._guiModeAvailable = true;
this._config.card = ev.detail.config;
fireEvent(this, "config-changed", { config: this._config });
}
private _handleCardChanged(ev: HASSDomEvent<ConfigChangedEvent>): void {
ev.stopPropagation(); ev.stopPropagation();
if (!this._config) { if (!this._config) {
return; return;
} }
this._config.card = ev.detail.config; this._config.card = ev.detail.config;
this._guiModeAvailable = ev.detail.guiModeAvailable;
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
private _handleReplaceCard(): void { private _handleReplaceCard(): void {
if (!this._config) { if (!this._config) {
return; return;
@ -267,6 +318,9 @@ export class HuiConditionalCardEditor extends LitElement
justify-content: flex-end; justify-content: flex-end;
width: 100%; width: 100%;
} }
.gui-mode-button {
margin-right: auto;
}
`; `;
} }
} }

View File

@ -67,7 +67,7 @@ export class HuiEntitiesCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -69,7 +69,7 @@ export class HuiEntityCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -73,7 +73,7 @@ export class HuiGaugeCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -80,7 +80,7 @@ export class HuiGlanceCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -67,7 +67,7 @@ export class HuiHistoryGraphCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -47,7 +47,7 @@ export class HuiIframeCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -72,7 +72,7 @@ export class HuiLightCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -79,7 +79,7 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -50,7 +50,7 @@ export class HuiMarkdownCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -37,7 +37,7 @@ export class HuiMediaControlCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -60,7 +60,7 @@ export class HuiPictureCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -100,7 +100,7 @@ export class HuiPictureEntityCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -111,7 +111,7 @@ export class HuiPictureGlanceCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -51,7 +51,7 @@ export class HuiPlantStatusCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -78,7 +78,7 @@ export class HuiSensorCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -46,7 +46,7 @@ export class HuiShoppingListEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -16,7 +16,10 @@ import { LovelaceCardEditor } from "../../types";
import { StackCardConfig } from "../../cards/types"; import { StackCardConfig } from "../../cards/types";
import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event";
import { LovelaceConfig } from "../../../../data/lovelace"; import { LovelaceConfig } from "../../../../data/lovelace";
import { HuiCardEditor } from "../card-editor/hui-card-editor"; import {
HuiCardEditor,
ConfigChangedEvent,
} from "../card-editor/hui-card-editor";
import { GUIModeChangedEvent } from "../types"; import { GUIModeChangedEvent } from "../types";
const cardConfigStruct = struct({ const cardConfigStruct = struct({
@ -32,7 +35,8 @@ export class HuiStackCardEditor extends LitElement
@property() public lovelace?: LovelaceConfig; @property() public lovelace?: LovelaceConfig;
@property() private _config?: StackCardConfig; @property() private _config?: StackCardConfig;
@property() private _selectedCard: number = 0; @property() private _selectedCard: number = 0;
@property() private _GUImode?: boolean; @property() private _GUImode = true;
@property() private _guiModeAvailable? = true;
@query("hui-card-editor") private _cardEditorEl?: HuiCardEditor; @query("hui-card-editor") private _cardEditorEl?: HuiCardEditor;
public setConfig(config: StackCardConfig): void { public setConfig(config: StackCardConfig): void {
@ -52,7 +56,7 @@ export class HuiStackCardEditor extends LitElement
<paper-tabs <paper-tabs
.selected=${selected} .selected=${selected}
scrollable scrollable
@iron-select=${this._handleSelectedCard} @iron-activate=${this._handleSelectedCard}
> >
${this._config.cards.map((_card, i) => { ${this._config.cards.map((_card, i) => {
return html` return html`
@ -65,7 +69,7 @@ export class HuiStackCardEditor extends LitElement
<paper-tabs <paper-tabs
id="add-card" id="add-card"
.selected=${selected === numcards ? "0" : undefined} .selected=${selected === numcards ? "0" : undefined}
@iron-select=${this._handleSelectedCard} @iron-activate=${this._handleSelectedCard}
> >
<paper-tab> <paper-tab>
<ha-icon icon="hass:plus"></ha-icon> <ha-icon icon="hass:plus"></ha-icon>
@ -80,8 +84,7 @@ export class HuiStackCardEditor extends LitElement
<div id="card-options"> <div id="card-options">
<mwc-button <mwc-button
@click=${this._toggleMode} @click=${this._toggleMode}
?disabled=${this._cardEditorEl?.hasWarning || .disabled=${!this._guiModeAvailable}
this._cardEditorEl?.hasError}
class="gui-mode-button" class="gui-mode-button"
> >
${this.hass!.localize( ${this.hass!.localize(
@ -94,7 +97,7 @@ export class HuiStackCardEditor extends LitElement
id="move-before" id="move-before"
title="Move card before" title="Move card before"
icon="hass:arrow-left" icon="hass:arrow-left"
?disabled=${selected === 0} .disabled=${selected === 0}
@click=${this._handleMove} @click=${this._handleMove}
></paper-icon-button> ></paper-icon-button>
@ -102,7 +105,7 @@ export class HuiStackCardEditor extends LitElement
id="move-after" id="move-after"
title="Move card after" title="Move card after"
icon="hass:arrow-right" icon="hass:arrow-right"
?disabled=${selected === numcards - 1} .disabled=${selected === numcards - 1}
@click=${this._handleMove} @click=${this._handleMove}
></paper-icon-button> ></paper-icon-button>
@ -134,18 +137,22 @@ export class HuiStackCardEditor extends LitElement
} }
private _handleSelectedCard(ev) { private _handleSelectedCard(ev) {
this._selectedCard = if (ev.target.id === "add-card") {
ev.target.id === "add-card" this._selectedCard = this._config!.cards.length;
? this._config!.cards.length return;
: parseInt(ev.target.selected, 10); }
this._setMode(true);
this._guiModeAvailable = true;
this._selectedCard = parseInt(ev.detail.selected, 10);
} }
private _handleConfigChanged(ev) { private _handleConfigChanged(ev: HASSDomEvent<ConfigChangedEvent>) {
ev.stopPropagation(); ev.stopPropagation();
if (!this._config) { if (!this._config) {
return; return;
} }
this._config.cards[this._selectedCard] = ev.detail.config; this._config.cards[this._selectedCard] = ev.detail.config;
this._guiModeAvailable = ev.detail.guiModeAvailable;
fireEvent(this, "config-changed", { config: this._config }); fireEvent(this, "config-changed", { config: this._config });
} }
@ -183,12 +190,20 @@ export class HuiStackCardEditor extends LitElement
private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void { private _handleGUIModeChanged(ev: HASSDomEvent<GUIModeChangedEvent>): void {
ev.stopPropagation(); ev.stopPropagation();
this._GUImode = ev.detail.guiMode; this._GUImode = ev.detail.guiMode;
this._guiModeAvailable = ev.detail.guiModeAvailable;
} }
private _toggleMode(): void { private _toggleMode(): void {
this._cardEditorEl?.toggleMode(); this._cardEditorEl?.toggleMode();
} }
private _setMode(value: boolean): void {
this._GUImode = value;
if (this._cardEditorEl) {
this._cardEditorEl!.GUImode = value;
}
}
static get styles(): CSSResult { static get styles(): CSSResult {
return css` return css`
.toolbar { .toolbar {

View File

@ -50,7 +50,7 @@ export class HuiThermostatCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -49,7 +49,7 @@ export class HuiWeatherForecastCardEditor extends LitElement
} }
protected render(): TemplateResult { protected render(): TemplateResult {
if (!this.hass) { if (!this.hass || !this._config) {
return html``; return html``;
} }

View File

@ -16,6 +16,7 @@ export interface YamlChangedEvent extends Event {
export interface GUIModeChangedEvent { export interface GUIModeChangedEvent {
guiMode: boolean; guiMode: boolean;
guiModeAvailable: boolean;
} }
export interface ViewEditEvent extends Event { export interface ViewEditEvent extends Event {