UI Editor for gauge card (#2229)

* UI editor for `gauge` card

Need to develop a severity input method still

* Config works well but no preview showing

* Add `sensor` domain filter

* Remove `id`
This commit is contained in:
Ian Richardson 2018-12-11 14:22:08 -06:00 committed by Paulus Schoutsen
parent 65cf2feb7a
commit db4c1e45f5
2 changed files with 260 additions and 4 deletions

View File

@ -6,7 +6,7 @@ import {
} from "@polymer/lit-element";
import { TemplateResult } from "lit-html";
import { LovelaceCard } from "../types";
import { LovelaceCard, LovelaceCardEditor } from "../types";
import { LovelaceCardConfig } from "../../../data/lovelace";
import { HomeAssistant } from "../../../types";
import { fireEvent } from "../../../common/dom/fire_event";
@ -18,17 +18,23 @@ import computeStateName from "../../../common/entity/compute_state_name";
import "../../../components/ha-card";
interface Config extends LovelaceCardConfig {
export interface SeverityConfig {
green?: number;
yellow?: number;
red?: number;
}
export interface Config extends LovelaceCardConfig {
entity: string;
name?: string;
unit?: string;
min?: number;
max?: number;
severity?: object;
severity?: SeverityConfig;
theme?: string;
}
const severityMap = {
export const severityMap = {
red: "var(--label-badge-red)",
green: "var(--label-badge-green)",
yellow: "var(--label-badge-yellow)",
@ -36,6 +42,14 @@ const severityMap = {
};
class HuiGaugeCard extends LitElement implements LovelaceCard {
public static async getConfigElement(): Promise<LovelaceCardEditor> {
await import("../editor/config-elements/hui-gauge-card-editor");
return document.createElement("hui-gauge-card-editor");
}
public static getStubConfig(): object {
return {};
}
public hass?: HomeAssistant;
private _config?: Config;

View File

@ -0,0 +1,242 @@
import { html, LitElement, PropertyDeclarations } from "@polymer/lit-element";
import { TemplateResult } from "lit-html";
import { struct } from "../../common/structs/struct";
import "@polymer/paper-input/paper-input";
import "@polymer/paper-toggle-button/paper-toggle-button";
import { EntitiesEditorEvent, EditorTarget } from "../types";
import { hassLocalizeLitMixin } from "../../../../mixins/lit-localize-mixin";
import { HomeAssistant } from "../../../../types";
import { LovelaceCardEditor } from "../../types";
import { fireEvent } from "../../../../common/dom/fire_event";
import { Config, SeverityConfig } from "../../cards/hui-gauge-card";
import { configElementStyle } from "./config-elements-style";
import "../../components/hui-theme-select-editor";
import "../../components/hui-entity-editor";
const cardConfigStruct = struct({
type: "string",
title: "string?",
entity: "string?",
unit: "string?",
min: "number?",
max: "number?",
severity: "object?",
theme: "string?",
});
export class HuiGaugeCardEditor extends hassLocalizeLitMixin(LitElement)
implements LovelaceCardEditor {
public hass?: HomeAssistant;
private _config?: Config;
private _useSeverity?: boolean;
public setConfig(config: Config): void {
config = cardConfigStruct(config);
this._useSeverity = config.severity ? true : false;
this._config = {
type: "gauge",
...config,
};
}
static get properties(): PropertyDeclarations {
return { hass: {}, _config: {} };
}
get _title(): string {
return this._config!.title || "";
}
get _entity(): string {
return this._config!.entity || "";
}
get _unit(): string {
return this._config!.unit || "";
}
get _theme(): string {
return this._config!.theme || "default";
}
get _min(): number {
return this._config!.number || 0;
}
get _max(): number {
return this._config!.max || 100;
}
get _severity(): SeverityConfig | undefined {
return this._config!.severity || undefined;
}
protected render(): TemplateResult {
if (!this.hass) {
return html``;
}
return html`
${configElementStyle} ${this.renderStyle()}
<div class="card-config">
<div class="side-by-side">
<paper-input
label="Title"
value="${this._title}"
.configValue=${"title"}
@value-changed="${this._valueChanged}"
></paper-input>
<ha-entity-picker
.hass="${this.hass}"
.value="${this._entity}"
.configValue=${"entity"}
.domainFilter=${"sensor"}
@change="${this._valueChanged}"
allow-custom-entity
></ha-entity-picker>
</div>
<div class="side-by-side">
<paper-input
label="Unit"
value="${this._unit}"
.configValue=${"unit"}
@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>
<div class="side-by-side">
<paper-input
type="number"
label="Minimum"
value="${this._min}"
.configValue=${"min"}
@value-changed="${this._valueChanged}"
></paper-input>
<paper-input
type="number"
label="Maximum"
value="${this._max}"
.configValue=${"max"}
@value-changed="${this._valueChanged}"
></paper-input>
</div>
<div class="side-by-side">
<paper-toggle-button
?checked="${this._useSeverity !== false}"
@change="${this._toggleSeverity}"
>Define Severity?</paper-toggle-button
>
<div class="severity">
<paper-input
type="number"
label="Green"
value="${this._severity ? this._severity.green : 0}"
.configValue=${"green"}
@value-changed="${this._severityChanged}"
></paper-input>
<paper-input
type="number"
label="Yellow"
value="${this._severity ? this._severity.yellow : 0}"
.configValue=${"yellow"}
@value-changed="${this._severityChanged}"
></paper-input>
<paper-input
type="number"
label="Red"
value="${this._severity ? this._severity.red : 0}"
.configValue=${"red"}
@value-changed="${this._severityChanged}"
></paper-input>
</div>
</div>
</div>
`;
}
private renderStyle(): TemplateResult {
return html`
<style>
.severity {
display: none;
width: 100%;
padding-left: 16px;
flex-direction: row;
flex-wrap: wrap;
}
.severity > * {
flex: 1 0 30%;
padding-right: 4px;
}
paper-toggle-button[checked] ~ .severity {
display: flex;
}
</style>
`;
}
private _toggleSeverity(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
this._config.severity = target.checked
? {
green: 0,
yellow: 0,
red: 0,
}
: undefined;
fireEvent(this, "config-changed", { config: this._config });
}
private _severityChanged(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
const severity = {
...this._config.severity,
[target.configValue!]: Number(target.value),
};
this._config = {
...this._config,
severity,
};
fireEvent(this, "config-changed", { config: this._config });
}
private _valueChanged(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
if (target.configValue) {
let value: any = target.value;
if (target.type === "number") {
value = Number(value);
}
this._config = { ...this._config, [target.configValue!]: value };
}
fireEvent(this, "config-changed", { config: this._config });
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-gauge-card-editor": HuiGaugeCardEditor;
}
}
customElements.define("hui-gauge-card-editor", HuiGaugeCardEditor);