diff --git a/src/components/map/ha-locations-editor.ts b/src/components/map/ha-locations-editor.ts index 3cb70c0f93aa..fcf8c2b12aef 100644 --- a/src/components/map/ha-locations-editor.ts +++ b/src/components/map/ha-locations-editor.ts @@ -41,7 +41,8 @@ export interface MarkerLocation { id: string; icon?: string; radius_color?: string; - editable?: boolean; + location_editable?: boolean; + radius_editable?: boolean; } @customElement("ha-locations-editor") @@ -208,7 +209,7 @@ export class HaLocationsEditor extends LitElement { } ); circle.addTo(this._leafletMap!); - if (location.editable) { + if (location.radius_editable || location.location_editable) { // @ts-ignore circle.editing.enable(); // @ts-ignore @@ -230,19 +231,25 @@ export class HaLocationsEditor extends LitElement { // @ts-ignore (ev: MouseEvent) => this._markerClicked(ev) ); - resizeMarker.addEventListener( - "dragend", - // @ts-ignore - (ev: DragEndEvent) => this._updateRadius(ev) - ); + if (location.radius_editable) { + resizeMarker.addEventListener( + "dragend", + // @ts-ignore + (ev: DragEndEvent) => this._updateRadius(ev) + ); + } else { + resizeMarker.remove(); + } this._locationMarkers![location.id] = circle; } else { this._circles[location.id] = circle; } } - if (!location.radius || !location.editable) { + if ( + !location.radius || + (!location.radius_editable && !location.location_editable) + ) { const options: MarkerOptions = { - draggable: Boolean(location.editable), title: location.name, }; diff --git a/src/panels/config/zone/ha-config-zone.ts b/src/panels/config/zone/ha-config-zone.ts index e015af15acb5..b441c09379e5 100644 --- a/src/panels/config/zone/ha-config-zone.ts +++ b/src/panels/config/zone/ha-config-zone.ts @@ -47,6 +47,9 @@ import { SubscribeMixin } from "../../../mixins/subscribe-mixin"; import { subscribeEntityRegistry } from "../../../data/entity_registry"; import { configSections } from "../ha-panel-config"; import { navigate } from "../../../common/navigate"; +import { saveCoreConfig } from "../../../data/core"; +import { ifDefined } from "lit-html/directives/if-defined"; +import { showConfirmationDialog } from "../../../dialogs/generic/show-dialog-box"; @customElement("ha-config-zone") export class HaConfigZone extends SubscribeMixin(LitElement) { @@ -57,6 +60,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { @property() private _storageItems?: Zone[]; @property() private _stateItems?: HassEntity[]; @property() private _activeEntry: string = ""; + @property() private _canEditCore = false; @query("ha-locations-editor") private _map?: HaLocationsEditor; private _regEntities: string[] = []; @@ -76,14 +80,17 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { : state.attributes.passive ? passiveRadiusColor : defaultRadiusColor, - editable: false, + location_editable: + state.entity_id === "zone.home" && this._canEditCore, + radius_editable: false, }; }); const storageLocations: MarkerLocation[] = storageItems.map((zone) => { return { ...zone, radius_color: zone.passive ? passiveRadiusColor : defaultRadiusColor, - editable: true, + location_editable: true, + radius_editable: true, }; }); return storageLocations.concat(stateLocations); @@ -166,12 +173,23 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { ${state.entity_id === "zone.home" ? this.hass.localize( - "ui.panel.config.zone.edit_home_zone" + `ui.panel.config.zone.${ + this.narrow + ? "edit_home_zone_narrow" + : "edit_home_zone" + }` ) : this.hass.localize( "ui.panel.config.zone.configured_in_yaml" @@ -234,6 +252,9 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { protected firstUpdated(changedProps: PropertyValues) { super.firstUpdated(changedProps); + this._canEditCore = + Boolean(this.hass.user?.is_admin) && + ["storage", "default"].includes(this.hass.config.config_source); this._fetchData(); if (this.route.path === "/new") { navigate(this, "/config/zone", true); @@ -288,8 +309,15 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { } } - private _locationUpdated(ev: CustomEvent) { + private async _locationUpdated(ev: CustomEvent) { this._activeEntry = ev.detail.id; + if (ev.detail.id === "zone.home" && this._canEditCore) { + await saveCoreConfig(this.hass, { + latitude: ev.detail.location[0], + longitude: ev.detail.location[1], + }); + return; + } const entry = this._storageItems!.find((item) => item.id === ev.detail.id); if (!entry) { return; @@ -319,7 +347,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { this._openDialog(); } - private _itemClicked(ev: MouseEvent) { + private _itemClicked(ev: Event) { if (this.narrow) { this._openEditEntry(ev); return; @@ -328,7 +356,7 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { this._zoomZone(entry.id); } - private _stateItemClicked(ev: MouseEvent) { + private _stateItemClicked(ev: Event) { const entityId = (ev.currentTarget! as HTMLElement).getAttribute( "data-id" )!; @@ -339,11 +367,29 @@ export class HaConfigZone extends SubscribeMixin(LitElement) { this._map?.fitMarker(id); } - private _openEditEntry(ev: MouseEvent) { + private _openEditEntry(ev: Event) { const entry: Zone = (ev.currentTarget! as any).entry; this._openDialog(entry); } + private async _openCoreConfig(ev: Event) { + const entityId: string = (ev.currentTarget! as any).entityId; + if (entityId !== "zone.home" || !this.narrow || !this._canEditCore) { + return; + } + if ( + !(await showConfirmationDialog(this, { + title: this.hass.localize("ui.panel.config.zone.go_to_core_config"), + text: this.hass.localize("ui.panel.config.zone.home_zone_core_config"), + confirmText: this.hass!.localize("ui.common.yes"), + dismissText: this.hass!.localize("ui.common.no"), + })) + ) { + return; + } + navigate(this, "/config/core"); + } + private async _createEntry(values: ZoneMutableParams) { const created = await createZone(this.hass!, values); this._storageItems = this._storageItems!.concat( diff --git a/src/translations/en.json b/src/translations/en.json index 771ac55b29ca..37885ba5cdb7 100755 --- a/src/translations/en.json +++ b/src/translations/en.json @@ -1411,7 +1411,10 @@ "add_zone": "Add Zone", "confirm_delete": "Are you sure you want to delete this zone?", "configured_in_yaml": "Zones configured via configuration.yaml cannot be edited via the UI.", - "edit_home_zone": "The location of your home can be changed in the general configuration.", + "edit_home_zone": "The radius of the Home zone can't be edited from the frontend yet. Drag the marker on the map to move the home zone.", + "edit_home_zone_narrow": "The radius of the Home zone can't be edited from the frontend yet. The location can be changed from the general configuration.", + "go_to_core_config": "Go to general configuration?", + "home_zone_core_config": "The location of your home zone is editable from the general configuration page. The radius of the Home zone can't be edited from the frontend yet. Do you want to go to the general configuration?", "detail": { "new_zone": "New Zone", "name": "Name",