Geolocation source configurable in map editor (#2755)

* wip

* added input list editor

* input label configurable, variables renamed

* new input field working as expected now

* fix lint issues

* fix lint issues

* fix lint issues and code clean-up

* fix lint issues

* uses property decorator now

* change the way css is included

* moved heading from input list editor to map card editor

* moved styling of input list editor to map card editor

* stopped propagating event

* return new value in event instead of changing the input value

* added button to clear value; consolidate value when leaving input field

* fix lint issues

* fix lint issues

* using customElement decorator

* fix lint issues
This commit is contained in:
Malte Franken 2019-03-08 09:06:40 +11:00 committed by Paulus Schoutsen
parent f5d0162aec
commit ed9dff99d3
2 changed files with 164 additions and 10 deletions

View File

@ -0,0 +1,115 @@
import {
html,
css,
LitElement,
property,
TemplateResult,
CSSResult,
customElement,
} from "lit-element";
import "@polymer/paper-input/paper-input";
import { HomeAssistant } from "../../../types";
import { fireEvent } from "../../../common/dom/fire_event";
import { EditorTarget } from "../editor/types";
@customElement("hui-input-list-editor")
export class HuiInputListEditor extends LitElement {
@property() protected value?: string[];
@property() protected hass?: HomeAssistant;
@property() protected inputLabel?: string;
protected render(): TemplateResult | void {
if (!this.value) {
return html``;
}
return html`
${this.value.map((listEntry, index) => {
return html`
<paper-input
label="${this.inputLabel}"
.value="${listEntry}"
.configValue="${"entry"}"
.index="${index}"
@value-changed="${this._valueChanged}"
@blur="${this._consolidateEntries}"
><paper-icon-button
slot="suffix"
class="clear-button"
icon="hass:close"
no-ripple
@click="${this._removeEntry}"
>Clear</paper-icon-button
></paper-input
>
`;
})}
<paper-input
label="${this.inputLabel}"
@change="${this._addEntry}"
></paper-input>
`;
}
private _addEntry(ev: Event): void {
const target = ev.target! as EditorTarget;
if (target.value === "") {
return;
}
const newEntries = this.value!.concat(target.value as string);
target.value = "";
fireEvent(this, "value-changed", {
value: newEntries,
});
(ev.target! as LitElement).blur();
}
private _valueChanged(ev: Event): void {
ev.stopPropagation();
const target = ev.target! as EditorTarget;
const newEntries = this.value!.concat();
newEntries[target.index!] = target.value!;
fireEvent(this, "value-changed", {
value: newEntries,
});
}
private _consolidateEntries(ev: Event): void {
const target = ev.target! as EditorTarget;
if (target.value === "") {
const newEntries = this.value!.concat();
newEntries.splice(target.index!, 1);
fireEvent(this, "value-changed", {
value: newEntries,
});
}
}
private _removeEntry(ev: Event): void {
const parent = (ev.currentTarget as any).parentElement;
const newEntries = this.value!.concat();
newEntries.splice(parent.index!, 1);
fireEvent(this, "value-changed", {
value: newEntries,
});
}
static get styles(): CSSResult {
return css`
paper-input > paper-icon-button {
width: 24px;
height: 24px;
padding: 2px;
color: var(--secondary-text-color);
}
`;
}
}
declare global {
interface HTMLElementTagNameMap {
"hui-input-list-editor": HuiInputListEditor;
}
}

View File

@ -1,9 +1,11 @@
import {
html,
css,
LitElement,
TemplateResult,
customElement,
property,
CSSResult,
} from "lit-element";
import "@polymer/paper-input/paper-input";
@ -16,8 +18,10 @@ import { MapCardConfig } from "../../cards/hui-map-card";
import { configElementStyle } from "./config-elements-style";
import { processEditorEntities } from "../process-editor-entities";
import { EntityConfig } from "../../entity-rows/types";
import { PolymerChangedEvent } from "../../../../polymer-types";
import "../../components/hui-entity-editor";
import "../../components/hui-input-list-editor";
const entitiesConfigStruct = struct.union([
{
@ -34,6 +38,7 @@ const cardConfigStruct = struct({
aspect_ratio: "string?",
default_zoom: "number?",
entities: [entitiesConfigStruct],
geo_location_sources: "array?",
});
@customElement("hui-map-card-editor")
@ -62,6 +67,10 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
return this._config!.default_zoom || NaN;
}
get _geo_location_sources(): string[] {
return this._config!.geo_location_sources || [];
}
protected render(): TemplateResult | void {
if (!this.hass) {
return html``;
@ -94,31 +103,53 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
<hui-entity-editor
.hass="${this.hass}"
.entities="${this._configEntities}"
@entities-changed="${this._valueChanged}"
@entities-changed="${this._entitiesValueChanged}"
></hui-entity-editor>
<h3>Geolocation Sources</h3>
<div class="geo_location_sources">
<hui-input-list-editor
inputLabel="Source"
.hass="${this.hass}"
.value="${this._geo_location_sources}"
.configValue="${"geo_location_sources"}"
@value-changed="${this._valueChanged}"
></hui-input-list-editor>
</div>
</div>
`;
}
private _valueChanged(ev: EntitiesEditorEvent): void {
private _entitiesValueChanged(ev: EntitiesEditorEvent): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
if (target.configValue && this[`_${target.configValue}`] === target.value) {
return;
}
if (ev.detail && ev.detail.entities) {
this._config.entities = ev.detail.entities;
this._configEntities = processEditorEntities(this._config.entities);
} else if (target.configValue) {
fireEvent(this, "config-changed", { config: this._config });
}
}
private _valueChanged(ev: PolymerChangedEvent<any>): void {
if (!this._config || !this.hass) {
return;
}
const target = ev.target! as EditorTarget;
if (
target.configValue &&
ev.detail &&
this[`_${target.configValue}`] === ev.detail.value
) {
return;
}
if (target.configValue && ev.detail) {
if (
target.value === "" ||
(target.type === "number" && isNaN(Number(target.value)))
ev.detail.value === "" ||
(target.type === "number" && isNaN(Number(ev.detail.value)))
) {
delete this._config[target.configValue!];
} else {
let value: any = target.value;
let value: any = ev.detail.value;
if (target.type === "number") {
value = Number(value);
}
@ -130,6 +161,14 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
}
fireEvent(this, "config-changed", { config: this._config });
}
static get styles(): CSSResult {
return css`
.geo_location_sources {
padding-left: 20px;
}
`;
}
}
declare global {