mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-01 13:37:47 +00:00
Add badges to view editor (#2176)
* Badges * Fix entity picker * Make editor own element
This commit is contained in:
parent
e2e002b9a9
commit
16cc3adcff
128
src/panels/lovelace/editor/config-elements/hui-view-editor.ts
Normal file
128
src/panels/lovelace/editor/config-elements/hui-view-editor.ts
Normal file
@ -0,0 +1,128 @@
|
||||
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-style";
|
||||
|
||||
import "../../components/hui-theme-select-editor";
|
||||
import { LovelaceViewConfig } from "../../../../data/lovelace";
|
||||
|
||||
declare global {
|
||||
interface HASSDomEvents {
|
||||
"view-config-changed": {
|
||||
config: LovelaceViewConfig;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
export class HuiViewEditor extends hassLocalizeLitMixin(LitElement) {
|
||||
static get properties(): PropertyDeclarations {
|
||||
return { hass: {}, _config: {} };
|
||||
}
|
||||
|
||||
get _id(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.id || "";
|
||||
}
|
||||
|
||||
get _title(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.title || "";
|
||||
}
|
||||
|
||||
get _icon(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.icon || "";
|
||||
}
|
||||
|
||||
get _theme(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.theme || "Backend-selected";
|
||||
}
|
||||
|
||||
public hass?: HomeAssistant;
|
||||
private _config?: LovelaceViewConfig;
|
||||
|
||||
set config(config: LovelaceViewConfig) {
|
||||
this._config = config;
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
if (!this.hass) {
|
||||
return html``;
|
||||
}
|
||||
|
||||
return html`
|
||||
${configElementStyle}
|
||||
<div class="card-config">
|
||||
<paper-input
|
||||
label="ID"
|
||||
value="${this._id}"
|
||||
.configValue="${"id"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<paper-input
|
||||
label="Title"
|
||||
value="${this._title}"
|
||||
.configValue="${"title"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<paper-input
|
||||
label="Icon"
|
||||
value="${this._icon}"
|
||||
.configValue="${"icon"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<hui-theme-select-editor
|
||||
.hass="${this.hass}"
|
||||
.value="${this._theme}"
|
||||
.configValue="${"theme"}"
|
||||
@theme-changed="${this._valueChanged}"
|
||||
></hui-theme-select-editor>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private _valueChanged(ev: Event): void {
|
||||
if (!this._config || !this.hass) {
|
||||
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, "view-config-changed", { config: newConfig });
|
||||
}
|
||||
}
|
||||
|
||||
declare global {
|
||||
interface HTMLElementTagNameMap {
|
||||
"hui-view-editor": HuiViewEditor;
|
||||
}
|
||||
}
|
||||
|
||||
customElements.define("hui-view-editor", HuiViewEditor);
|
@ -7,13 +7,16 @@ import {
|
||||
import { TemplateResult } from "lit-html";
|
||||
|
||||
import "@polymer/paper-spinner/paper-spinner";
|
||||
import "@polymer/paper-tabs/paper-tab";
|
||||
import "@polymer/paper-tabs/paper-tabs";
|
||||
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 "../components/hui-theme-select-editor";
|
||||
import "../components/hui-entity-editor";
|
||||
import "./config-elements/hui-view-editor";
|
||||
import { HomeAssistant } from "../../../types";
|
||||
import {
|
||||
addView,
|
||||
@ -22,7 +25,9 @@ import {
|
||||
} from "../../../data/lovelace";
|
||||
import { fireEvent } from "../../../common/dom/fire_event";
|
||||
import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin";
|
||||
import { EditorTarget } from "./types";
|
||||
import { EntitiesEditorEvent, ViewEditEvent } from "./types";
|
||||
import { processEditorEntities } from "./process-editor-entities";
|
||||
import { EntityConfig } from "../entity-rows/types";
|
||||
|
||||
export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
static get properties(): PropertyDeclarations {
|
||||
@ -31,7 +36,9 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
viewConfig: {},
|
||||
add: {},
|
||||
_config: {},
|
||||
_badges: {},
|
||||
_saving: {},
|
||||
_curTab: {},
|
||||
};
|
||||
}
|
||||
|
||||
@ -40,11 +47,15 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
public reloadLovelace?: () => {};
|
||||
protected hass?: HomeAssistant;
|
||||
private _config?: LovelaceViewConfig;
|
||||
private _badges?: EntityConfig[];
|
||||
private _saving: boolean;
|
||||
private _curTabIndex: number;
|
||||
private _curTab?: string;
|
||||
|
||||
protected constructor() {
|
||||
super();
|
||||
this._saving = false;
|
||||
this._curTabIndex = 0;
|
||||
}
|
||||
|
||||
public async showDialog(): Promise<void> {
|
||||
@ -66,9 +77,12 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
this.viewConfig.id !==
|
||||
(changedProperties.get("viewConfig") as LovelaceViewConfig).id)
|
||||
) {
|
||||
this._config = this.viewConfig;
|
||||
const { cards, badges, ...viewConfig } = this.viewConfig;
|
||||
this._badges = processEditorEntities(badges);
|
||||
this._config = viewConfig;
|
||||
} else if (changedProperties.has("add")) {
|
||||
this._config = { cards: [] };
|
||||
this._config = {};
|
||||
this._badges = [];
|
||||
}
|
||||
this._resizeDialog();
|
||||
}
|
||||
@ -77,67 +91,47 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
return this.shadowRoot!.querySelector("paper-dialog")!;
|
||||
}
|
||||
|
||||
get _id(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.id || "";
|
||||
}
|
||||
|
||||
get _title(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.title || "";
|
||||
}
|
||||
|
||||
get _icon(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.icon || "";
|
||||
}
|
||||
|
||||
get _theme(): string {
|
||||
if (!this._config) {
|
||||
return "";
|
||||
}
|
||||
return this._config.theme || "Backend-selected";
|
||||
}
|
||||
|
||||
protected render(): TemplateResult {
|
||||
let content;
|
||||
switch (this._curTab) {
|
||||
case "tab-settings":
|
||||
content = html`
|
||||
<hui-view-editor
|
||||
.hass="${this.hass}"
|
||||
.config="${this._config}"
|
||||
@view-config-changed="${this._viewConfigChanged}"
|
||||
></hui-view-editor>
|
||||
`;
|
||||
break;
|
||||
case "tab-badges":
|
||||
content = html`
|
||||
<hui-entity-editor
|
||||
.hass="${this.hass}"
|
||||
.entities="${this._badges}"
|
||||
@entities-changed="${this._badgesChanged}"
|
||||
></hui-entity-editor>
|
||||
`;
|
||||
break;
|
||||
case "tab-cards":
|
||||
content = html`
|
||||
Cards
|
||||
`;
|
||||
break;
|
||||
}
|
||||
return html`
|
||||
${this.renderStyle()}
|
||||
<paper-dialog with-backdrop>
|
||||
<h2>${this.localize("ui.panel.lovelace.editor.edit_view.header")}</h2>
|
||||
<paper-dialog-scrollable>
|
||||
<div class="card-config">
|
||||
<paper-input
|
||||
label="ID"
|
||||
value="${this._id}"
|
||||
.configValue="${"id"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<paper-input
|
||||
label="Title"
|
||||
value="${this._title}"
|
||||
.configValue="${"title"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<paper-input
|
||||
label="Icon"
|
||||
value="${this._icon}"
|
||||
.configValue="${"icon"}"
|
||||
@value-changed="${this._valueChanged}"
|
||||
></paper-input>
|
||||
<hui-theme-select-editor
|
||||
.hass="${this.hass}"
|
||||
.value="${this._theme}"
|
||||
.configValue="${"theme"}"
|
||||
@theme-changed="${this._valueChanged}"
|
||||
></hui-theme-select-editor>
|
||||
</div>
|
||||
</paper-dialog-scrollable>
|
||||
<paper-tabs
|
||||
scrollable
|
||||
hide-scroll-buttons
|
||||
.selected="${this._curTabIndex}"
|
||||
@selected-item-changed="${this._handleTabSelected}"
|
||||
>
|
||||
<paper-tab id="tab-settings">Settings</paper-tab>
|
||||
<paper-tab id="tab-badges">Badges</paper-tab>
|
||||
</paper-tabs>
|
||||
<paper-dialog-scrollable> ${content} </paper-dialog-scrollable>
|
||||
<div class="paper-dialog-buttons">
|
||||
<paper-button @click="${this._closeDialog}"
|
||||
>${this.localize("ui.common.cancel")}</paper-button
|
||||
@ -163,6 +157,10 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
paper-dialog {
|
||||
width: 650px;
|
||||
}
|
||||
paper-tabs {
|
||||
--paper-tabs-selection-bar-color: var(--primary-color);
|
||||
text-transform: uppercase;
|
||||
}
|
||||
paper-button paper-spinner {
|
||||
width: 14px;
|
||||
height: 14px;
|
||||
@ -196,26 +194,45 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
}
|
||||
|
||||
private _closeDialog(): void {
|
||||
this._config = { cards: [] };
|
||||
this._curTabIndex = 0;
|
||||
this._config = {};
|
||||
this._badges = [];
|
||||
this.viewConfig = undefined;
|
||||
this._dialog.close();
|
||||
}
|
||||
|
||||
private _handleTabSelected(ev: CustomEvent): void {
|
||||
if (!ev.detail.value) {
|
||||
return;
|
||||
}
|
||||
this._curTab = ev.detail.value.id;
|
||||
this._resizeDialog();
|
||||
}
|
||||
|
||||
private async _updateConfigInBackend(): Promise<void> {
|
||||
if (!this._config) {
|
||||
return;
|
||||
}
|
||||
if (!this._isConfigChanged()) {
|
||||
this._closeDialog();
|
||||
this._saving = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this._badges) {
|
||||
this._config.badges = this._badges.map((entityConf) => {
|
||||
return entityConf.entity;
|
||||
});
|
||||
}
|
||||
|
||||
try {
|
||||
if (this.add) {
|
||||
await addView(this.hass!, this._config!, "json");
|
||||
await addView(this.hass!, this._config, "json");
|
||||
} else {
|
||||
await updateViewConfig(
|
||||
this.hass!,
|
||||
this.viewConfig!.id!,
|
||||
this._config!,
|
||||
this._config,
|
||||
"json"
|
||||
);
|
||||
}
|
||||
@ -228,23 +245,17 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||
}
|
||||
}
|
||||
|
||||
private _valueChanged(ev: Event): void {
|
||||
if (!this._config || !this.hass) {
|
||||
private _viewConfigChanged(ev: ViewEditEvent): void {
|
||||
if (ev.detail && ev.detail.config) {
|
||||
this._config = ev.detail.config;
|
||||
}
|
||||
}
|
||||
|
||||
private _badgesChanged(ev: EntitiesEditorEvent): void {
|
||||
if (!this._badges || !this.hass || !ev.detail || !ev.detail.entities) {
|
||||
return;
|
||||
}
|
||||
|
||||
const target = ev.currentTarget! as EditorTarget;
|
||||
|
||||
if (this[`_${target.configValue}`] === target.value) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (target.configValue) {
|
||||
this._config = {
|
||||
...this._config,
|
||||
[target.configValue]: target.value,
|
||||
};
|
||||
}
|
||||
this._badges = ev.detail.entities;
|
||||
}
|
||||
|
||||
private _isConfigChanged(): boolean {
|
||||
|
@ -1,4 +1,4 @@
|
||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
||||
import { LovelaceCardConfig, LovelaceViewConfig } from "../../../data/lovelace";
|
||||
import { EntityConfig } from "../entity-rows/types";
|
||||
|
||||
export interface YamlChangedEvent extends Event {
|
||||
@ -13,6 +13,12 @@ export interface CardPickedEvent extends Event {
|
||||
};
|
||||
}
|
||||
|
||||
export interface ViewEditEvent extends Event {
|
||||
detail: {
|
||||
config: LovelaceViewConfig;
|
||||
};
|
||||
}
|
||||
|
||||
export interface ConfigValue {
|
||||
format: "json" | "yaml";
|
||||
value?: string | LovelaceCardConfig;
|
||||
|
@ -327,9 +327,8 @@ class HUIRoot extends NavigateMixin(
|
||||
}
|
||||
|
||||
_editView() {
|
||||
const { cards, badges, ...viewConfig } = this.config.views[this._curView];
|
||||
showEditViewDialog(this, {
|
||||
viewConfig,
|
||||
viewConfig: this.config.views[this._curView],
|
||||
add: false,
|
||||
reloadLovelace: () => {
|
||||
this.fire("config-refresh");
|
||||
|
@ -22,6 +22,7 @@ class HUIView extends localizeMixin(EventsMixin(PolymerElement)) {
|
||||
padding: 4px 4px 0;
|
||||
transform: translateZ(0);
|
||||
position: relative;
|
||||
min-height: calc(100vh - 155px);
|
||||
}
|
||||
|
||||
#badges {
|
||||
|
Loading…
x
Reference in New Issue
Block a user