2019-01-13 08:32:53 +01:00
|
|
|
import {
|
2019-08-10 21:14:35 +02:00
|
|
|
css,
|
2019-01-13 08:32:53 +01:00
|
|
|
html,
|
|
|
|
LitElement,
|
|
|
|
TemplateResult,
|
2019-08-10 21:14:35 +02:00
|
|
|
CSSResultArray,
|
2019-03-05 20:36:17 +01:00
|
|
|
customElement,
|
|
|
|
property,
|
2019-01-13 08:32:53 +01:00
|
|
|
} from "lit-element";
|
2018-11-02 16:00:25 +01:00
|
|
|
|
2020-02-25 21:51:07 +01:00
|
|
|
import deepFreeze from "deep-freeze";
|
|
|
|
|
2018-12-10 08:57:29 +01:00
|
|
|
import { HomeAssistant } from "../../../../types";
|
|
|
|
import { HASSDomEvent } from "../../../../common/dom/fire_event";
|
2019-10-22 10:24:25 +02:00
|
|
|
import {
|
|
|
|
LovelaceCardConfig,
|
|
|
|
LovelaceViewConfig,
|
|
|
|
} from "../../../../data/lovelace";
|
2019-08-10 21:14:35 +02:00
|
|
|
import "./hui-card-editor";
|
|
|
|
// tslint:disable-next-line
|
|
|
|
import { HuiCardEditor } from "./hui-card-editor";
|
|
|
|
import "./hui-card-preview";
|
|
|
|
import "./hui-card-picker";
|
2018-12-10 08:57:29 +01:00
|
|
|
import { EditCardDialogParams } from "./show-edit-card-dialog";
|
2019-03-26 23:31:43 +01:00
|
|
|
import { addCard, replaceCard } from "../config-util";
|
2018-11-02 16:00:25 +01:00
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
import "../../../../components/dialog/ha-paper-dialog";
|
|
|
|
import { haStyleDialog } from "../../../../resources/styles";
|
2019-12-23 10:39:17 +01:00
|
|
|
import { showSaveSuccessToast } from "../../../../util/toast-saved-success";
|
2019-08-10 21:14:35 +02:00
|
|
|
|
2018-11-25 20:47:29 +01:00
|
|
|
declare global {
|
|
|
|
// for fire event
|
|
|
|
interface HASSDomEvents {
|
|
|
|
"reload-lovelace": undefined;
|
|
|
|
}
|
|
|
|
// for add event listener
|
|
|
|
interface HTMLElementEventMap {
|
|
|
|
"reload-lovelace": HASSDomEvent<undefined>;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-03-05 20:36:17 +01:00
|
|
|
@customElement("hui-dialog-edit-card")
|
2018-11-02 16:00:25 +01:00
|
|
|
export class HuiDialogEditCard extends LitElement {
|
2019-12-23 10:39:17 +01:00
|
|
|
@property() protected hass!: HomeAssistant;
|
2018-11-02 16:00:25 +01:00
|
|
|
|
2019-03-05 20:36:17 +01:00
|
|
|
@property() private _params?: EditCardDialogParams;
|
|
|
|
|
|
|
|
@property() private _cardConfig?: LovelaceCardConfig;
|
2019-10-22 10:24:25 +02:00
|
|
|
@property() private _viewConfig!: LovelaceViewConfig;
|
2018-11-02 16:00:25 +01:00
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
@property() private _saving: boolean = false;
|
|
|
|
@property() private _error?: string;
|
2018-12-10 08:57:29 +01:00
|
|
|
|
2018-11-25 20:09:32 +01:00
|
|
|
public async showDialog(params: EditCardDialogParams): Promise<void> {
|
|
|
|
this._params = params;
|
2019-03-26 23:31:43 +01:00
|
|
|
const [view, card] = params.path;
|
2019-12-23 10:39:17 +01:00
|
|
|
this._viewConfig = params.lovelaceConfig.views[view];
|
2018-12-10 08:57:29 +01:00
|
|
|
this._cardConfig =
|
2020-03-18 20:33:59 +01:00
|
|
|
card !== undefined ? this._viewConfig.cards![card] : params.cardConfig;
|
2020-02-25 21:51:07 +01:00
|
|
|
if (this._cardConfig && !Object.isFrozen(this._cardConfig)) {
|
|
|
|
this._cardConfig = deepFreeze(this._cardConfig);
|
|
|
|
}
|
2018-11-02 16:00:25 +01:00
|
|
|
}
|
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
private get _cardEditorEl(): HuiCardEditor | null {
|
|
|
|
return this.shadowRoot!.querySelector("hui-card-editor");
|
|
|
|
}
|
|
|
|
|
2020-01-27 17:34:22 +01:00
|
|
|
protected render(): TemplateResult {
|
2018-11-25 20:09:32 +01:00
|
|
|
if (!this._params) {
|
|
|
|
return html``;
|
|
|
|
}
|
2019-08-10 21:14:35 +02:00
|
|
|
|
2019-10-07 20:17:12 +02:00
|
|
|
let heading: string;
|
|
|
|
if (this._cardConfig && this._cardConfig.type) {
|
|
|
|
heading = `${this.hass!.localize(
|
|
|
|
`ui.panel.lovelace.editor.card.${this._cardConfig.type}.name`
|
|
|
|
)} ${this.hass!.localize("ui.panel.lovelace.editor.edit_card.header")}`;
|
2019-10-22 10:24:25 +02:00
|
|
|
} else if (!this._cardConfig) {
|
|
|
|
heading = this._viewConfig.title
|
|
|
|
? this.hass!.localize(
|
|
|
|
"ui.panel.lovelace.editor.edit_card.pick_card_view_title",
|
|
|
|
"name",
|
|
|
|
`"${this._viewConfig.title}"`
|
|
|
|
)
|
|
|
|
: this.hass!.localize("ui.panel.lovelace.editor.edit_card.pick_card");
|
2019-10-07 20:17:12 +02:00
|
|
|
} else {
|
|
|
|
heading = this.hass!.localize(
|
|
|
|
"ui.panel.lovelace.editor.edit_card.header"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
2018-11-02 16:00:25 +01:00
|
|
|
return html`
|
2020-01-23 14:43:09 +01:00
|
|
|
<ha-paper-dialog with-backdrop opened modal @keyup=${this._handleKeyUp}>
|
2019-08-10 21:14:35 +02:00
|
|
|
<h2>
|
2019-10-07 20:17:12 +02:00
|
|
|
${heading}
|
2019-08-10 21:14:35 +02:00
|
|
|
</h2>
|
|
|
|
<paper-dialog-scrollable>
|
|
|
|
${this._cardConfig === undefined
|
|
|
|
? html`
|
|
|
|
<hui-card-picker
|
2020-03-03 20:53:55 +01:00
|
|
|
.lovelace="${this._params.lovelaceConfig}"
|
2020-02-28 22:35:42 +01:00
|
|
|
.hass=${this.hass}
|
2019-09-08 22:43:28 +02:00
|
|
|
@config-changed="${this._handleCardPicked}"
|
2019-08-10 21:14:35 +02:00
|
|
|
></hui-card-picker>
|
|
|
|
`
|
|
|
|
: html`
|
|
|
|
<div class="content">
|
|
|
|
<div class="element-editor">
|
|
|
|
<hui-card-editor
|
2020-02-28 22:35:42 +01:00
|
|
|
.hass=${this.hass}
|
2020-03-04 22:04:04 +01:00
|
|
|
.lovelace="${this._params.lovelaceConfig}"
|
2019-08-10 21:14:35 +02:00
|
|
|
.value="${this._cardConfig}"
|
|
|
|
@config-changed="${this._handleConfigChanged}"
|
|
|
|
></hui-card-editor>
|
|
|
|
</div>
|
|
|
|
<div class="element-preview">
|
|
|
|
<hui-card-preview
|
2020-02-28 22:35:42 +01:00
|
|
|
.hass=${this.hass}
|
2019-08-10 21:14:35 +02:00
|
|
|
.config="${this._cardConfig}"
|
|
|
|
class=${this._error ? "blur" : ""}
|
|
|
|
></hui-card-preview>
|
|
|
|
${this._error
|
|
|
|
? html`
|
|
|
|
<paper-spinner
|
|
|
|
active
|
|
|
|
alt="Can't update card"
|
|
|
|
></paper-spinner>
|
|
|
|
`
|
|
|
|
: ``}
|
|
|
|
</div>
|
|
|
|
</div>
|
|
|
|
`}
|
|
|
|
</paper-dialog-scrollable>
|
|
|
|
<div class="paper-dialog-buttons">
|
|
|
|
<mwc-button @click="${this._close}">
|
|
|
|
${this.hass!.localize("ui.common.cancel")}
|
|
|
|
</mwc-button>
|
2019-10-19 14:18:59 +02:00
|
|
|
${this._cardConfig !== undefined
|
|
|
|
? html`
|
|
|
|
<mwc-button
|
|
|
|
?disabled="${!this._canSave || this._saving}"
|
|
|
|
@click="${this._save}"
|
|
|
|
>
|
|
|
|
${this._saving
|
|
|
|
? html`
|
|
|
|
<paper-spinner active alt="Saving"></paper-spinner>
|
|
|
|
`
|
|
|
|
: this.hass!.localize("ui.common.save")}
|
|
|
|
</mwc-button>
|
|
|
|
`
|
|
|
|
: ``}
|
2019-08-10 21:14:35 +02:00
|
|
|
</div>
|
|
|
|
</ha-paper-dialog>
|
2018-11-02 16:00:25 +01:00
|
|
|
`;
|
|
|
|
}
|
2018-12-03 14:11:46 +01:00
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
static get styles(): CSSResultArray {
|
|
|
|
return [
|
|
|
|
haStyleDialog,
|
|
|
|
css`
|
|
|
|
:host {
|
|
|
|
--code-mirror-max-height: calc(100vh - 176px);
|
|
|
|
}
|
|
|
|
|
|
|
|
@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%;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-11-04 21:34:59 +01:00
|
|
|
@media all and (min-width: 850px) {
|
2019-08-10 21:14:35 +02:00
|
|
|
ha-paper-dialog {
|
|
|
|
width: 845px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ha-paper-dialog {
|
|
|
|
max-width: 845px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.center {
|
|
|
|
margin-left: auto;
|
|
|
|
margin-right: auto;
|
|
|
|
}
|
|
|
|
|
|
|
|
.content {
|
|
|
|
display: flex;
|
|
|
|
flex-direction: column;
|
|
|
|
margin: 0 -10px;
|
|
|
|
}
|
|
|
|
.content hui-card-preview {
|
|
|
|
margin: 4px auto;
|
|
|
|
max-width: 390px;
|
|
|
|
}
|
|
|
|
.content .element-editor {
|
|
|
|
margin: 0 10px;
|
|
|
|
}
|
|
|
|
|
|
|
|
@media (min-width: 1200px) {
|
|
|
|
ha-paper-dialog {
|
|
|
|
max-width: none;
|
|
|
|
width: 1000px;
|
|
|
|
}
|
|
|
|
|
|
|
|
.content {
|
|
|
|
flex-direction: row;
|
|
|
|
}
|
|
|
|
.content > * {
|
|
|
|
flex-basis: 0;
|
|
|
|
flex-grow: 1;
|
|
|
|
flex-shrink: 1;
|
|
|
|
min-width: 0;
|
|
|
|
}
|
|
|
|
.content hui-card-preview {
|
|
|
|
padding: 8px 0;
|
|
|
|
margin: auto 10px;
|
|
|
|
max-width: 500px;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
mwc-button paper-spinner {
|
|
|
|
width: 14px;
|
|
|
|
height: 14px;
|
|
|
|
margin-right: 20px;
|
|
|
|
}
|
|
|
|
.hidden {
|
|
|
|
display: none;
|
|
|
|
}
|
|
|
|
.element-editor {
|
|
|
|
margin-bottom: 8px;
|
|
|
|
}
|
|
|
|
.blur {
|
|
|
|
filter: blur(2px) grayscale(100%);
|
|
|
|
}
|
|
|
|
.element-preview {
|
|
|
|
position: relative;
|
|
|
|
}
|
|
|
|
.element-preview paper-spinner {
|
|
|
|
top: 50%;
|
|
|
|
left: 50%;
|
|
|
|
position: absolute;
|
|
|
|
z-index: 10;
|
|
|
|
}
|
|
|
|
hui-card-preview {
|
|
|
|
padding-top: 8px;
|
|
|
|
margin-bottom: 4px;
|
|
|
|
display: block;
|
|
|
|
width: 100%;
|
|
|
|
}
|
|
|
|
`,
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2019-09-08 22:43:28 +02:00
|
|
|
private _handleCardPicked(ev) {
|
2020-02-25 21:51:07 +01:00
|
|
|
const config = ev.detail.config;
|
2020-03-03 20:53:55 +01:00
|
|
|
if (this._params!.entities && this._params!.entities.length) {
|
2020-02-25 21:51:07 +01:00
|
|
|
if (Object.keys(config).includes("entities")) {
|
|
|
|
config.entities = this._params!.entities;
|
|
|
|
} else if (Object.keys(config).includes("entity")) {
|
|
|
|
config.entity = this._params!.entities[0];
|
2019-09-08 22:43:28 +02:00
|
|
|
}
|
|
|
|
}
|
2020-02-25 21:51:07 +01:00
|
|
|
this._cardConfig = deepFreeze(config);
|
2019-09-08 22:43:28 +02:00
|
|
|
this._error = ev.detail.error;
|
|
|
|
}
|
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
private _handleConfigChanged(ev) {
|
2020-02-25 21:51:07 +01:00
|
|
|
this._cardConfig = deepFreeze(ev.detail.config);
|
2019-08-10 21:14:35 +02:00
|
|
|
this._error = ev.detail.error;
|
2018-12-10 08:57:29 +01:00
|
|
|
}
|
|
|
|
|
2020-01-23 14:43:09 +01:00
|
|
|
private _handleKeyUp(ev: KeyboardEvent) {
|
|
|
|
if (ev.keyCode === 27) {
|
|
|
|
this._close();
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
private _close(): void {
|
2018-12-10 08:57:29 +01:00
|
|
|
this._params = undefined;
|
|
|
|
this._cardConfig = undefined;
|
2019-08-10 21:14:35 +02:00
|
|
|
this._error = undefined;
|
|
|
|
}
|
|
|
|
|
|
|
|
private get _canSave(): boolean {
|
|
|
|
if (this._saving) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (this._cardConfig === undefined) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
if (this._cardEditorEl && this._cardEditorEl.hasError) {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2018-12-03 14:11:46 +01:00
|
|
|
}
|
2019-03-26 23:31:43 +01:00
|
|
|
|
2019-08-10 21:14:35 +02:00
|
|
|
private async _save(): Promise<void> {
|
|
|
|
this._saving = true;
|
2019-12-23 10:39:17 +01:00
|
|
|
await this._params!.saveConfig(
|
2019-03-26 23:31:43 +01:00
|
|
|
this._params!.path.length === 1
|
2019-08-10 21:14:35 +02:00
|
|
|
? addCard(
|
2019-12-23 10:39:17 +01:00
|
|
|
this._params!.lovelaceConfig,
|
2019-08-10 21:14:35 +02:00
|
|
|
this._params!.path as [number],
|
|
|
|
this._cardConfig!
|
|
|
|
)
|
2019-03-26 23:31:43 +01:00
|
|
|
: replaceCard(
|
2019-12-23 10:39:17 +01:00
|
|
|
this._params!.lovelaceConfig,
|
2019-03-26 23:31:43 +01:00
|
|
|
this._params!.path as [number, number],
|
2019-08-10 21:14:35 +02:00
|
|
|
this._cardConfig!
|
2019-03-26 23:31:43 +01:00
|
|
|
)
|
|
|
|
);
|
2019-08-10 21:14:35 +02:00
|
|
|
this._saving = false;
|
2019-12-23 10:39:17 +01:00
|
|
|
showSaveSuccessToast(this, this.hass);
|
2019-08-10 21:14:35 +02:00
|
|
|
this._close();
|
2019-03-26 23:31:43 +01:00
|
|
|
}
|
2018-11-02 16:00:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
declare global {
|
|
|
|
interface HTMLElementTagNameMap {
|
2018-11-29 15:00:30 +01:00
|
|
|
"hui-dialog-edit-card": HuiDialogEditCard;
|
2018-11-02 16:00:25 +01:00
|
|
|
}
|
|
|
|
}
|