mirror of
https://github.com/home-assistant/frontend.git
synced 2025-07-24 09:46:36 +00:00
Add new config options for map entity markers (#17938)
This commit is contained in:
parent
6b33b4e656
commit
579050bfc7
@ -15,7 +15,7 @@ class HaEntityMarker extends LitElement {
|
||||
protected render() {
|
||||
return html`
|
||||
<div
|
||||
class="marker"
|
||||
class="marker ${this.entityPicture ? "picture" : ""}"
|
||||
style=${styleMap({ "border-color": this.entityColor })}
|
||||
@click=${this._badgeTap}
|
||||
>
|
||||
@ -45,7 +45,6 @@ class HaEntityMarker extends LitElement {
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
box-sizing: border-box;
|
||||
overflow: hidden;
|
||||
width: 48px;
|
||||
height: 48px;
|
||||
font-size: var(--ha-marker-font-size, 1.5em);
|
||||
@ -54,6 +53,9 @@ class HaEntityMarker extends LitElement {
|
||||
color: var(--primary-text-color);
|
||||
background-color: var(--card-background-color);
|
||||
}
|
||||
.marker.picture {
|
||||
overflow: hidden;
|
||||
}
|
||||
.entity-picture {
|
||||
background-size: cover;
|
||||
height: 100%;
|
||||
|
@ -37,6 +37,9 @@ export interface HaMapPaths {
|
||||
export interface HaMapEntity {
|
||||
entity_id: string;
|
||||
color: string;
|
||||
label_mode?: "name" | "state";
|
||||
name?: string;
|
||||
focus?: boolean;
|
||||
}
|
||||
|
||||
@customElement("ha-map")
|
||||
@ -71,6 +74,8 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
private _mapItems: Array<Marker | Circle> = [];
|
||||
|
||||
private _mapFocusItems: Array<Marker | Circle> = [];
|
||||
|
||||
private _mapZones: Array<Marker | Circle> = [];
|
||||
|
||||
private _mapPaths: Array<Polyline | CircleMarker> = [];
|
||||
@ -168,7 +173,7 @@ export class HaMap extends ReactiveElement {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!this._mapItems.length && !this.layers?.length) {
|
||||
if (!this._mapFocusItems.length && !this.layers?.length) {
|
||||
this.leafletMap.setView(
|
||||
new this.Leaflet.LatLng(
|
||||
this.hass.config.latitude,
|
||||
@ -180,7 +185,9 @@ export class HaMap extends ReactiveElement {
|
||||
}
|
||||
|
||||
let bounds = this.Leaflet.latLngBounds(
|
||||
this._mapItems ? this._mapItems.map((item) => item.getLatLng()) : []
|
||||
this._mapFocusItems
|
||||
? this._mapFocusItems.map((item) => item.getLatLng())
|
||||
: []
|
||||
);
|
||||
|
||||
if (this.fitZones) {
|
||||
@ -324,6 +331,7 @@ export class HaMap extends ReactiveElement {
|
||||
if (this._mapItems.length) {
|
||||
this._mapItems.forEach((marker) => marker.remove());
|
||||
this._mapItems = [];
|
||||
this._mapFocusItems = [];
|
||||
}
|
||||
|
||||
if (this._mapZones.length) {
|
||||
@ -353,7 +361,8 @@ export class HaMap extends ReactiveElement {
|
||||
if (!stateObj) {
|
||||
continue;
|
||||
}
|
||||
const title = computeStateName(stateObj);
|
||||
const customTitle = typeof entity !== "string" ? entity.name : undefined;
|
||||
const title = customTitle ?? computeStateName(stateObj);
|
||||
const {
|
||||
latitude,
|
||||
longitude,
|
||||
@ -413,17 +422,20 @@ export class HaMap extends ReactiveElement {
|
||||
|
||||
// DRAW ENTITY
|
||||
// create icon
|
||||
const entityName = title
|
||||
.split(" ")
|
||||
.map((part) => part[0])
|
||||
.join("")
|
||||
.substr(0, 3);
|
||||
const entityName =
|
||||
typeof entity !== "string" && entity.label_mode === "state"
|
||||
? this.hass.formatEntityState(stateObj)
|
||||
: customTitle ??
|
||||
title
|
||||
.split(" ")
|
||||
.map((part) => part[0])
|
||||
.join("")
|
||||
.substr(0, 3);
|
||||
|
||||
// create marker with the icon
|
||||
this._mapItems.push(
|
||||
Leaflet.marker([latitude, longitude], {
|
||||
icon: Leaflet.divIcon({
|
||||
html: `
|
||||
const marker = Leaflet.marker([latitude, longitude], {
|
||||
icon: Leaflet.divIcon({
|
||||
html: `
|
||||
<ha-entity-marker
|
||||
entity-id="${getEntityId(entity)}"
|
||||
entity-name="${entityName}"
|
||||
@ -437,12 +449,15 @@ export class HaMap extends ReactiveElement {
|
||||
}
|
||||
></ha-entity-marker>
|
||||
`,
|
||||
iconSize: [48, 48],
|
||||
className: "",
|
||||
}),
|
||||
title: computeStateName(stateObj),
|
||||
})
|
||||
);
|
||||
iconSize: [48, 48],
|
||||
className: "",
|
||||
}),
|
||||
title: title,
|
||||
});
|
||||
this._mapItems.push(marker);
|
||||
if (typeof entity === "string" || entity.focus !== false) {
|
||||
this._mapFocusItems.push(marker);
|
||||
}
|
||||
|
||||
// create circle around if entity has accuracy
|
||||
if (gpsAccuracy) {
|
||||
|
@ -48,6 +48,11 @@ import { MapCardConfig } from "./types";
|
||||
export const DEFAULT_HOURS_TO_SHOW = 0;
|
||||
export const DEFAULT_ZOOM = 14;
|
||||
|
||||
interface MapEntityConfig extends EntityConfig {
|
||||
label_mode?: "state" | "name";
|
||||
focus?: boolean;
|
||||
}
|
||||
|
||||
@customElement("hui-map-card")
|
||||
class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
@property({ attribute: false }) public hass!: HomeAssistant;
|
||||
@ -63,7 +68,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
@query("ha-map")
|
||||
private _map?: HaMap;
|
||||
|
||||
private _configEntities?: string[];
|
||||
private _configEntities?: MapEntityConfig[];
|
||||
|
||||
private _colorDict: Record<string, string> = {};
|
||||
|
||||
@ -94,11 +99,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
}
|
||||
|
||||
this._config = config;
|
||||
this._configEntities = (
|
||||
config.entities
|
||||
? processConfigEntities<EntityConfig>(config.entities)
|
||||
: []
|
||||
).map((entity) => entity.entity);
|
||||
this._configEntities = config.entities
|
||||
? processConfigEntities<MapEntityConfig>(config.entities)
|
||||
: [];
|
||||
}
|
||||
|
||||
public getCardSize(): number {
|
||||
@ -238,7 +241,7 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
this._stateHistory = combinedHistory;
|
||||
},
|
||||
this._config!.hours_to_show! ?? DEFAULT_HOURS_TO_SHOW,
|
||||
this._configEntities!,
|
||||
(this._configEntities || []).map((entity) => entity.entity)!,
|
||||
false,
|
||||
false,
|
||||
false
|
||||
@ -309,16 +312,14 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
(
|
||||
states: HassEntities,
|
||||
config: MapCardConfig,
|
||||
configEntities?: string[]
|
||||
configEntities?: MapEntityConfig[]
|
||||
) => {
|
||||
if (!states || !config) {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
let entities = configEntities || [];
|
||||
|
||||
const geoEntities: string[] = [];
|
||||
if (config.geo_location_sources) {
|
||||
const geoEntities: string[] = [];
|
||||
// Calculate visible geo location sources
|
||||
const includesAll = config.geo_location_sources.includes("all");
|
||||
for (const stateObj of Object.values(states)) {
|
||||
@ -330,14 +331,21 @@ class HuiMapCard extends LitElement implements LovelaceCard {
|
||||
geoEntities.push(stateObj.entity_id);
|
||||
}
|
||||
}
|
||||
|
||||
entities = [...entities, ...geoEntities];
|
||||
}
|
||||
|
||||
return entities.map((entity) => ({
|
||||
entity_id: entity,
|
||||
color: this._getColor(entity),
|
||||
}));
|
||||
return [
|
||||
...(configEntities || []).map((entityConf) => ({
|
||||
entity_id: entityConf.entity,
|
||||
color: this._getColor(entityConf.entity),
|
||||
label_mode: entityConf.label_mode,
|
||||
focus: entityConf.focus,
|
||||
name: entityConf.name,
|
||||
})),
|
||||
...geoEntities.map((entity) => ({
|
||||
entity_id: entity,
|
||||
color: this._getColor(entity),
|
||||
})),
|
||||
];
|
||||
}
|
||||
);
|
||||
|
||||
|
@ -9,6 +9,7 @@ import {
|
||||
object,
|
||||
optional,
|
||||
string,
|
||||
union,
|
||||
} from "superstruct";
|
||||
import { fireEvent } from "../../../../common/dom/fire_event";
|
||||
import { hasLocation } from "../../../../common/entity/has_location";
|
||||
@ -25,10 +26,19 @@ import { EntityConfig } from "../../entity-rows/types";
|
||||
import { LovelaceCardEditor } from "../../types";
|
||||
import { processEditorEntities } from "../process-editor-entities";
|
||||
import { baseLovelaceCardConfig } from "../structs/base-card-struct";
|
||||
import { entitiesConfigStruct } from "../structs/entities-struct";
|
||||
import { EntitiesEditorEvent } from "../types";
|
||||
import { configElementStyle } from "./config-elements-style";
|
||||
|
||||
export const mapEntitiesConfigStruct = union([
|
||||
object({
|
||||
entity: string(),
|
||||
label_mode: optional(string()),
|
||||
focus: optional(boolean()),
|
||||
name: optional(string()),
|
||||
}),
|
||||
string(),
|
||||
]);
|
||||
|
||||
const cardConfigStruct = assign(
|
||||
baseLovelaceCardConfig,
|
||||
object({
|
||||
@ -36,7 +46,7 @@ const cardConfigStruct = assign(
|
||||
aspect_ratio: optional(string()),
|
||||
default_zoom: optional(number()),
|
||||
dark_mode: optional(boolean()),
|
||||
entities: array(entitiesConfigStruct),
|
||||
entities: array(mapEntitiesConfigStruct),
|
||||
hours_to_show: optional(number()),
|
||||
geo_location_sources: optional(array(string())),
|
||||
auto_fit: optional(boolean()),
|
||||
|
Loading…
x
Reference in New Issue
Block a user