From 64e21e185ca2ca6a22eebdf08ca25a6ea56d1c83 Mon Sep 17 00:00:00 2001
From: karwosts <32912880+karwosts@users.noreply.github.com>
Date: Tue, 29 Oct 2024 00:36:58 -0700
Subject: [PATCH] Add a geo_location selector to map editor (#22538)
* Add a geo_location selector to map editor
* delete unused
---
.../components/hui-input-list-editor.ts | 123 ------------------
.../config-elements/hui-map-card-editor.ts | 58 ++++++++-
src/translations/en.json | 1 +
3 files changed, 53 insertions(+), 129 deletions(-)
delete mode 100644 src/panels/lovelace/components/hui-input-list-editor.ts
diff --git a/src/panels/lovelace/components/hui-input-list-editor.ts b/src/panels/lovelace/components/hui-input-list-editor.ts
deleted file mode 100644
index 6616753fc81f..000000000000
--- a/src/panels/lovelace/components/hui-input-list-editor.ts
+++ /dev/null
@@ -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`
-
-
-
- `
- )}
-
- `;
- }
-
- 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;
- }
-}
diff --git a/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts b/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
index 7aafbb59006e..8b8186d0f8c3 100644
--- a/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
+++ b/src/panels/lovelace/editor/config-elements/hui-map-card-editor.ts
@@ -15,15 +15,17 @@ import {
import memoizeOne from "memoize-one";
import { fireEvent } from "../../../../common/dom/fire_event";
import { hasLocation } from "../../../../common/entity/has_location";
+import { computeDomain } from "../../../../common/entity/compute_domain";
import "../../../../components/ha-form/ha-form";
import { SchemaUnion } from "../../../../components/ha-form/types";
+import type { SelectSelector } from "../../../../data/selector";
import "../../../../components/ha-formfield";
import "../../../../components/ha-switch";
+import "../../../../components/ha-selector/ha-selector-select";
import { HomeAssistant, ValueChangedEvent } from "../../../../types";
import { DEFAULT_HOURS_TO_SHOW, DEFAULT_ZOOM } from "../../cards/hui-map-card";
import { MapCardConfig } from "../../cards/types";
import "../../components/hui-entity-editor";
-import "../../components/hui-input-list-editor";
import { EntityConfig } from "../../entity-rows/types";
import { LovelaceCardEditor } from "../../types";
import { processEditorEntities } from "../process-editor-entities";
@@ -67,6 +69,8 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
@state() private _configEntities?: EntityConfig[];
+ @state() private _possibleGeoSources?: { value: string; label?: string }[];
+
private _schema = memoizeOne(
(localize: LocalizeFunc) =>
[
@@ -166,17 +170,40 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
)}
-
+ .selector=${this._selectSchema(
+ this._possibleGeoSources,
+ this.hass.localize
+ )}
+ >
`;
}
+ 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 {
if (ev.detail && 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 });
}
+ protected willUpdate() {
+ if (this.hass && !this._possibleGeoSources) {
+ const sources: Record = {};
+ 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 = (
schema: SchemaUnion>
) => {
diff --git a/src/translations/en.json b/src/translations/en.json
index dd8d778954a5..03e0cc46a81c 100644
--- a/src/translations/en.json
+++ b/src/translations/en.json
@@ -6086,6 +6086,7 @@
"map": {
"name": "Map",
"geo_location_sources": "Geolocation sources",
+ "no_geo_location_sources": "No geolocation sources available",
"dark_mode": "Dark mode?",
"appearance": "Appearance",
"theme_mode": "Theme Mode",