mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-29 04:06:35 +00:00
Change edit mode + add edit lovelace (#2277)
* Change edit mode + add edit lovelace * Comments * Fix (yes it was used :-) * Raw edit header changed
This commit is contained in:
parent
d277571735
commit
8c61624a9c
@ -87,7 +87,7 @@ export class HuiCardOptions extends hassLocalizeLitMixin(LitElement) {
|
||||
}
|
||||
return html`
|
||||
<paper-item @click="${this._moveCard}" .index="${index}"
|
||||
>${view.title}</paper-item
|
||||
>${view.title || "Unnamed view"}</paper-item
|
||||
>
|
||||
`;
|
||||
})
|
||||
|
@ -0,0 +1,152 @@
|
||||
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
|
||||
import { TemplateResult } from "lit-html";
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import "@polymer/paper-dialog/paper-dialog";
|
||||
// This is not a duplicate import, one is for types, one is for element.
|
||||
// tslint:disable-next-line
|
||||
import { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog";
|
||||
import "@polymer/paper-button/paper-button";
|
||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
||||
import "./hui-lovelace-editor";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { LovelaceConfig } from "../../../../data/lovelace";
|
||||
import { hassLocalizeLitMixin } from "../../../../mixins/lit-localize-mixin";
|
||||
import { Lovelace } from "../../types";
|
||||
|
||||
export class HuiDialogEditLovelace extends hassLocalizeLitMixin(LitElement) {
|
||||
public hass?: HomeAssistant;
|
||||
private _lovelace?: Lovelace;
|
||||
private _config?: LovelaceConfig;
|
||||
private _saving: boolean;
|
||||
|
||||
static get properties(): PropertyDeclarations {
|
||||
return {
|
||||
hass: {},
|
||||
_lovelace: {},
|
||||
};
|
||||
}
|
||||
|
||||
protected constructor() {
|
||||
super();
|
||||
this._saving = false;
|
||||
}
|
||||
|
||||
public async showDialog(lovelace: Lovelace): Promise<void> {
|
||||
this._lovelace = lovelace;
|
||||
if (this._dialog == null) {
|
||||
await this.updateComplete;
|
||||
}
|
||||
|
||||
const { views, ...lovelaceConfig } = this._lovelace!.config;
|
||||
this._config = lovelaceConfig as LovelaceConfig;
|
||||
|
||||
this._dialog.open();
|
||||
}
|
||||
|
||||
private get _dialog(): PaperDialogElement {
|
||||
return this.shadowRoot!.querySelector("paper-dialog")!;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
${this.renderStyle()}
|
||||
<paper-dialog with-backdrop>
|
||||
<h2>Edit Lovelace</h2>
|
||||
<paper-dialog-scrollable>
|
||||
<hui-lovelace-editor
|
||||
.hass="${this.hass}"
|
||||
.config="${this._config}"
|
||||
@lovelace-config-changed="${this._ConfigChanged}"
|
||||
></hui-lovelace-editor
|
||||
></paper-dialog-scrollable>
|
||||
<div class="paper-dialog-buttons">
|
||||
<paper-button @click="${this._closeDialog}"
|
||||
>${this.localize("ui.common.cancel")}</paper-button
|
||||
>
|
||||
<paper-button
|
||||
?disabled="${!this._config || this._saving}"
|
||||
@click="${this._save}"
|
||||
>
|
||||
<paper-spinner
|
||||
?active="${this._saving}"
|
||||
alt="Saving"
|
||||
></paper-spinner>
|
||||
${this.localize("ui.common.save")}</paper-button
|
||||
>
|
||||
</div>
|
||||
</paper-dialog>
|
||||
`;
|
||||
}
|
||||
|
||||
private _closeDialog(): void {
|
||||
this._config = undefined;
|
||||
this._dialog.close();
|
||||
}
|
||||
|
||||
private async _save(): Promise<void> {
|
||||
if (!this._config) {
|
||||
return;
|
||||
}
|
||||
if (!this._isConfigChanged()) {
|
||||
this._closeDialog();
|
||||
return;
|
||||
}
|
||||
|
||||
this._saving = true;
|
||||
const lovelace = this._lovelace!;
|
||||
|
||||
const config: LovelaceConfig = {
|
||||
...lovelace.config,
|
||||
...this._config,
|
||||
};
|
||||
|
||||
try {
|
||||
await lovelace.saveConfig(config);
|
||||
this._closeDialog();
|
||||
} catch (err) {
|
||||
alert(`Saving failed: ${err.message}`);
|
||||
} finally {
|
||||
this._saving = false;
|
||||
}
|
||||
}
|
||||
|
||||
private _ConfigChanged(ev: CustomEvent): void {
|
||||
if (ev.detail && ev.detail.config) {
|
||||
this._config = ev.detail.config;
|
||||
}
|
||||
}
|
||||
|
||||
private _isConfigChanged(): boolean {
|
||||
const { views, ...lovelaceConfig } = this._lovelace!.config;
|
||||
return JSON.stringify(this._config) !== JSON.stringify(lovelaceConfig);
|
||||
}
|
||||
|
||||
private renderStyle(): TemplateResult {
|
||||
return html`
|
||||
<style>
|
||||
paper-dialog {
|
||||
width: 650px;
|
||||
}
|
||||
paper-button paper-spinner {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
margin-right: 20px;
|
||||
}
|
||||
paper-spinner {
|
||||
display: none;
|
||||
}
|
||||
paper-spinner[active] {
|
||||
display: block;
|
||||
}
|
||||
</style>
|
||||
`;
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-dialog-edit-lovelace": HuiDialogEditLovelace;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("hui-dialog-edit-lovelace", HuiDialogEditLovelace);
|
@ -0,0 +1,80 @@
|
||||
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
|
||||
import { TemplateResult } from "lit-html";
|
||||
import "@polymer/paper-input/paper-input";
|
||||
|
||||
import { EditorTarget } from "../types";
|
||||
import { hassLocalizeLitMixin } from "../../../../mixins/lit-localize-mixin";
|
||||
import { HomeAssistant } from "../../../../types";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { configElementStyle } from "../config-elements/config-elements-style";
|
||||
|
||||
import { LovelaceConfig } from "../../../../data/lovelace";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"lovelace-config-changed": {
|
||||
config: LovelaceConfig;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class HuiLovelaceEditor extends hassLocalizeLitMixin(LitElement) {
|
||||
static get properties(): PropertyDeclarations {
|
||||
return { hass: {}, config: {} };
|
||||
}
|
||||
|
||||
public hass?: HomeAssistant;
|
||||
public config?: LovelaceConfig;
|
||||
|
||||
get _title(): string {
|
||||
if (!this.config) {
|
||||
return "";
|
||||
}
|
||||
return this.config.title || "";
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
return html`
|
||||
${configElementStyle}
|
||||
<div class="card-config">
|
||||
<paper-input
|
||||
label="Title"
|
||||
.value="${this._title}"
|
||||
.configValue="${"title"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: Event): void {
|
||||
if (!this.config) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = ev.currentTarget! as EditorTarget;
|
||||
|
||||
if (this[`_${target.configValue}`] === target.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
let newConfig;
|
||||
|
||||
if (target.configValue) {
|
||||
newConfig = {
|
||||
...this.config,
|
||||
[target.configValue]: target.value,
|
||||
};
|
||||
}
|
||||
|
||||
fireEvent(this, "lovelace-config-changed", { config: newConfig });
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-lovelace-editor": HuiLovelaceEditor;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("hui-lovelace-editor", HuiLovelaceEditor);
|
@ -0,0 +1,32 @@
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { Lovelace } from "../../types";
|
||||
|
||||
declare global {
|
||||
// for fire event
|
||||
interface HASSDomEvents {
|
||||
"show-edit-lovelace": Lovelace;
|
||||
}
|
||||
}
|
||||
|
||||
let registeredDialog = false;
|
||||
const dialogShowEvent = "show-edit-lovelace";
|
||||
const dialogTag = "hui-dialog-edit-lovelace";
|
||||
|
||||
const registerEditLovelaceDialog = (element: HTMLElement) =>
|
||||
fireEvent(element, "register-dialog", {
|
||||
dialogShowEvent,
|
||||
dialogTag,
|
||||
dialogImport: () =>
|
||||
import(/* webpackChunkName: "hui-dialog-edit-lovelace" */ "./hui-dialog-edit-lovelace"),
|
||||
});
|
||||
|
||||
export const showEditLovelaceDialog = (
|
||||
element: HTMLElement,
|
||||
lovelace: Lovelace
|
||||
) => {
|
||||
if (!registeredDialog) {
|
||||
registeredDialog = true;
|
||||
registerEditLovelaceDialog(element);
|
||||
}
|
||||
fireEvent(element, dialogShowEvent, lovelace);
|
||||
};
|
@ -90,7 +90,9 @@ class LovelaceFullConfigEditor extends hassLocalizeLitMixin(LitElement) {
|
||||
app-header-layout {
|
||||
height: 100vh;
|
||||
}
|
||||
|
||||
app-toolbar {
|
||||
background-color: #455a64;
|
||||
}
|
||||
paper-button {
|
||||
font-size: 16px;
|
||||
}
|
||||
|
@ -43,6 +43,7 @@ import "./hui-view";
|
||||
import { HUIView } from "./hui-view";
|
||||
import createCardElement from "./common/create-card-element";
|
||||
import { showEditViewDialog } from "./editor/view-editor/show-edit-view-dialog";
|
||||
import { showEditLovelaceDialog } from "./editor/lovelace-editor/show-edit-lovelace-dialog";
|
||||
import { Lovelace } from "./types";
|
||||
import { afterNextRender } from "../../common/util/render-status";
|
||||
|
||||
@ -121,18 +122,51 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
.narrow="${this.narrow}"
|
||||
></hui-notification-drawer>
|
||||
<ha-app-layout id="layout">
|
||||
<app-header slot="header" effects="waterfall" fixed condenses>
|
||||
<app-header slot="header" effects="waterfall" class="${classMap({
|
||||
"edit-mode": this._editMode,
|
||||
})}" fixed condenses>
|
||||
${
|
||||
this._editMode
|
||||
? html`
|
||||
<app-toolbar>
|
||||
<app-toolbar class="edit-mode">
|
||||
<paper-icon-button
|
||||
icon="hass:close"
|
||||
@click="${this._editModeDisable}"
|
||||
></paper-icon-button>
|
||||
<div main-title>
|
||||
${this.localize("ui.panel.lovelace.editor.header")}
|
||||
${
|
||||
this.config.title ||
|
||||
this.localize("ui.panel.lovelace.editor.header")
|
||||
}
|
||||
<paper-icon-button
|
||||
icon="hass:pencil"
|
||||
class="edit-icon"
|
||||
@click="${this._editLovelace}"
|
||||
></paper-icon-button>
|
||||
</div>
|
||||
<paper-icon-button
|
||||
icon="hass:help-circle"
|
||||
title="Help"
|
||||
@click="${this._handleHelp}"
|
||||
></paper-icon-button>
|
||||
<paper-menu-button
|
||||
no-animations
|
||||
horizontal-align="right"
|
||||
horizontal-offset="-5"
|
||||
>
|
||||
<paper-icon-button
|
||||
icon="hass:dots-vertical"
|
||||
slot="dropdown-trigger"
|
||||
></paper-icon-button>
|
||||
<paper-listbox
|
||||
@iron-select="${this._deselect}"
|
||||
slot="dropdown-content"
|
||||
>
|
||||
<paper-item @click="${this.lovelace!.enableFullEditMode}"
|
||||
>Raw config editor</paper-item
|
||||
>
|
||||
</paper-listbox>
|
||||
</paper-menu-button>
|
||||
</app-toolbar>
|
||||
`
|
||||
: html`
|
||||
@ -180,16 +214,6 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
this.localize("ui.panel.lovelace.editor.configure_ui")
|
||||
}</paper-item
|
||||
>
|
||||
${
|
||||
this._storageMode
|
||||
? html`
|
||||
<paper-item
|
||||
@click="${this.lovelace!.enableFullEditMode}"
|
||||
>Raw config editor</paper-item
|
||||
>
|
||||
`
|
||||
: ""
|
||||
}
|
||||
<paper-item @click="${this._handleHelp}">Help</paper-item>
|
||||
</paper-listbox>
|
||||
</paper-menu-button>
|
||||
@ -224,7 +248,7 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
this._editMode
|
||||
? html`
|
||||
<ha-icon
|
||||
class="edit-view-icon"
|
||||
class="edit-icon view"
|
||||
@click="${this._editView}"
|
||||
icon="hass:pencil"
|
||||
></ha-icon>
|
||||
@ -293,11 +317,20 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
--paper-tabs-selection-bar-color: var(--text-primary-color, #fff);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
paper-tab.iron-selected .edit-view-icon {
|
||||
.edit-mode {
|
||||
background-color: #455a64;
|
||||
}
|
||||
.edit-mode div[main-title] {
|
||||
pointer-events: auto;
|
||||
}
|
||||
paper-tab.iron-selected .edit-icon {
|
||||
display: inline-flex;
|
||||
}
|
||||
.edit-view-icon {
|
||||
.edit-icon {
|
||||
color: var(--accent-color);
|
||||
padding-left: 8px;
|
||||
}
|
||||
.edit-icon.view {
|
||||
display: none;
|
||||
}
|
||||
#add-view {
|
||||
@ -412,10 +445,6 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
return this.lovelace!.mode === "yaml";
|
||||
}
|
||||
|
||||
private get _storageMode(): boolean {
|
||||
return this.lovelace!.mode === "storage";
|
||||
}
|
||||
|
||||
private get _editMode() {
|
||||
return this.lovelace!.editMode;
|
||||
}
|
||||
@ -478,6 +507,10 @@ class HUIRoot extends hassLocalizeLitMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private _editLovelace() {
|
||||
showEditLovelaceDialog(this, this.lovelace!);
|
||||
}
|
||||
|
||||
private _editView() {
|
||||
showEditViewDialog(this, {
|
||||
lovelace: this.lovelace!,
|
||||
|
Loading…
x
Reference in New Issue
Block a user