Add 'focus' option to geo_location_sources for map card (#22535)

* Add 'focus' option to geo_location_sources for map card

* visual editor compatibility
This commit is contained in:
karwosts 2024-10-29 06:32:30 -07:00 committed by GitHub
parent 48dfa1163b
commit 42f2341e06
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 53 additions and 14 deletions

View File

@ -50,6 +50,11 @@ interface MapEntityConfig extends EntityConfig {
focus?: boolean;
}
interface GeoEntity {
entity_id: string;
focus: boolean;
}
@customElement("hui-map-card")
class HuiMapCard extends LitElement implements LovelaceCard {
@property({ attribute: false }) public hass!: HomeAssistant;
@ -332,23 +337,32 @@ class HuiMapCard extends LitElement implements LovelaceCard {
return color;
}
private _getSourceEntities(states?: HassEntities): string[] {
private _getSourceEntities(states?: HassEntities): GeoEntity[] {
if (!states || !this._config?.geo_location_sources) {
return [];
}
const geoEntities: string[] = [];
const sourceObjs = this._config.geo_location_sources.map((source) =>
typeof source === "string" ? { source } : source
);
const geoEntities: GeoEntity[] = [];
// Calculate visible geo location sources
const includesAll = this._config.geo_location_sources.includes("all");
const allSource = sourceObjs.find((s) => s.source === "all");
for (const stateObj of Object.values(states)) {
const sourceObj = sourceObjs.find(
(s) => s.source === stateObj.attributes.source
);
if (
computeDomain(stateObj.entity_id) === "geo_location" &&
(includesAll ||
this._config.geo_location_sources.includes(
stateObj.attributes.source
))
(allSource || sourceObj)
) {
geoEntities.push(stateObj.entity_id);
geoEntities.push({
entity_id: stateObj.entity_id,
focus: sourceObj
? (sourceObj.focus ?? true)
: (allSource?.focus ?? true),
});
}
}
return geoEntities;
@ -364,8 +378,9 @@ class HuiMapCard extends LitElement implements LovelaceCard {
name: entityConf.name,
})),
...this._getSourceEntities(this.hass?.states).map((entity) => ({
entity_id: entity,
color: this._getColor(entity),
entity_id: entity.entity_id,
focus: entity.focus,
color: this._getColor(entity.entity_id),
})),
];
}

View File

@ -298,6 +298,11 @@ export interface LogbookCardConfig extends LovelaceCardConfig {
theme?: string;
}
interface GeoLocationSourceConfig {
source: string;
focus?: boolean;
}
export interface MapCardConfig extends LovelaceCardConfig {
type: "map";
title?: string;
@ -307,7 +312,7 @@ export interface MapCardConfig extends LovelaceCardConfig {
default_zoom?: number;
entities?: Array<EntityConfig | string>;
hours_to_show?: number;
geo_location_sources?: string[];
geo_location_sources?: Array<GeoLocationSourceConfig | string>;
dark_mode?: boolean;
theme_mode?: ThemeMode;
}

View File

@ -44,6 +44,14 @@ export const mapEntitiesConfigStruct = union([
string(),
]);
const geoSourcesConfigStruct = union([
object({
source: string(),
focus: optional(boolean()),
}),
string(),
]);
const cardConfigStruct = assign(
baseLovelaceCardConfig,
object({
@ -53,7 +61,7 @@ const cardConfigStruct = assign(
dark_mode: optional(boolean()),
entities: array(mapEntitiesConfigStruct),
hours_to_show: optional(number()),
geo_location_sources: optional(array(string())),
geo_location_sources: optional(array(geoSourcesConfigStruct)),
auto_fit: optional(boolean()),
theme_mode: optional(string()),
})
@ -139,8 +147,12 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
: [];
}
private _geoSourcesStrings = memoizeOne((sources): string[] | undefined =>
sources?.map((s) => (typeof s === "string" ? s : s.source))
);
get _geo_location_sources(): string[] {
return this._config!.geo_location_sources || [];
return this._geoSourcesStrings(this._config!.geo_location_sources) || [];
}
protected render() {
@ -228,9 +240,16 @@ export class HuiMapCardEditor extends LitElement implements LovelaceCardEditor {
this._config = { ...this._config };
delete this._config.geo_location_sources;
} else {
const newSources = value.map(
(newSource) =>
this._config!.geo_location_sources?.find(
(oldSource) =>
typeof oldSource === "object" && oldSource.source === newSource
) || newSource
);
this._config = {
...this._config,
geo_location_sources: value,
geo_location_sources: newSources,
};
}
fireEvent(this, "config-changed", { config: this._config });