From 16ad8a3c01b667afc64fc15d34bd20874c897422 Mon Sep 17 00:00:00 2001 From: Bram Kragten Date: Wed, 13 May 2020 19:49:03 +0200 Subject: [PATCH] Open newly added view after adding (#5851) --- .../view-editor/hui-dialog-edit-view.ts | 402 +++++++++++++++++- .../editor/view-editor/hui-edit-view.ts | 400 ----------------- .../view-editor/show-edit-view-dialog.ts | 2 + src/panels/lovelace/hui-root.ts | 10 +- 4 files changed, 390 insertions(+), 424 deletions(-) delete mode 100644 src/panels/lovelace/editor/view-editor/hui-edit-view.ts diff --git a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts index b8616528af..8bdbbd67a9 100644 --- a/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts +++ b/src/panels/lovelace/editor/view-editor/hui-dialog-edit-view.ts @@ -1,51 +1,407 @@ +import "@material/mwc-button"; +import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; +import "../../../../components/ha-icon-button"; +import "@polymer/paper-spinner/paper-spinner"; +import "@polymer/paper-tabs/paper-tab"; +import "@polymer/paper-tabs/paper-tabs"; import { + css, + CSSResult, customElement, html, LitElement, property, TemplateResult, } from "lit-element"; -import { HASSDomEvent } from "../../../../common/dom/fire_event"; -import { HomeAssistant } from "../../../../types"; -import "./hui-edit-view"; +import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; +import { navigate } from "../../../../common/navigate"; +import "../../../../components/dialog/ha-paper-dialog"; +import type { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; +import type { + LovelaceBadgeConfig, + LovelaceCardConfig, + LovelaceViewConfig, +} from "../../../../data/lovelace"; +import { + showAlertDialog, + showConfirmationDialog, +} from "../../../../dialogs/generic/show-dialog-box"; +import { haStyleDialog } from "../../../../resources/styles"; +import type { HomeAssistant } from "../../../../types"; +import "../../components/hui-entity-editor"; +import { addView, deleteView, replaceView } from "../config-util"; +import "../hui-badge-preview"; +import { processEditorEntities } from "../process-editor-entities"; +import { + EntitiesEditorEvent, + ViewEditEvent, + ViewVisibilityChangeEvent, +} from "../types"; +import "./hui-view-editor"; +import "./hui-view-visibility-editor"; import { EditViewDialogParams } from "./show-edit-view-dialog"; -declare global { - // for fire event - interface HASSDomEvents { - "reload-lovelace": undefined; - } - // for add event listener - interface HTMLElementEventMap { - "reload-lovelace": HASSDomEvent; - } -} - @customElement("hui-dialog-edit-view") export class HuiDialogEditView extends LitElement { - @property() protected hass?: HomeAssistant; + @property() public hass?: HomeAssistant; @property() private _params?: EditViewDialogParams; + @property() private _config?: LovelaceViewConfig; + + @property() private _badges?: LovelaceBadgeConfig[]; + + @property() private _cards?: LovelaceCardConfig[]; + + @property() private _saving = false; + + @property() private _curTab?: string; + + private _curTabIndex = 0; + public async showDialog(params: EditViewDialogParams): Promise { + // Wait till dialog is rendered. this._params = params; - await this.updateComplete; - (this.shadowRoot!.children[0] as any).showDialog(); + + if (this._dialog == null) { + await this.updateComplete; + } + + if (this._params.viewIndex === undefined) { + this._config = {}; + this._badges = []; + this._cards = []; + } else { + const { + cards, + badges, + ...viewConfig + } = this._params.lovelace!.config.views[this._params.viewIndex]; + this._config = viewConfig; + this._badges = badges ? processEditorEntities(badges) : []; + this._cards = cards; + } + + this._dialog.open(); + } + + private get _dialog(): HaPaperDialog { + return this.shadowRoot!.querySelector("ha-paper-dialog")!; + } + + private get _viewConfigTitle(): string { + if (!this._config || !this._config.title) { + return this.hass!.localize("ui.panel.lovelace.editor.edit_view.header"); + } + + return this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.header_name", + "name", + this._config.title + ); } protected render(): TemplateResult { if (!this._params) { return html``; } + + let content; + switch (this._curTab) { + case "tab-settings": + content = html` + + `; + break; + case "tab-badges": + content = html` + ${this._badges?.length + ? html` +
+ ${this._badges.map((badgeConfig) => { + return html` + + `; + })} +
+ ` + : ""} + + `; + break; + case "tab-visibility": + content = html` + + `; + break; + case "tab-cards": + content = html` Cards `; + break; + } return html` - - + +

+ ${this._viewConfigTitle} +

+ + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_settings" + )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_badges" + )} + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.tab_visibility" + )} + + ${content} +
+ ${this._params.viewIndex !== undefined + ? html` + + ${this.hass!.localize( + "ui.panel.lovelace.editor.edit_view.delete" + )} + + ` + : ""} + ${this.hass!.localize("ui.common.cancel")} + + + ${this.hass!.localize("ui.common.save")} +
+
`; } + + private async _delete(): Promise { + if (!this._params) { + return; + } + try { + await this._params.lovelace!.saveConfig( + deleteView(this._params.lovelace!.config, this._params.viewIndex!) + ); + this._closeDialog(); + navigate(this, `/${window.location.pathname.split("/")[1]}`); + } catch (err) { + showAlertDialog(this, { + text: `Deleting failed: ${err.message}`, + }); + } + } + + private _deleteConfirm(): void { + showConfirmationDialog(this, { + title: this.hass!.localize( + `ui.panel.lovelace.views.confirm_delete${ + this._cards?.length ? `_existing_cards` : "" + }` + ), + text: this.hass!.localize( + `ui.panel.lovelace.views.confirm_delete${ + this._cards?.length ? `_existing_cards` : "" + }_text`, + "name", + this._config?.title || "Unnamed view", + "number", + this._cards?.length || 0 + ), + confirm: () => this._delete(), + }); + } + + private async _resizeDialog(): Promise { + await this.updateComplete; + fireEvent(this._dialog as HTMLElement, "iron-resize"); + } + + private _closeDialog(): void { + this._curTabIndex = 0; + this._params = undefined; + this._config = {}; + this._badges = []; + this._dialog.close(); + } + + private _handleTabSelected(ev: CustomEvent): void { + if (!ev.detail.value) { + return; + } + this._curTab = ev.detail.value.id; + this._resizeDialog(); + } + + private async _save(): Promise { + if (!this._params || !this._config) { + return; + } + if (!this._isConfigChanged()) { + this._closeDialog(); + return; + } + + this._saving = true; + + const viewConf: LovelaceViewConfig = { + ...this._config, + badges: this._badges, + cards: this._cards, + }; + + const lovelace = this._params.lovelace!; + + try { + await lovelace.saveConfig( + this._creatingView + ? addView(lovelace.config, viewConf) + : replaceView(lovelace.config, this._params.viewIndex!, viewConf) + ); + if (this._params.saveCallback) { + this._params.saveCallback( + this._params.viewIndex || lovelace.config.views.length, + viewConf + ); + } + this._closeDialog(); + } catch (err) { + showAlertDialog(this, { + text: `Saving failed: ${err.message}`, + }); + } finally { + this._saving = false; + } + } + + private _viewConfigChanged(ev: ViewEditEvent): void { + if (ev.detail && ev.detail.config) { + this._config = ev.detail.config; + } + } + + private _viewVisibilityChanged( + ev: HASSDomEvent + ): void { + if (ev.detail.visible && this._config) { + this._config.visible = ev.detail.visible; + } + } + + private _badgesChanged(ev: EntitiesEditorEvent): void { + if (!this._badges || !this.hass || !ev.detail || !ev.detail.entities) { + return; + } + this._badges = processEditorEntities(ev.detail.entities); + this._resizeDialog(); + } + + private _isConfigChanged(): boolean { + return ( + this._creatingView || + JSON.stringify(this._config) !== + JSON.stringify( + this._params!.lovelace!.config.views[this._params!.viewIndex!] + ) + ); + } + + private get _creatingView(): boolean { + return this._params!.viewIndex === undefined; + } + + static get styles(): CSSResult[] { + return [ + haStyleDialog, + css` + @media all and (max-width: 450px), all and (max-height: 500px) { + /* overrule the ha-style-dialog max-height on small screens */ + ha-paper-dialog { + max-height: 100%; + height: 100%; + } + } + @media all and (min-width: 660px) { + ha-paper-dialog { + width: 650px; + } + } + ha-paper-dialog { + max-width: 650px; + } + paper-tabs { + --paper-tabs-selection-bar-color: var(--primary-color); + text-transform: uppercase; + border-bottom: 1px solid rgba(0, 0, 0, 0.1); + } + mwc-button paper-spinner { + width: 14px; + height: 14px; + margin-right: 20px; + } + mwc-button.warning { + margin-right: auto; + } + paper-spinner { + display: none; + } + paper-spinner[active] { + display: block; + } + paper-dialog-scrollable { + margin-top: 0; + } + .hidden { + display: none; + } + .error { + color: var(--error-color); + border-bottom: 1px solid var(--error-color); + } + .preview-badges { + display: flex; + justify-content: center; + margin: 12px 16px; + flex-wrap: wrap; + } + `, + ]; + } } declare global { diff --git a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts b/src/panels/lovelace/editor/view-editor/hui-edit-view.ts deleted file mode 100644 index 2d8ef67175..0000000000 --- a/src/panels/lovelace/editor/view-editor/hui-edit-view.ts +++ /dev/null @@ -1,400 +0,0 @@ -import "@material/mwc-button"; -import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable"; -import "../../../../components/ha-icon-button"; -import "@polymer/paper-spinner/paper-spinner"; -import "@polymer/paper-tabs/paper-tab"; -import "@polymer/paper-tabs/paper-tabs"; -import { - css, - CSSResult, - customElement, - html, - LitElement, - property, - TemplateResult, -} from "lit-element"; -import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; -import { navigate } from "../../../../common/navigate"; -import "../../../../components/dialog/ha-paper-dialog"; -import type { HaPaperDialog } from "../../../../components/dialog/ha-paper-dialog"; -import type { - LovelaceBadgeConfig, - LovelaceCardConfig, - LovelaceViewConfig, -} from "../../../../data/lovelace"; -import { - showAlertDialog, - showConfirmationDialog, -} from "../../../../dialogs/generic/show-dialog-box"; -import { haStyleDialog } from "../../../../resources/styles"; -import type { HomeAssistant } from "../../../../types"; -import "../../components/hui-entity-editor"; -import type { Lovelace } from "../../types"; -import { addView, deleteView, replaceView } from "../config-util"; -import "../hui-badge-preview"; -import { processEditorEntities } from "../process-editor-entities"; -import { - EntitiesEditorEvent, - ViewEditEvent, - ViewVisibilityChangeEvent, -} from "../types"; -import "./hui-view-editor"; -import "./hui-view-visibility-editor"; - -@customElement("hui-edit-view") -export class HuiEditView extends LitElement { - @property() public lovelace?: Lovelace; - - @property() public viewIndex?: number; - - @property() public hass?: HomeAssistant; - - @property() private _config?: LovelaceViewConfig; - - @property() private _badges?: LovelaceBadgeConfig[]; - - @property() private _cards?: LovelaceCardConfig[]; - - @property() private _saving: boolean; - - @property() private _curTab?: string; - - private _curTabIndex: number; - - public constructor() { - super(); - this._saving = false; - this._curTabIndex = 0; - } - - public async showDialog(): Promise { - // Wait till dialog is rendered. - if (this._dialog == null) { - await this.updateComplete; - } - - if (this.viewIndex === undefined) { - this._config = {}; - this._badges = []; - this._cards = []; - } else { - const { cards, badges, ...viewConfig } = this.lovelace!.config.views[ - this.viewIndex - ]; - this._config = viewConfig; - this._badges = badges ? processEditorEntities(badges) : []; - this._cards = cards; - } - - this._dialog.open(); - } - - private get _dialog(): HaPaperDialog { - return this.shadowRoot!.querySelector("ha-paper-dialog")!; - } - - private get _viewConfigTitle(): string { - if (!this._config || !this._config.title) { - return this.hass!.localize("ui.panel.lovelace.editor.edit_view.header"); - } - - return this.hass!.localize( - "ui.panel.lovelace.editor.edit_view.header_name", - "name", - this._config.title - ); - } - - protected render(): TemplateResult { - let content; - switch (this._curTab) { - case "tab-settings": - content = html` - - `; - break; - case "tab-badges": - content = html` - ${this._badges?.length - ? html` -
- ${this._badges.map((badgeConfig) => { - return html` - - `; - })} -
- ` - : ""} - - `; - break; - case "tab-visibility": - content = html` - - `; - break; - case "tab-cards": - content = html` Cards `; - break; - } - return html` - -

- ${this._viewConfigTitle} -

- - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_view.tab_settings" - )} - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_view.tab_badges" - )} - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_view.tab_visibility" - )} - - ${content} -
- ${this.viewIndex !== undefined - ? html` - - ${this.hass!.localize( - "ui.panel.lovelace.editor.edit_view.delete" - )} - - ` - : ""} - ${this.hass!.localize("ui.common.cancel")} - - - ${this.hass!.localize("ui.common.save")} -
-
- `; - } - - private async _delete(): Promise { - try { - await this.lovelace!.saveConfig( - deleteView(this.lovelace!.config, this.viewIndex!) - ); - this._closeDialog(); - navigate(this, `/${window.location.pathname.split("/")[1]}`); - } catch (err) { - showAlertDialog(this, { - text: `Deleting failed: ${err.message}`, - }); - } - } - - private _deleteConfirm(): void { - showConfirmationDialog(this, { - title: this.hass!.localize( - `ui.panel.lovelace.views.confirm_delete${ - this._cards?.length ? `_existing_cards` : "" - }` - ), - text: this.hass!.localize( - `ui.panel.lovelace.views.confirm_delete${ - this._cards?.length ? `_existing_cards` : "" - }_text`, - "name", - this._config?.title || "Unnamed view", - "number", - this._cards?.length || 0 - ), - confirm: () => this._delete(), - }); - } - - private async _resizeDialog(): Promise { - await this.updateComplete; - fireEvent(this._dialog as HTMLElement, "iron-resize"); - } - - private _closeDialog(): void { - this._curTabIndex = 0; - this.lovelace = undefined; - this._config = {}; - this._badges = []; - this._dialog.close(); - } - - private _handleTabSelected(ev: CustomEvent): void { - if (!ev.detail.value) { - return; - } - this._curTab = ev.detail.value.id; - this._resizeDialog(); - } - - private async _save(): Promise { - if (!this._config) { - return; - } - if (!this._isConfigChanged()) { - this._closeDialog(); - return; - } - - this._saving = true; - - const viewConf: LovelaceViewConfig = { - ...this._config, - badges: this._badges, - cards: this._cards, - }; - - const lovelace = this.lovelace!; - - try { - await lovelace.saveConfig( - this._creatingView - ? addView(lovelace.config, viewConf) - : replaceView(lovelace.config, this.viewIndex!, viewConf) - ); - this._closeDialog(); - } catch (err) { - showAlertDialog(this, { - text: `Saving failed: ${err.message}`, - }); - } finally { - this._saving = false; - } - } - - private _viewConfigChanged(ev: ViewEditEvent): void { - if (ev.detail && ev.detail.config) { - this._config = ev.detail.config; - } - } - - private _viewVisibilityChanged( - ev: HASSDomEvent - ): void { - if (ev.detail.visible && this._config) { - this._config.visible = ev.detail.visible; - } - } - - private _badgesChanged(ev: EntitiesEditorEvent): void { - if (!this._badges || !this.hass || !ev.detail || !ev.detail.entities) { - return; - } - this._badges = processEditorEntities(ev.detail.entities); - this._resizeDialog(); - } - - private _isConfigChanged(): boolean { - return ( - this._creatingView || - JSON.stringify(this._config) !== - JSON.stringify(this.lovelace!.config.views[this.viewIndex!]) - ); - } - - private get _creatingView(): boolean { - return this.viewIndex === undefined; - } - - static get styles(): CSSResult[] { - return [ - haStyleDialog, - css` - @media all and (max-width: 450px), all and (max-height: 500px) { - /* overrule the ha-style-dialog max-height on small screens */ - ha-paper-dialog { - max-height: 100%; - height: 100%; - } - } - @media all and (min-width: 660px) { - ha-paper-dialog { - width: 650px; - } - } - ha-paper-dialog { - max-width: 650px; - } - paper-tabs { - --paper-tabs-selection-bar-color: var(--primary-color); - text-transform: uppercase; - border-bottom: 1px solid rgba(0, 0, 0, 0.1); - } - mwc-button paper-spinner { - width: 14px; - height: 14px; - margin-right: 20px; - } - mwc-button.warning { - margin-right: auto; - } - paper-spinner { - display: none; - } - paper-spinner[active] { - display: block; - } - paper-dialog-scrollable { - margin-top: 0; - } - .hidden { - display: none; - } - .error { - color: var(--error-color); - border-bottom: 1px solid var(--error-color); - } - .preview-badges { - display: flex; - justify-content: center; - margin: 12px 16px; - flex-wrap: wrap; - } - `, - ]; - } -} - -declare global { - interface HTMLElementTagNameMap { - "hui-edit-view": HuiEditView; - } -} diff --git a/src/panels/lovelace/editor/view-editor/show-edit-view-dialog.ts b/src/panels/lovelace/editor/view-editor/show-edit-view-dialog.ts index c752aa3eb2..00d2153fb9 100644 --- a/src/panels/lovelace/editor/view-editor/show-edit-view-dialog.ts +++ b/src/panels/lovelace/editor/view-editor/show-edit-view-dialog.ts @@ -1,5 +1,6 @@ import { fireEvent, HASSDomEvent } from "../../../../common/dom/fire_event"; import { Lovelace } from "../../types"; +import { LovelaceViewConfig } from "../../../../data/lovelace"; declare global { // for fire event @@ -20,6 +21,7 @@ const dialogTag = "hui-dialog-edit-view"; export interface EditViewDialogParams { lovelace: Lovelace; viewIndex?: number; + saveCallback?: (viewIndex: number, viewConfig: LovelaceViewConfig) => void; } const registerEditViewDialog = (element: HTMLElement): Event => diff --git a/src/panels/lovelace/hui-root.ts b/src/panels/lovelace/hui-root.ts index ad52c6a23b..3b1ba96e00 100644 --- a/src/panels/lovelace/hui-root.ts +++ b/src/panels/lovelace/hui-root.ts @@ -31,7 +31,11 @@ import "../../components/ha-icon"; import "../../components/ha-menu-button"; import "../../components/ha-icon-button-arrow-next"; import "../../components/ha-icon-button-arrow-prev"; -import type { LovelaceConfig, LovelacePanelConfig } from "../../data/lovelace"; +import type { + LovelaceConfig, + LovelacePanelConfig, + LovelaceViewConfig, +} from "../../data/lovelace"; import { showAlertDialog, showConfirmationDialog, @@ -558,6 +562,10 @@ class HUIRoot extends LitElement { private _addView() { showEditViewDialog(this, { lovelace: this.lovelace!, + saveCallback: (viewIndex: number, viewConfig: LovelaceViewConfig) => { + const path = viewConfig.path || viewIndex; + navigate(this, `${this.route?.prefix}/${path}`); + }, }); }