mirror of
https://github.com/home-assistant/frontend.git
synced 2025-08-03 14: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 { TemplateResult } from "lit-html";
|
||||||
|
|
||||||
import "@polymer/paper-spinner/paper-spinner";
|
import "@polymer/paper-spinner/paper-spinner";
|
||||||
|
import "@polymer/paper-tabs/paper-tab";
|
||||||
|
import "@polymer/paper-tabs/paper-tabs";
|
||||||
import "@polymer/paper-dialog/paper-dialog";
|
import "@polymer/paper-dialog/paper-dialog";
|
||||||
// This is not a duplicate import, one is for types, one is for element.
|
// This is not a duplicate import, one is for types, one is for element.
|
||||||
// tslint:disable-next-line
|
// tslint:disable-next-line
|
||||||
import { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog";
|
import { PaperDialogElement } from "@polymer/paper-dialog/paper-dialog";
|
||||||
import "@polymer/paper-button/paper-button";
|
import "@polymer/paper-button/paper-button";
|
||||||
import "@polymer/paper-dialog-scrollable/paper-dialog-scrollable";
|
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 { HomeAssistant } from "../../../types";
|
||||||
import {
|
import {
|
||||||
addView,
|
addView,
|
||||||
@ -22,7 +25,9 @@ import {
|
|||||||
} from "../../../data/lovelace";
|
} from "../../../data/lovelace";
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
import { fireEvent } from "../../../common/dom/fire_event";
|
||||||
import { hassLocalizeLitMixin } from "../../../mixins/lit-localize-mixin";
|
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) {
|
export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
||||||
static get properties(): PropertyDeclarations {
|
static get properties(): PropertyDeclarations {
|
||||||
@ -31,7 +36,9 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
viewConfig: {},
|
viewConfig: {},
|
||||||
add: {},
|
add: {},
|
||||||
_config: {},
|
_config: {},
|
||||||
|
_badges: {},
|
||||||
_saving: {},
|
_saving: {},
|
||||||
|
_curTab: {},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -40,11 +47,15 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
public reloadLovelace?: () => {};
|
public reloadLovelace?: () => {};
|
||||||
protected hass?: HomeAssistant;
|
protected hass?: HomeAssistant;
|
||||||
private _config?: LovelaceViewConfig;
|
private _config?: LovelaceViewConfig;
|
||||||
|
private _badges?: EntityConfig[];
|
||||||
private _saving: boolean;
|
private _saving: boolean;
|
||||||
|
private _curTabIndex: number;
|
||||||
|
private _curTab?: string;
|
||||||
|
|
||||||
protected constructor() {
|
protected constructor() {
|
||||||
super();
|
super();
|
||||||
this._saving = false;
|
this._saving = false;
|
||||||
|
this._curTabIndex = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public async showDialog(): Promise<void> {
|
public async showDialog(): Promise<void> {
|
||||||
@ -66,9 +77,12 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
this.viewConfig.id !==
|
this.viewConfig.id !==
|
||||||
(changedProperties.get("viewConfig") as LovelaceViewConfig).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")) {
|
} else if (changedProperties.has("add")) {
|
||||||
this._config = { cards: [] };
|
this._config = {};
|
||||||
|
this._badges = [];
|
||||||
}
|
}
|
||||||
this._resizeDialog();
|
this._resizeDialog();
|
||||||
}
|
}
|
||||||
@ -77,67 +91,47 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
return this.shadowRoot!.querySelector("paper-dialog")!;
|
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 {
|
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`
|
return html`
|
||||||
${this.renderStyle()}
|
${this.renderStyle()}
|
||||||
<paper-dialog with-backdrop>
|
<paper-dialog with-backdrop>
|
||||||
<h2>${this.localize("ui.panel.lovelace.editor.edit_view.header")}</h2>
|
<h2>${this.localize("ui.panel.lovelace.editor.edit_view.header")}</h2>
|
||||||
<paper-dialog-scrollable>
|
<paper-tabs
|
||||||
<div class="card-config">
|
scrollable
|
||||||
<paper-input
|
hide-scroll-buttons
|
||||||
label="ID"
|
.selected="${this._curTabIndex}"
|
||||||
value="${this._id}"
|
@selected-item-changed="${this._handleTabSelected}"
|
||||||
.configValue="${"id"}"
|
>
|
||||||
@value-changed="${this._valueChanged}"
|
<paper-tab id="tab-settings">Settings</paper-tab>
|
||||||
></paper-input>
|
<paper-tab id="tab-badges">Badges</paper-tab>
|
||||||
<paper-input
|
</paper-tabs>
|
||||||
label="Title"
|
<paper-dialog-scrollable> ${content} </paper-dialog-scrollable>
|
||||||
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>
|
|
||||||
<div class="paper-dialog-buttons">
|
<div class="paper-dialog-buttons">
|
||||||
<paper-button @click="${this._closeDialog}"
|
<paper-button @click="${this._closeDialog}"
|
||||||
>${this.localize("ui.common.cancel")}</paper-button
|
>${this.localize("ui.common.cancel")}</paper-button
|
||||||
@ -163,6 +157,10 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
paper-dialog {
|
paper-dialog {
|
||||||
width: 650px;
|
width: 650px;
|
||||||
}
|
}
|
||||||
|
paper-tabs {
|
||||||
|
--paper-tabs-selection-bar-color: var(--primary-color);
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
paper-button paper-spinner {
|
paper-button paper-spinner {
|
||||||
width: 14px;
|
width: 14px;
|
||||||
height: 14px;
|
height: 14px;
|
||||||
@ -196,26 +194,45 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private _closeDialog(): void {
|
private _closeDialog(): void {
|
||||||
this._config = { cards: [] };
|
this._curTabIndex = 0;
|
||||||
|
this._config = {};
|
||||||
|
this._badges = [];
|
||||||
this.viewConfig = undefined;
|
this.viewConfig = undefined;
|
||||||
this._dialog.close();
|
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> {
|
private async _updateConfigInBackend(): Promise<void> {
|
||||||
|
if (!this._config) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
if (!this._isConfigChanged()) {
|
if (!this._isConfigChanged()) {
|
||||||
this._closeDialog();
|
this._closeDialog();
|
||||||
this._saving = false;
|
this._saving = false;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this._badges) {
|
||||||
|
this._config.badges = this._badges.map((entityConf) => {
|
||||||
|
return entityConf.entity;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (this.add) {
|
if (this.add) {
|
||||||
await addView(this.hass!, this._config!, "json");
|
await addView(this.hass!, this._config, "json");
|
||||||
} else {
|
} else {
|
||||||
await updateViewConfig(
|
await updateViewConfig(
|
||||||
this.hass!,
|
this.hass!,
|
||||||
this.viewConfig!.id!,
|
this.viewConfig!.id!,
|
||||||
this._config!,
|
this._config,
|
||||||
"json"
|
"json"
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -228,23 +245,17 @@ export class HuiEditView extends hassLocalizeLitMixin(LitElement) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private _valueChanged(ev: Event): void {
|
private _viewConfigChanged(ev: ViewEditEvent): void {
|
||||||
if (!this._config || !this.hass) {
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
this._badges = ev.detail.entities;
|
||||||
const target = ev.currentTarget! as EditorTarget;
|
|
||||||
|
|
||||||
if (this[`_${target.configValue}`] === target.value) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (target.configValue) {
|
|
||||||
this._config = {
|
|
||||||
...this._config,
|
|
||||||
[target.configValue]: target.value,
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _isConfigChanged(): boolean {
|
private _isConfigChanged(): boolean {
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
import { LovelaceCardConfig } from "../../../data/lovelace";
|
import { LovelaceCardConfig, LovelaceViewConfig } from "../../../data/lovelace";
|
||||||
import { EntityConfig } from "../entity-rows/types";
|
import { EntityConfig } from "../entity-rows/types";
|
||||||
|
|
||||||
export interface YamlChangedEvent extends Event {
|
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 {
|
export interface ConfigValue {
|
||||||
format: "json" | "yaml";
|
format: "json" | "yaml";
|
||||||
value?: string | LovelaceCardConfig;
|
value?: string | LovelaceCardConfig;
|
||||||
|
@ -327,9 +327,8 @@ class HUIRoot extends NavigateMixin(
|
|||||||
}
|
}
|
||||||
|
|
||||||
_editView() {
|
_editView() {
|
||||||
const { cards, badges, ...viewConfig } = this.config.views[this._curView];
|
|
||||||
showEditViewDialog(this, {
|
showEditViewDialog(this, {
|
||||||
viewConfig,
|
viewConfig: this.config.views[this._curView],
|
||||||
add: false,
|
add: false,
|
||||||
reloadLovelace: () => {
|
reloadLovelace: () => {
|
||||||
this.fire("config-refresh");
|
this.fire("config-refresh");
|
||||||
|
@ -22,6 +22,7 @@ class HUIView extends localizeMixin(EventsMixin(PolymerElement)) {
|
|||||||
padding: 4px 4px 0;
|
padding: 4px 4px 0;
|
||||||
transform: translateZ(0);
|
transform: translateZ(0);
|
||||||
position: relative;
|
position: relative;
|
||||||
|
min-height: calc(100vh - 155px);
|
||||||
}
|
}
|
||||||
|
|
||||||
#badges {
|
#badges {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user