mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-25 18:26:35 +00:00
Add a geo_location selector to map editor (#22538)
* Add a geo_location selector to map editor * delete unused
This commit is contained in:
parent
7a1838ee1a
commit
64e21e185c
@ -1,123 +0,0 @@
|
|||||||
import { mdiClose } from "@mdi/js";
|
|
||||||
import { css, CSSResultGroup, html, LitElement, nothing } from "lit";
|
|
||||||
import { customElement, property } from "lit/decorators";
|
|
||||||
import { fireEvent } from "../../../common/dom/fire_event";
|
|
||||||
import "../../../components/ha-icon-button";
|
|
||||||
import "../../../components/ha-textfield";
|
|
||||||
import { HomeAssistant } from "../../../types";
|
|
||||||
import { EditorTarget } from "../editor/types";
|
|
||||||
|
|
||||||
@customElement("hui-input-list-editor")
|
|
||||||
export class HuiInputListEditor extends LitElement {
|
|
||||||
@property({ type: Array }) public value?: string[];
|
|
||||||
|
|
||||||
@property({ attribute: false }) public hass?: HomeAssistant;
|
|
||||||
|
|
||||||
@property() public inputLabel?: string;
|
|
||||||
|
|
||||||
protected render() {
|
|
||||||
if (!this.value) {
|
|
||||||
return nothing;
|
|
||||||
}
|
|
||||||
|
|
||||||
return html`
|
|
||||||
${this.value.map(
|
|
||||||
(listEntry, index) => html`
|
|
||||||
<ha-textfield
|
|
||||||
.label=${this.inputLabel}
|
|
||||||
.value=${listEntry}
|
|
||||||
.configValue=${"entry"}
|
|
||||||
.index=${index}
|
|
||||||
@input=${this._valueChanged}
|
|
||||||
@blur=${this._consolidateEntries}
|
|
||||||
@keydown=${this._handleKeyDown}
|
|
||||||
iconTrailing
|
|
||||||
><ha-icon-button
|
|
||||||
slot="trailingIcon"
|
|
||||||
class="clear-button"
|
|
||||||
.path=${mdiClose}
|
|
||||||
no-ripple
|
|
||||||
@click=${this._removeEntry}
|
|
||||||
.label=${this.hass!.localize("ui.common.clear")}
|
|
||||||
>
|
|
||||||
</ha-icon-button>
|
|
||||||
</ha-textfield>
|
|
||||||
`
|
|
||||||
)}
|
|
||||||
<ha-textfield
|
|
||||||
.label=${this.inputLabel}
|
|
||||||
@change=${this._addEntry}
|
|
||||||
></ha-textfield>
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
|
|
||||||
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 _handleKeyDown(ev: KeyboardEvent) {
|
|
||||||
if (ev.key === "Enter") {
|
|
||||||
ev.stopPropagation();
|
|
||||||
this._consolidateEntries(ev);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
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(): CSSResultGroup {
|
|
||||||
return css`
|
|
||||||
ha-icon-button {
|
|
||||||
margin-right: -24px;
|
|
||||||
margin-inline-end: -24px;
|
|
||||||
margin-inline-start: initial;
|
|
||||||
color: var(--secondary-text-color);
|
|
||||||
}
|
|
||||||
ha-textfield {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
declare global {
|
|
||||||
interface HTMLElementTagNameMap {
|
|
||||||
"hui-input-list-editor": HuiInputListEditor;
|
|
||||||
}
|
|
||||||
}
|
|
@ -15,15 +15,17 @@ import {
|
|||||||
import memoizeOne from "memoize-one";
|
import memoizeOne from "memoize-one";
|
||||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||||
import { hasLocation } from "../../../../common/entity/has_location";
|
import { hasLocation } from "../../../../common/entity/has_location";
|
||||||
|
import { computeDomain } from "../../../../common/entity/compute_domain";
|
||||||
import "../../../../components/ha-form/ha-form";
|
import "../../../../components/ha-form/ha-form";
|
||||||
import { SchemaUnion } from "../../../../components/ha-form/types";
|
import { SchemaUnion } from "../../../../components/ha-form/types";
|
||||||
|
import type { SelectSelector } from "../../../../data/selector";
|
||||||
import "../../../../components/ha-formfield";
|
import "../../../../components/ha-formfield";
|
||||||
import "../../../../components/ha-switch";
|
import "../../../../components/ha-switch";
|
||||||
|
import "../../../../components/ha-selector/ha-selector-select";
|
||||||
import { HomeAssistant, ValueChangedEvent } from "../../../../types";
|
import { HomeAssistant, ValueChangedEvent } from "../../../../types";
|
||||||
import { DEFAULT_HOURS_TO_SHOW, DEFAULT_ZOOM } from "../../cards/hui-map-card";
|
import { DEFAULT_HOURS_TO_SHOW, DEFAULT_ZOOM } from "../../cards/hui-map-card";
|
||||||
import { MapCardConfig } from "../../cards/types";
|
import { MapCardConfig } from "../../cards/types";
|
||||||
import "../../components/hui-entity-editor";
|
import "../../components/hui-entity-editor";
|
||||||
import "../../components/hui-input-list-editor";
|
|
||||||
import { EntityConfig } from "../../entity-rows/types";
|
import { EntityConfig } from "../../entity-rows/types";
|
||||||
import { LovelaceCardEditor } from "../../types";
|
import { LovelaceCardEditor } from "../../types";
|
||||||
import { processEditorEntities } from "../process-editor-entities";
|
import { processEditorEntities } from "../process-editor-entities";
|
||||||
@ -67,6 +69,8 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
|||||||
|
|
||||||
@state() private _configEntities?: EntityConfig[];
|
@state() private _configEntities?: EntityConfig[];
|
||||||
|
|
||||||
|
@state() private _possibleGeoSources?: { value: string; label?: string }[];
|
||||||
|
|
||||||
private _schema = memoizeOne(
|
private _schema = memoizeOne(
|
||||||
(localize: LocalizeFunc) =>
|
(localize: LocalizeFunc) =>
|
||||||
[
|
[
|
||||||
@ -166,17 +170,40 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
|||||||
)}
|
)}
|
||||||
</h3>
|
</h3>
|
||||||
|
|
||||||
<hui-input-list-editor
|
<ha-selector-select
|
||||||
.inputLabel=${this.hass.localize(
|
.label=${this.hass.localize("ui.panel.lovelace.editor.card.map.source")}
|
||||||
"ui.panel.lovelace.editor.card.map.source"
|
.required=${false}
|
||||||
)}
|
|
||||||
.hass=${this.hass}
|
.hass=${this.hass}
|
||||||
.value=${this._geo_location_sources}
|
.value=${this._geo_location_sources}
|
||||||
@value-changed=${this._geoSourcesChanged}
|
@value-changed=${this._geoSourcesChanged}
|
||||||
></hui-input-list-editor>
|
.selector=${this._selectSchema(
|
||||||
|
this._possibleGeoSources,
|
||||||
|
this.hass.localize
|
||||||
|
)}
|
||||||
|
></ha-selector-select>
|
||||||
`;
|
`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _selectSchema = memoizeOne(
|
||||||
|
(options, localize: LocalizeFunc): SelectSelector => ({
|
||||||
|
select: {
|
||||||
|
sort: true,
|
||||||
|
multiple: true,
|
||||||
|
custom_value: true,
|
||||||
|
options: options.length
|
||||||
|
? options
|
||||||
|
: [
|
||||||
|
{
|
||||||
|
value: "",
|
||||||
|
label: localize(
|
||||||
|
"ui.panel.lovelace.editor.card.map.no_geo_location_sources"
|
||||||
|
),
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
private _entitiesValueChanged(ev: EntitiesEditorEvent): void {
|
private _entitiesValueChanged(ev: EntitiesEditorEvent): void {
|
||||||
if (ev.detail && ev.detail.entities) {
|
if (ev.detail && ev.detail.entities) {
|
||||||
this._config = { ...this._config!, entities: ev.detail.entities };
|
this._config = { ...this._config!, entities: ev.detail.entities };
|
||||||
@ -213,6 +240,25 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
|
|||||||
fireEvent(this, "config-changed", { config: ev.detail.value });
|
fireEvent(this, "config-changed", { config: ev.detail.value });
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected willUpdate() {
|
||||||
|
if (this.hass && !this._possibleGeoSources) {
|
||||||
|
const sources: Record<string, string> = {};
|
||||||
|
Object.entries(this.hass.states).forEach(([entity_id, stateObj]) => {
|
||||||
|
const domain = computeDomain(entity_id);
|
||||||
|
if (domain === "geo_location" && stateObj.attributes.source) {
|
||||||
|
sources[stateObj.attributes.source] = stateObj.attributes.attribution;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
this._possibleGeoSources = Object.entries(sources).map(
|
||||||
|
([source, attribution]) => ({
|
||||||
|
value: source,
|
||||||
|
label: attribution || source,
|
||||||
|
})
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private _computeLabelCallback = (
|
private _computeLabelCallback = (
|
||||||
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
schema: SchemaUnion<ReturnType<typeof this._schema>>
|
||||||
) => {
|
) => {
|
||||||
|
@ -6086,6 +6086,7 @@
|
|||||||
"map": {
|
"map": {
|
||||||
"name": "Map",
|
"name": "Map",
|
||||||
"geo_location_sources": "Geolocation sources",
|
"geo_location_sources": "Geolocation sources",
|
||||||
|
"no_geo_location_sources": "No geolocation sources available",
|
||||||
"dark_mode": "Dark mode?",
|
"dark_mode": "Dark mode?",
|
||||||
"appearance": "Appearance",
|
"appearance": "Appearance",
|
||||||
"theme_mode": "Theme Mode",
|
"theme_mode": "Theme Mode",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user