Gauge Editor to Ha Form (#11793)

This commit is contained in:
Zack Barett 2022-02-23 08:35:58 -06:00 committed by GitHub
parent 0010bf5a8f
commit e6dbbc31a8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 134 additions and 254 deletions

View File

@ -50,7 +50,12 @@ export class HaEntitySelector extends SubscribeMixin(LitElement) {
private _filterEntities = (entity: HassEntity): boolean => {
if (this.selector.entity?.domain) {
if (computeStateDomain(entity) !== this.selector.entity.domain) {
const filterDomain = this.selector.entity.domain;
const entityDomain = computeStateDomain(entity);
if (
(Array.isArray(filterDomain) && !filterDomain.includes(entityDomain)) ||
entityDomain !== filterDomain
) {
return false;
}
}

View File

@ -76,6 +76,7 @@ export class HaTextSelector extends LitElement {
if (value === "" && !this.required) {
value = undefined;
}
fireEvent(this, "value-changed", { value });
}

View File

@ -20,7 +20,7 @@ export type Selector =
export interface EntitySelector {
entity: {
integration?: string;
domain?: string;
domain?: string | string[];
device_class?: string;
};
}

View File

@ -1,5 +1,5 @@
import "@polymer/paper-input/paper-input";
import { css, CSSResultGroup, html, LitElement, TemplateResult } from "lit";
import "../../../../components/ha-form/ha-form";
import { html, LitElement, TemplateResult } from "lit";
import { customElement, property, state } from "lit/decorators";
import {
assert,
@ -10,18 +10,13 @@ import {
optional,
string,
} from "superstruct";
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
import { computeRTLDirection } from "../../../../common/util/compute_rtl";
import "../../../../components/ha-formfield";
import "../../../../components/ha-switch";
import { HomeAssistant } from "../../../../types";
import { GaugeCardConfig, SeverityConfig } from "../../cards/types";
import "../../components/hui-entity-editor";
import "../../components/hui-theme-select-editor";
import { LovelaceCardEditor } from "../../types";
import type { HaFormSchema } from "../../../../components/ha-form/types";
import type { HomeAssistant } from "../../../../types";
import type { GaugeCardConfig } from "../../cards/types";
import type { LovelaceCardEditor } from "../../types";
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
import { EditorTarget, EntitiesEditorEvent } from "../types";
import { configElementStyle } from "./config-elements-style";
const cardConfigStruct = assign(
baseLovelaceCardConfig,
@ -37,8 +32,6 @@ const cardConfigStruct = assign(
})
);
const includeDomains = ["counter", "input_number", "number", "sensor"];
@customElement("hui-gauge-card-editor")
export class HuiGaugeCardEditor
extends LitElement
@ -53,264 +46,145 @@ export class HuiGaugeCardEditor
this._config = config;
}
get _name(): string {
return this._config!.name || "";
}
private _schema = memoizeOne((showSeverity: boolean) => {
const schema = [
{
name: "entity",
selector: {
entity: {
domain: ["counter", "input_number", "number", "sensor"],
},
},
},
{
name: "",
type: "grid",
schema: [
{ name: "name", selector: { text: {} } },
{ name: "unit", selector: { text: {} } },
],
},
{ name: "theme", selector: { theme: {} } },
{
name: "",
type: "grid",
schema: [
{ name: "min", selector: { number: { min: 1, mode: "box" } } },
{ name: "max", selector: { number: { min: 1, mode: "box" } } },
],
},
{
name: "",
type: "grid",
schema: [
{ name: "needle", selector: { boolean: {} } },
{ name: "show_severity", selector: { boolean: {} } },
],
},
];
get _entity(): string {
return this._config!.entity || "";
}
if (showSeverity) {
schema.push({
name: "",
type: "grid",
schema: [
{ name: "green", selector: { number: { min: 0, mode: "box" } } },
{ name: "yellow", selector: { number: { min: 0, mode: "box" } } },
{ name: "red", selector: { number: { min: 0, mode: "box" } } },
],
});
}
get _unit(): string {
return this._config!.unit || "";
}
get _theme(): string {
return this._config!.theme || "";
}
get _min(): number {
return this._config!.min || 0;
}
get _max(): number {
return this._config!.max || 100;
}
get _severity(): SeverityConfig | undefined {
return this._config!.severity || undefined;
}
return schema;
});
protected render(): TemplateResult {
if (!this.hass || !this._config) {
return html``;
}
const schema = this._schema(this._config!.severity !== undefined);
const data = {
show_severity: this._config!.severity !== undefined,
...this._config,
};
return html`
<div class="card-config">
<ha-entity-picker
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.entity"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.required"
)})"
.hass=${this.hass}
.value=${this._entity}
.configValue=${"entity"}
.includeDomains=${includeDomains}
@change=${this._valueChanged}
allow-custom-entity
></ha-entity-picker>
<paper-input
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.name"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._name}
.configValue=${"name"}
@value-changed=${this._valueChanged}
></paper-input>
<paper-input
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.unit"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._unit}
.configValue=${"unit"}
@value-changed=${this._valueChanged}
></paper-input>
<hui-theme-select-editor
.hass=${this.hass}
.value=${this._theme}
.configValue=${"theme"}
@value-changed=${this._valueChanged}
></hui-theme-select-editor>
<paper-input
type="number"
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.minimum"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._min}
.configValue=${"min"}
@value-changed=${this._valueChanged}
></paper-input>
<paper-input
type="number"
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.generic.maximum"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.optional"
)})"
.value=${this._max}
.configValue=${"max"}
@value-changed=${this._valueChanged}
></paper-input>
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.gauge.needle_gauge"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.checked=${this._config!.needle !== undefined}
@change=${this._toggleNeedle}
></ha-switch
></ha-formfield>
<ha-formfield
.label=${this.hass.localize(
"ui.panel.lovelace.editor.card.gauge.severity.define"
)}
.dir=${computeRTLDirection(this.hass)}
>
<ha-switch
.checked=${this._config!.severity !== undefined}
@change=${this._toggleSeverity}
></ha-switch
></ha-formfield>
${this._config!.severity !== undefined
? html`
<paper-input
type="number"
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.gauge.severity.green"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.required"
)})"
.value=${this._severity ? this._severity.green : 0}
.configValue=${"green"}
@value-changed=${this._severityChanged}
></paper-input>
<paper-input
type="number"
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.gauge.severity.yellow"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.required"
)})"
.value=${this._severity ? this._severity.yellow : 0}
.configValue=${"yellow"}
@value-changed=${this._severityChanged}
></paper-input>
<paper-input
type="number"
.label="${this.hass.localize(
"ui.panel.lovelace.editor.card.gauge.severity.red"
)} (${this.hass.localize(
"ui.panel.lovelace.editor.card.config.required"
)})"
.value=${this._severity ? this._severity.red : 0}
.configValue=${"red"}
@value-changed=${this._severityChanged}
></paper-input>
</div>
`
: ""}
</div>
<ha-form
.hass=${this.hass}
.data=${data}
.schema=${schema}
.computeLabel=${this._computeLabelCallback}
@value-changed=${this._valueChanged}
></ha-form>
`;
}
static get styles(): CSSResultGroup {
return [
configElementStyle,
css`
.severity {
display: none;
width: 100%;
padding-left: 16px;
flex-direction: row;
flex-wrap: wrap;
}
.severity > * {
flex: 1 0 30%;
padding-right: 4px;
}
ha-switch[checked] ~ .severity {
display: flex;
}
`,
];
}
private _valueChanged(ev: CustomEvent): void {
let config = ev.detail.value;
private _toggleNeedle(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
if ((ev.target as EditorTarget).checked) {
this._config = {
...this._config,
needle: true,
};
} else {
this._config = { ...this._config };
delete this._config.needle;
}
fireEvent(this, "config-changed", { config: this._config });
}
private _toggleSeverity(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
if ((ev.target as EditorTarget).checked) {
this._config = {
...this._config,
if (config.show_severity) {
config = {
...config,
severity: {
green: 0,
yellow: 0,
red: 0,
green: config.green || config.severity?.green || 0,
yellow: config.yellow || config.severity?.yellow || 0,
red: config.red || config.severity?.red || 0,
},
};
} else {
this._config = { ...this._config };
delete this._config.severity;
} else if (!config.show_severity && config.severity) {
delete config.severity;
}
fireEvent(this, "config-changed", { config: this._config });
delete config.show_severity;
delete config.green;
delete config.yellow;
delete config.red;
fireEvent(this, "config-changed", { config });
}
private _severityChanged(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
private _computeLabelCallback = (schema: HaFormSchema) => {
switch (schema.name) {
case "name":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.name"
);
case "entity":
return `${this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.entity"
)} (${this.hass!.localize(
"ui.panel.lovelace.editor.card.config.required"
)})`;
case "max":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.maximum"
);
case "min":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.generic.minimum"
);
case "show_severity":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.gauge.severity.define"
);
case "needle":
return this.hass!.localize(
"ui.panel.lovelace.editor.card.gauge.needle_gauge"
);
}
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) {
if (
target.value === "" ||
(target.type === "number" && isNaN(Number(target.value)))
) {
this._config = { ...this._config };
delete this._config[target.configValue!];
} else {
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 });
}
return (
this.hass!.localize(
`ui.panel.lovelace.editor.card.gauge.${schema.name}`
) ||
this.hass!.localize(
`ui.panel.lovelace.editor.card.generic.${schema.name}`
) ||
this.hass!.localize(
`ui.panel.lovelace.editor.card.gauge.severity.${schema.name}`
)
);
};
}
declare global {