diff --git a/application/src/main/java/org/thingsboard/server/controller/AdminController.java b/application/src/main/java/org/thingsboard/server/controller/AdminController.java index 8873d82366..134171c8b1 100644 --- a/application/src/main/java/org/thingsboard/server/controller/AdminController.java +++ b/application/src/main/java/org/thingsboard/server/controller/AdminController.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.controller; +import com.fasterxml.jackson.databind.node.ObjectNode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.access.prepost.PreAuthorize; import org.springframework.web.bind.annotation.PathVariable; @@ -59,7 +60,11 @@ public class AdminController extends BaseController { public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException { try { accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ); - return checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key)); + AdminSettings adminSettings = checkNotNull(adminSettingsService.findAdminSettingsByKey(TenantId.SYS_TENANT_ID, key)); + if (adminSettings.getKey().equals("mail")) { + ((ObjectNode) adminSettings.getJsonValue()).put("password", ""); + } + return adminSettings; } catch (Exception e) { throw handleException(e); } @@ -74,6 +79,7 @@ public class AdminController extends BaseController { adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings)); if (adminSettings.getKey().equals("mail")) { mailService.updateMailConfiguration(); + ((ObjectNode) adminSettings.getJsonValue()).put("password", ""); } return adminSettings; } catch (Exception e) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java index 3064754a1b..f2e768e6b2 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java +++ b/dao/src/main/java/org/thingsboard/server/dao/alarm/BaseAlarmService.java @@ -391,8 +391,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ } private Set getPropagationEntityIds(Alarm alarm) { - List relations = relationService.findByTo(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM); - return relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet()); + if (alarm.isPropagate()) { + List relations = relationService.findByTo(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM); + return relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet()); + } else { + return Collections.singleton(alarm.getOriginator()); + } } private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId) { diff --git a/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java b/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java index 3d53064ff1..ec57567a1a 100644 --- a/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java +++ b/dao/src/main/java/org/thingsboard/server/dao/settings/AdminSettingsServiceImpl.java @@ -15,6 +15,7 @@ */ package org.thingsboard.server.dao.settings; +import com.fasterxml.jackson.databind.node.ObjectNode; import lombok.extern.slf4j.Slf4j; import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; @@ -51,6 +52,13 @@ public class AdminSettingsServiceImpl implements AdminSettingsService { public AdminSettings saveAdminSettings(TenantId tenantId, AdminSettings adminSettings) { log.trace("Executing saveAdminSettings [{}]", adminSettings); adminSettingsValidator.validate(adminSettings, data -> tenantId); + if (adminSettings.getKey().equals("mail") && "".equals(adminSettings.getJsonValue().get("password").asText())) { + AdminSettings mailSettings = findAdminSettingsByKey(tenantId, "mail"); + if (mailSettings != null) { + ((ObjectNode) adminSettings.getJsonValue()).put("password", mailSettings.getJsonValue().get("password").asText()); + } + } + return adminSettingsDao.save(tenantId, adminSettings); } diff --git a/ui-ngx/package.json b/ui-ngx/package.json index 2c8270e239..9ccabf971e 100644 --- a/ui-ngx/package.json +++ b/ui-ngx/package.json @@ -35,13 +35,11 @@ "@ngrx/effects": "^10.0.0", "@ngrx/store": "^10.0.0", "@ngrx/store-devtools": "^10.0.0", - "ngx-sharebuttons": "^8.0.1", "@ngx-translate/core": "^13.0.0", "@ngx-translate/http-loader": "^6.0.0", "ace-builds": "^1.4.12", "angular-gridster2": "^10.1.3", "angular2-hotkeys": "^2.2.0", - "base64-js": "^1.3.1", "canvas-gauges": "^2.1.7", "compass-sass-mixins": "^0.12.7", "core-js": "^3.6.5", @@ -70,6 +68,7 @@ "ngx-daterangepicker-material": "^3.0.4", "ngx-flowchart": "git://github.com/thingsboard/ngx-flowchart.git#master", "ngx-hm-carousel": "^2.0.0-rc.1", + "ngx-sharebuttons": "^8.0.1", "ngx-translate-messageformat-compiler": "^4.8.0", "objectpath": "^2.0.0", "prettier": "^2.0.5", diff --git a/ui-ngx/src/app/core/services/resources.service.ts b/ui-ngx/src/app/core/services/resources.service.ts index 3c88ff4200..97dd480e2e 100644 --- a/ui-ngx/src/app/core/services/resources.service.ts +++ b/ui-ngx/src/app/core/services/resources.service.ts @@ -26,7 +26,6 @@ import { import { DOCUMENT } from '@angular/common'; import { forkJoin, Observable, ReplaySubject, throwError } from 'rxjs'; import { HttpClient } from '@angular/common/http'; -import { objToBase64 } from '@core/utils'; declare const SystemJS; diff --git a/ui-ngx/src/app/core/utils.ts b/ui-ngx/src/app/core/utils.ts index 5ba8c80806..9834405eda 100644 --- a/ui-ngx/src/app/core/utils.ts +++ b/ui-ngx/src/app/core/utils.ts @@ -17,7 +17,6 @@ import _ from 'lodash'; import { Observable, Subject } from 'rxjs'; import { finalize, share } from 'rxjs/operators'; -import base64js from 'base64-js'; import { Datasource } from '@app/shared/models/widget.models'; const varsRegex = /\${([^}]*)}/g; @@ -123,7 +122,8 @@ export function isEmpty(obj: any): boolean { } export function formatValue(value: any, dec?: number, units?: string, showZeroDecimals?: boolean): string | undefined { - if (isDefinedAndNotNull(value) && isNumeric(value) && (isDefinedAndNotNull(dec) || isDefinedAndNotNull(units) || Number(value).toString() === value)) { + if (isDefinedAndNotNull(value) && isNumeric(value) && + (isDefinedAndNotNull(dec) || isDefinedAndNotNull(units) || Number(value).toString() === value)) { let formatted: string | number = Number(value); if (isDefinedAndNotNull(dec)) { formatted = formatted.toFixed(dec); @@ -164,28 +164,21 @@ export function deleteNullProperties(obj: any) { export function objToBase64(obj: any): string { const json = JSON.stringify(obj); - const encoded = utf8Encode(json); - return base64js.fromByteArray(encoded); + return btoa(encodeURIComponent(json).replace(/%([0-9A-F]{2})/g, + function toSolidBytes(match, p1) { + return String.fromCharCode(Number('0x' + p1)); + })); } -export function base64toObj(b64Encoded: string): any { - const encoded: Uint8Array | number[] = base64js.toByteArray(b64Encoded); - const json = utf8Decode(encoded); - return JSON.parse(json); -} - -function utf8Encode(str: string): Uint8Array | number[] { - let result: Uint8Array | number[]; - if (isUndefined(Uint8Array)) { - result = utf8ToBytes(str); - } else { - result = new Uint8Array(utf8ToBytes(str)); - } - return result; +export function objToBase64URI(obj: any): string { + return encodeURIComponent(objToBase64(obj)); } -function utf8Decode(bytes: Uint8Array | number[]): string { - return utf8Slice(bytes, 0, bytes.length); +export function base64toObj(b64Encoded: string): any { + const json = decodeURIComponent(atob(b64Encoded).split('').map((c) => { + return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2); + }).join('')); + return JSON.parse(json); } const scrollRegex = /(auto|scroll)/; @@ -275,129 +268,6 @@ function easeInOut( ); } -function utf8Slice(buf: Uint8Array | number[], start: number, end: number): string { - let res = ''; - let tmp = ''; - end = Math.min(buf.length, end || Infinity); - start = start || 0; - - for (let i = start; i < end; i++) { - if (buf[i] <= 0x7F) { - res += decodeUtf8Char(tmp) + String.fromCharCode(buf[i]); - tmp = ''; - } else { - tmp += '%' + buf[i].toString(16); - } - } - return res + decodeUtf8Char(tmp); -} - -function decodeUtf8Char(str: string): string { - try { - return decodeURIComponent(str); - } catch (err) { - return String.fromCharCode(0xFFFD); // UTF 8 invalid char - } -} - -function utf8ToBytes(input: string, units?: number): number[] { - units = units || Infinity; - let codePoint: number; - const length = input.length; - let leadSurrogate: number = null; - const bytes: number[] = []; - let i = 0; - - for (; i < length; i++) { - codePoint = input.charCodeAt(i); - - // is surrogate component - if (codePoint > 0xD7FF && codePoint < 0xE000) { - // last char was a lead - if (leadSurrogate) { - // 2 leads in a row - if (codePoint < 0xDC00) { - units -= 3; - if (units > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - leadSurrogate = codePoint; - continue; - } else { - // valid surrogate pair - // tslint:disable-next-line:no-bitwise - codePoint = leadSurrogate - 0xD800 << 10 | codePoint - 0xDC00 | 0x10000; - leadSurrogate = null; - } - } else { - // no lead yet - - if (codePoint > 0xDBFF) { - // unexpected trail - units -= 3; - if (units > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - continue; - } else if (i + 1 === length) { - // unpaired lead - units -= 3; - if (units > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - continue; - } else { - // valid lead - leadSurrogate = codePoint; - continue; - } - } - } else if (leadSurrogate) { - // valid bmp char, but last char was a lead - units -= 3; - if (units > -1) { bytes.push(0xEF, 0xBF, 0xBD); } - leadSurrogate = null; - } - - // encode utf8 - if (codePoint < 0x80) { - units -= 1; - if (units < 0) { break; } - bytes.push(codePoint); - } else if (codePoint < 0x800) { - units -= 2; - if (units < 0) { break; } - bytes.push( - // tslint:disable-next-line:no-bitwise - codePoint >> 0x6 | 0xC0, - // tslint:disable-next-line:no-bitwise - codePoint & 0x3F | 0x80 - ); - } else if (codePoint < 0x10000) { - units -= 3; - if (units < 0) { break; } - bytes.push( - // tslint:disable-next-line:no-bitwise - codePoint >> 0xC | 0xE0, - // tslint:disable-next-line:no-bitwise - codePoint >> 0x6 & 0x3F | 0x80, - // tslint:disable-next-line:no-bitwise - codePoint & 0x3F | 0x80 - ); - } else if (codePoint < 0x200000) { - units -= 4; - if (units < 0) { break; } - bytes.push( - // tslint:disable-next-line:no-bitwise - codePoint >> 0x12 | 0xF0, - // tslint:disable-next-line:no-bitwise - codePoint >> 0xC & 0x3F | 0x80, - // tslint:disable-next-line:no-bitwise - codePoint >> 0x6 & 0x3F | 0x80, - // tslint:disable-next-line:no-bitwise - codePoint & 0x3F | 0x80 - ); - } else { - throw new Error('Invalid code point'); - } - } - return bytes; -} - export function deepClone(target: T, ignoreFields?: string[]): T { if (target === null) { return target; diff --git a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts index 4868270948..d3b8c36286 100644 --- a/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts +++ b/ui-ngx/src/app/modules/home/components/attribute/add-widget-to-dashboard-dialog.component.ts @@ -24,7 +24,7 @@ import { Router } from '@angular/router'; import { DialogComponent } from '@app/shared/components/dialog.component'; import { UtilsService } from '@core/services/utils.service'; import { Dashboard, DashboardLayoutId } from '@app/shared/models/dashboard.models'; -import { objToBase64 } from '@core/utils'; +import { objToBase64URI } from '@core/utils'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { EntityId } from '@app/shared/models/id/entity-id'; import { Widget } from '@app/shared/models/widget.models'; @@ -205,7 +205,7 @@ export class AddWidgetToDashboardDialogComponent extends id: targetState, params: {} }; - const state = objToBase64([ stateObject ]); + const state = objToBase64URI([ stateObject ]); url = `/dashboards/${theDashboard.id.id}?state=${state}`; } else { url = `/dashboards/${theDashboard.id.id}`; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts index 2da560b8cb..6bf8fc9ce2 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/leaflet-map.ts @@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster'; import { defaultSettings, FormattedData, + MapProviders, MapSettings, MarkerSettings, PolygonSettings, @@ -74,6 +75,8 @@ export default abstract class LeafletMap { drawRoutes: boolean; showPolygon: boolean; updatePending = false; + addMarkers: L.Marker[] = []; + addPolygons: L.Polygon[] = []; protected constructor(public ctx: WidgetContext, public $container: HTMLElement, @@ -133,6 +136,7 @@ export default abstract class LeafletMap { shadowSize: [41, 41] }); const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map); + this.addMarkers.push(newMarker); const datasourcesList = document.createElement('div'); const customLatLng = this.convertToCustomFormat(mousePositionOnMap); const header = document.createElement('p'); @@ -147,10 +151,14 @@ export default abstract class LeafletMap { const updatedEnttity = { ...ds, ...customLatLng }; this.saveMarkerLocation(updatedEnttity).subscribe(() => { this.map.removeLayer(newMarker); + const markerIndex = this.addMarkers.indexOf(newMarker); + if (markerIndex > -1) { + this.addMarkers.splice(markerIndex, 1); + } this.deleteMarker(ds.entityName); this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options); }); - } + }; datasourcesList.append(dsItem); }); datasourcesList.append(document.createElement('br')); @@ -158,14 +166,18 @@ export default abstract class LeafletMap { deleteBtn.appendChild(document.createTextNode('Discard changes')); deleteBtn.onclick = () => { this.map.removeLayer(newMarker); - } + const markerIndex = this.addMarkers.indexOf(newMarker); + if (markerIndex > -1) { + this.addMarkers.splice(markerIndex, 1); + } + }; datasourcesList.append(deleteBtn); const popup = L.popup(); popup.setContent(datasourcesList); newMarker.bindPopup(popup).openPopup(); } - addMarker.setPosition('topright') - } + addMarker.setPosition('topright'); + }; L.Control.AddMarker = L.Control.extend({ onAdd() { const img = L.DomUtil.create('img') as any; @@ -177,7 +189,7 @@ export default abstract class LeafletMap { img.draggable = true; const draggableImg = new L.Draggable(img); draggableImg.enable(); - draggableImg.on('dragend', dragListener) + draggableImg.on('dragend', dragListener); return img; }, onRemove() { @@ -186,7 +198,7 @@ export default abstract class LeafletMap { } as any); L.control.addMarker = (opts) => { return new L.Control.AddMarker(opts); - } + }; addMarker = L.control.addMarker({ position: 'topright' }).addTo(this.map); } } @@ -196,14 +208,16 @@ export default abstract class LeafletMap { let mousePositionOnMap: L.LatLng[]; let addPolygon: L.Control; this.map.on('mousemove', (e: L.LeafletMouseEvent) => { + const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01; const latlng1 = e.latlng; - const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10); - const latlng3 = L.latLng(e.latlng.lat-10, e.latlng.lng); - mousePositionOnMap = [latlng1,latlng2, latlng3 ]; + const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset); + const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng); + mousePositionOnMap = [latlng1, latlng2, latlng3]; }); const dragListener = (e: L.DragEndEvent) => { if (e.type === 'dragend' && mousePositionOnMap) { const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map); + this.addPolygons.push(newPolygon); const datasourcesList = document.createElement('div'); const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)}; const header = document.createElement('p'); @@ -218,9 +232,13 @@ export default abstract class LeafletMap { const updatedEnttity = { ...ds, ...customLatLng }; this.savePolygonLocation(updatedEnttity).subscribe(() => { this.map.removeLayer(newPolygon); + const polygonIndex = this.addPolygons.indexOf(newPolygon); + if (polygonIndex > -1) { + this.addPolygons.splice(polygonIndex, 1); + } this.deletePolygon(ds.entityName); }); - } + }; datasourcesList.append(dsItem); }); datasourcesList.append(document.createElement('br')); @@ -228,14 +246,18 @@ export default abstract class LeafletMap { deleteBtn.appendChild(document.createTextNode('Discard changes')); deleteBtn.onclick = () => { this.map.removeLayer(newPolygon); - } + const polygonIndex = this.addPolygons.indexOf(newPolygon); + if (polygonIndex > -1) { + this.addPolygons.splice(polygonIndex, 1); + } + }; datasourcesList.append(deleteBtn); const popup = L.popup(); popup.setContent(datasourcesList); newPolygon.bindPopup(popup).openPopup(); } - addPolygon.setPosition('topright') - } + addPolygon.setPosition('topright'); + }; L.Control.AddPolygon = L.Control.extend({ onAdd() { const img = L.DomUtil.create('img') as any; @@ -247,7 +269,7 @@ export default abstract class LeafletMap { img.draggable = true; const draggableImg = new L.Draggable(img); draggableImg.enable(); - draggableImg.on('dragend', dragListener) + draggableImg.on('dragend', dragListener); return img; }, onRemove() { @@ -256,7 +278,7 @@ export default abstract class LeafletMap { } as any); L.control.addPolygon = (opts) => { return new L.Control.AddPolygon(opts); - } + }; addPolygon = L.control.addPolygon({ position: 'topright' }).addTo(this.map); } } @@ -280,10 +302,11 @@ export default abstract class LeafletMap { public setMap(map: L.Map) { this.map = map; if (this.options.useDefaultCenterPosition) { - this.map.panTo(this.options.defaultCenterPosition); - this.bounds = map.getBounds(); + this.map.panTo(this.options.defaultCenterPosition); + this.bounds = map.getBounds(); + } else { + this.bounds = new L.LatLngBounds(null, null); } - else this.bounds = new L.LatLngBounds(null, null); if (this.options.draggableMarker) { this.addMarkerControl(); } @@ -299,11 +322,11 @@ export default abstract class LeafletMap { } } - public saveMarkerLocation(_e: FormattedData, lat?: number, lng?: number): Observable { + public saveMarkerLocation(datasource: FormattedData, lat?: number, lng?: number): Observable { return of(null); } - public savePolygonLocation(_e: FormattedData, coordinates?: Array<[number, number]>): Observable { + public savePolygonLocation(datasource: FormattedData, coordinates?: Array<[number, number]>): Observable { return of(null); } @@ -364,7 +387,9 @@ export default abstract class LeafletMap { } convertPosition(expression: object): L.LatLng { - if (!expression) return null; + if (!expression) { + return null; + } const lat = expression[this.options.latKeyName]; const lng = expression[this.options.lngKeyName]; if (!isDefinedAndNotNull(lat) || isString(lat) || isNaN(lat) || !isDefinedAndNotNull(lng) || isString(lng) || isNaN(lng)) { @@ -382,35 +407,35 @@ export default abstract class LeafletMap { } else { return null; } - }).filter(el => !!el) + }).filter(el => !!el); } convertToCustomFormat(position: L.LatLng): object { return { [this.options.latKeyName]: position.lat % 90, [this.options.lngKeyName]: position.lng % 180 - } + }; } - convertToPolygonFormat(points: Array): Array { - if (points.length) { - return points.map(point=> { - if (point.length) { - return this.convertToPolygonFormat(point); - } else { - return [point.lat, point.lng]; - } - }) - } else { - return [] + convertToPolygonFormat(points: Array): Array { + if (points.length) { + return points.map(point => { + if (point.length) { + return this.convertToPolygonFormat(point); + } else { + return [point.lat, point.lng]; + } + }); + } else { + return []; + } } - } - convertPolygonToCustomFormat(expression: any[][]): object { - return { - [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) + convertPolygonToCustomFormat(expression: any[][]): object { + return { + [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) + }; } - } updateData(drawRoutes: boolean, showPolygon: boolean) { this.drawRoutes = drawRoutes; @@ -509,7 +534,7 @@ export default abstract class LeafletMap { this.markersCluster.addLayers(createdMarkers.map(marker => marker.leafletMarker)); } if (updatedMarkers.length) { - this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker)) + this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker)); } if (deletedMarkers.length) { this.markersCluster.removeLayers(deletedMarkers.map(marker => marker.leafletMarker)); @@ -518,7 +543,9 @@ export default abstract class LeafletMap { } dragMarker = (e, data = {} as FormattedData) => { - if (e.type !== 'dragend') return; + if (e.type !== 'dragend') { + return; + } this.saveMarkerLocation({ ...data, ...this.convertToCustomFormat(e.target._latlng) }).subscribe(); } @@ -527,7 +554,7 @@ export default abstract class LeafletMap { const newMarker = new Marker(this, this.convertPosition(data), settings, data, dataSources, this.dragMarker); if (callback) { newMarker.leafletMarker.on('click', () => { - callback(data, true) + callback(data, true); }); } if (this.bounds && updateBounds && !(this.options as MarkerSettings).useClusterMarkers) { @@ -565,11 +592,10 @@ export default abstract class LeafletMap { } deletePolygon(key: string) { - let polygon = this.polygons.get(key)?.leafletPoly; + const polygon = this.polygons.get(key)?.leafletPoly; if (polygon) { this.map.removeLayer(polygon); this.polygons.delete(key); - polygon = null; } return polygon; } @@ -684,7 +710,9 @@ export default abstract class LeafletMap { } dragPolygonVertex = (e?, data = {} as FormattedData) => { - if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) return; + if (e === undefined || (e.type !== 'editable:vertex:dragend' && e.type !== 'editable:vertex:deleted')) { + return; + } this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe(); } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts index 5341c48389..63fe097b98 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-models.ts @@ -62,7 +62,7 @@ export type MapSettings = { useCustomProvider: boolean, customProviderTileUrl: string; mapPageSize: number; -} +}; export enum MapProviders { google = 'google-map', @@ -103,7 +103,7 @@ export type MarkerSettings = { markerImageFunction?: MarkerImageFunction; markerOffsetX: number; markerOffsetY: number; -} +}; export interface FormattedData { $datasource: Datasource; @@ -112,19 +112,19 @@ export interface FormattedData { entityType: EntityType; dsIndex: number; deviceType: string; - [key: string]: any + [key: string]: any; } export interface ReplaceInfo { variable: string; valDec?: number; - dataKeyName: string + dataKeyName: string; } export type PolygonSettings = { showPolygon: boolean; polygonKeyName: string; - polKeyName: string;// deprecated + polKeyName: string; // deprecated polygonStrokeOpacity: number; polygonOpacity: number; polygonStrokeWeight: number; @@ -141,7 +141,7 @@ export type PolygonSettings = { polygonTooltipFunction: GenericFunction; polygonColorFunction?: GenericFunction; editablePolygon: boolean; -} +}; export type PolylineSettings = { usePolylineDecorator: any; @@ -166,7 +166,7 @@ export type PolylineSettings = { colorFunction: GenericFunction; strokeOpacityFunction: GenericFunction; strokeWeightFunction: GenericFunction; -} +}; export interface HistorySelectSettings { buttonColor: string; @@ -244,4 +244,5 @@ export const hereProviders = [ 'HERE.normalDay', 'HERE.normalNight', 'HERE.hybridDay', - 'HERE.terrainDay'] + 'HERE.terrainDay' +]; diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts index be618128dd..d321e04953 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget.interface.ts @@ -18,15 +18,15 @@ import { JsonSettingsSchema } from '@shared/models/widget.models'; import { MapProviders } from './map-models'; export interface MapWidgetInterface { - resize(), - update(), - onInit(), + resize(); + update(); + onInit(); onDestroy(); } export interface MapWidgetStaticInterface { settingsSchema(mapProvider?: MapProviders, drawRoutes?: boolean): JsonSettingsSchema; - getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema + getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema; dataKeySettingsSchema(): object; actionSources(): object; } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts index f6bd983bb5..950e73e96d 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/map-widget2.ts @@ -33,7 +33,7 @@ import { import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface'; import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils'; import { WidgetContext } from '@app/modules/home/models/widget-component.models'; -import { getDefCenterPosition, parseData, parseFunction, parseWithTranslation } from './maps-utils'; +import { getDefCenterPosition, parseFunction, parseWithTranslation } from './maps-utils'; import { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models'; import { EntityId } from '@shared/models/id/entity-id'; import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models'; @@ -102,8 +102,9 @@ export class MapWidgetController implements MapWidgetInterface { public static getProvidersSchema(mapProvider: MapProviders, ignoreImageMap = false) { const providerSchema = _.cloneDeep(mapProviderSchema); - if (mapProvider) - providerSchema.schema.properties.provider.default = mapProvider; + if (mapProvider) { + providerSchema.schema.properties.provider.default = mapProvider; + } if (ignoreImageMap) { providerSchema.form[0].items = providerSchema.form[0]?.items.filter(item => item.value !== 'image-map'); } @@ -129,7 +130,7 @@ export class MapWidgetController implements MapWidgetInterface { } else { const clusteringSchema = mergeSchemes([markerClusteringSettingsSchema, addCondition(markerClusteringSettingsSchemaLeaflet, - `model.useClusterMarkers === true && model.provider !== "image-map"`)]) + `model.useClusterMarkers === true && model.provider !== "image-map"`)]); addToSchema(schema, clusteringSchema); addGroupInfo(schema, 'Markers Clustering Settings'); } @@ -154,10 +155,11 @@ export class MapWidgetController implements MapWidgetInterface { } translate = (key: string, defaultTranslation?: string): string => { - if (key) - return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key) - || this.ctx.$injector.get(TranslateService).instant(key)); - else return ''; + if (key) { + return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key) + || this.ctx.$injector.get(TranslateService).instant(key)); + } + return ''; } getDescriptors(name: string): { [name: string]: ($event: Event, datasource: Datasource) => void } { @@ -211,10 +213,10 @@ export class MapWidgetController implements MapWidgetInterface { } if (value) { if (key.type === DataKeyType.attribute) { - attributes.push(value) + attributes.push(value); } if (key.type === DataKeyType.timeseries) { - timeseries.push(value) + timeseries.push(value); } } }); @@ -253,7 +255,7 @@ export class MapWidgetController implements MapWidgetInterface { const coordinatesProperties = this.settings.polygonKeyName; e.$datasource.dataKeys.forEach(key => { let value; - if (coordinatesProperties == key.name) { + if (coordinatesProperties === key.name) { value = { key: key.name, value: isDefined(coordinates) ? coordinates : e[key.name] @@ -261,10 +263,10 @@ export class MapWidgetController implements MapWidgetInterface { } if (value) { if (key.type === DataKeyType.attribute) { - attributes.push(value) + attributes.push(value); } if (key.type === DataKeyType.timeseries) { - timeseries.push(value) + timeseries.push(value); } } }); @@ -294,9 +296,11 @@ export class MapWidgetController implements MapWidgetInterface { const functionParams = ['data', 'dsData', 'dsIndex']; this.provider = settings.provider || this.mapProvider; if (this.provider === MapProviders.here && !settings.mapProviderHere) { - if (settings.mapProvider && hereProviders.includes(settings.mapProvider)) - settings.mapProviderHere = settings.mapProvider - else settings.mapProviderHere = hereProviders[0]; + if (settings.mapProvider && hereProviders.includes(settings.mapProvider)) { + settings.mapProviderHere = settings.mapProvider; + } else { + settings.mapProviderHere = hereProviders[0]; + } } const customOptions = { provider: this.provider, @@ -317,14 +321,14 @@ export class MapWidgetController implements MapWidgetInterface { url: settings.markerImage, size: settings.markerImageSize || 34 } : null - } + }; if (isEditMap && !settings.hasOwnProperty('draggableMarker')) { settings.draggableMarker = true; } if (isEditMap && !settings.hasOwnProperty('editablePolygon')) { settings.editablePolygon = true; } - return { ...defaultSettings, ...settings, ...customOptions, } + return { ...defaultSettings, ...settings, ...customOptions, }; } update() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts index 813437a439..e9f1f5dadd 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/maps-utils.ts @@ -31,9 +31,9 @@ import { } from '@core/utils'; export function createTooltip(target: L.Layer, - settings: MarkerSettings | PolylineSettings | PolygonSettings, - datasource: Datasource, - content?: string | HTMLElement + settings: MarkerSettings | PolylineSettings | PolygonSettings, + datasource: Datasource, + content?: string | HTMLElement ): L.Popup { const popup = L.popup(); popup.setContent(content); @@ -87,7 +87,7 @@ export function interpolateOnLineSegment( } export function findAngle(startPoint: FormattedData, endPoint: FormattedData, latKeyName: string, lngKeyName: string): number { - if(isUndefined(startPoint) || isUndefined(endPoint)){ + if (isUndefined(startPoint) || isUndefined(endPoint)) { return 0; } let angle = -Math.atan2(endPoint[latKeyName] - startPoint[latKeyName], endPoint[lngKeyName] - startPoint[lngKeyName]); @@ -97,11 +97,13 @@ export function findAngle(startPoint: FormattedData, endPoint: FormattedData, la export function getDefCenterPosition(position) { - if (typeof (position) === 'string') - return position.split(','); - if (typeof (position) === 'object') - return position; - return [0, 0]; + if (typeof (position) === 'string') { + return position.split(','); + } + if (typeof (position) === 'object') { + return position; + } + return [0, 0]; } @@ -123,7 +125,7 @@ function imageLoader(imageUrl: string): Observable { document.body.removeChild(image); observer.complete(); }; - document.body.appendChild(image) + document.body.appendChild(image); image.src = imageUrl; }); } @@ -135,11 +137,11 @@ export function aspectCache(imageUrl: string): Observable { if (aspect) { return of(aspect); } - else return imageLoader(imageUrl).pipe(map(image => { + return imageLoader(imageUrl).pipe(map(image => { aspect = image.width / image.height; imageAspectMap[hash] = aspect; return aspect; - })) + })); } } @@ -221,7 +223,7 @@ function parseTemplate(template: string, data: { $datasource?: Datasource, [key: // res = compiled(data); res = template; } catch (ex) { - console.log(ex, template) + console.log(ex, template); } return res; } @@ -263,7 +265,7 @@ export function processPattern(template: string, data: { $datasource?: Datasourc match = reg.exec(template); } } catch (ex) { - console.log(ex, template) + console.log(ex, template); } return replaceInfo; } @@ -271,7 +273,7 @@ export function processPattern(template: string, data: { $datasource?: Datasourc export function fillPattern(markerLabelText: string, replaceInfoLabelMarker: Array, data: FormattedData) { let text = createLabelFromDatasource(data.$datasource, markerLabelText); if (replaceInfoLabelMarker) { - for(const variableInfo of replaceInfoLabelMarker) { + for (const variableInfo of replaceInfoLabelMarker) { let txtVal = ''; if (variableInfo.dataKeyName && isDefinedAndNotNull(data[variableInfo.dataKeyName])) { const varData = data[variableInfo.dataKeyName]; @@ -334,7 +336,7 @@ export const parseWithTranslation = { setTranslate(translateFn: TranslateFunc) { this.translateFn = translateFn; } -} +}; export function parseData(input: DatasourceData[]): FormattedData[] { return _(input).groupBy(el => el?.datasource?.entityName) @@ -361,7 +363,7 @@ export function parseData(input: DatasourceData[]): FormattedData[] { export function parseArray(input: DatasourceData[]): FormattedData[][] { return _(input).groupBy(el => el?.datasource?.entityName) - .values().value().map((entityArray, dsIndex) => + .values().value().map((entityArray) => entityArray[0].data.map((el, i) => { const obj: FormattedData = { entityName: entityArray[0]?.datasource?.entityName, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts index f5f7663c39..4796956fa6 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/markers.ts @@ -81,7 +81,7 @@ export class Marker { } updateMarkerTooltip(data: FormattedData) { - if(!this.map.markerTooltipText || this.settings.useTooltipFunction) { + if (!this.map.markerTooltipText || this.settings.useTooltipFunction) { const pattern = this.settings.useTooltipFunction ? safeExecute(this.settings.tooltipFunction, [this.data, this.dataSources, this.data.dsIndex]) : this.settings.tooltipPattern; this.map.markerTooltipText = parseWithTranslation.prepareProcessPattern(pattern, true); @@ -103,7 +103,7 @@ export class Marker { updateMarkerLabel(settings: MarkerSettings) { this.leafletMarker.unbindTooltip(); if (settings.showLabel) { - if(!this.map.markerLabelText || settings.useLabelFunction) { + if (!this.map.markerLabelText || settings.useLabelFunction) { const pattern = settings.useLabelFunction ? safeExecute(settings.labelFunction, [this.data, this.dataSources, this.data.dsIndex]) : settings.label; this.map.markerLabelText = parseWithTranslation.prepareProcessPattern(pattern, true); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts index 94a9b30d22..dc2361a5fc 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/polygon.ts @@ -55,7 +55,7 @@ export class Polygon { this.leafletPoly.on('click', (event: LeafletMouseEvent) => { for (const action in this.settings.polygonClick) { if (typeof (this.settings.polygonClick[action]) === 'function') { - this.settings.polygonClick[action](event.originalEvent, polyData.datasource); + this.settings.polygonClick[action](event.originalEvent, polyData.$datasource); } } }); @@ -70,18 +70,19 @@ export class Polygon { } updatePolygon(data: FormattedData, dataSources: FormattedData[], settings: PolygonSettings) { - this.data = data; - this.dataSources = dataSources; - if (settings.editablePolygon) { - this.leafletPoly.disableEdit(); - } - this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]); + this.data = data; + this.dataSources = dataSources; + if (settings.editablePolygon) { + this.leafletPoly.disableEdit(); + } + this.leafletPoly.setLatLngs(data[this.settings.polygonKeyName]); if (settings.editablePolygon) { this.leafletPoly.enableEdit(this.map); } - if (settings.showPolygonTooltip) - this.updateTooltip(this.data); - this.updatePolygonColor(settings); + if (settings.showPolygonTooltip) { + this.updateTooltip(this.data); + } + this.updatePolygonColor(settings); } removePolygon() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts index 6521257be5..8c4997933c 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/polyline.ts @@ -57,7 +57,7 @@ export class Polyline { }) } ] - } + }; } updatePolyline(locations: L.LatLng[], data: FormattedData, dataSources: FormattedData[], settings: PolylineSettings) { @@ -65,8 +65,9 @@ export class Polyline { this.dataSources = dataSources; this.leafletPoly.setLatLngs(locations); this.leafletPoly.setStyle(this.getPolyStyle(settings)); - if (this.polylineDecorator) + if (this.polylineDecorator) { this.polylineDecorator.setPaths(this.leafletPoly); + } } getPolyStyle(settings: PolylineSettings): L.PolylineOptions { @@ -78,7 +79,7 @@ export class Polyline { [this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity), weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction, [this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight) - } + }; } removePolyline() { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts index 81313bc4ec..94fa1a09ac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/google-map.ts @@ -49,7 +49,7 @@ export class GoogleMap extends LeafletMap { private loadGoogle(callback, apiKey = 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q') { if (gmGlobals[apiKey]) { - callback() + callback(); } else { this.resource.loadResource(`https://maps.googleapis.com/maps/api/js?key=${apiKey}`).subscribe( () => { diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts index f289fcfeed..1b20ddad01 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/image-map.ts @@ -26,7 +26,7 @@ import { DataKeyType } from '@shared/models/telemetry/telemetry.models'; import { WidgetSubscriptionOptions } from '@core/api/widget-api.models'; import { isDefinedAndNotNull, isEmptyStr } from '@core/utils'; -const maxZoom = 4;// ? +const maxZoom = 4; // ? export class ImageMap extends LeafletMap { @@ -162,52 +162,64 @@ export class ImageMap extends LeafletMap { } onResize(updateImage?: boolean) { - let width = this.$container.clientWidth; - if (width > 0 && this.aspect) { - let height = width / this.aspect; - const imageMapHeight = this.$container.clientHeight; - if (imageMapHeight > 0 && height > imageMapHeight) { - height = imageMapHeight; - width = height * this.aspect; + let width = this.$container.clientWidth; + if (width > 0 && this.aspect) { + let height = width / this.aspect; + const imageMapHeight = this.$container.clientHeight; + if (imageMapHeight > 0 && height > imageMapHeight) { + height = imageMapHeight; + width = height * this.aspect; + } + width *= maxZoom; + const prevWidth = this.width; + const prevHeight = this.height; + if (this.width !== width || updateImage) { + this.width = width; + this.height = width / this.aspect; + if (!this.map) { + this.initMap(updateImage); + } else { + const lastCenterPos = this.latLngToPoint(this.map.getCenter()); + lastCenterPos.x /= prevWidth; + lastCenterPos.y /= prevHeight; + this.updateBounds(updateImage, lastCenterPos); + this.map.invalidateSize(true); + this.updateMarkers(this.markersData); + if (this.options.draggableMarker && this.addMarkers.length) { + this.addMarkers.forEach((marker) => { + const prevPoint = this.convertToCustomFormat(marker.getLatLng(), prevWidth, prevHeight); + marker.setLatLng(this.convertPosition(prevPoint)); + }); } - width *= maxZoom; - const prevWidth = this.width; - const prevHeight = this.height; - if (this.width !== width || updateImage) { - this.width = width; - this.height = width / this.aspect; - if (!this.map) { - this.initMap(updateImage); - } else { - const lastCenterPos = this.latLngToPoint(this.map.getCenter()); - lastCenterPos.x /= prevWidth; - lastCenterPos.y /= prevHeight; - this.updateBounds(updateImage, lastCenterPos); - this.map.invalidateSize(true); - this.updateMarkers(this.markersData); - this.updatePolygons(this.polygonsData); - } + this.updatePolygons(this.polygonsData); + if (this.options.showPolygon && this.options.editablePolygon && this.addPolygons.length) { + this.addPolygons.forEach((polygon) => { + const prevPolygonPoint = this.convertToPolygonFormat(polygon.getLatLngs(), prevWidth, prevHeight); + polygon.setLatLngs(this.convertPositionPolygon(prevPolygonPoint)); + }); } + } } + } } fitBounds(bounds: LatLngBounds, padding?: LatLngTuple) { } initMap(updateImage?: boolean) { - if (!this.map && this.aspect > 0) { - const center = this.pointToLatLng(this.width / 2, this.height / 2); - this.map = L.map(this.$container, { - minZoom: 1, - maxZoom, - scrollWheelZoom: !this.options.disableScrollZooming, - center, - zoom: 1, - crs: L.CRS.Simple, - attributionControl: false, - editable: !!this.options.editablePolygon - }); - this.updateBounds(updateImage); - } + if (!this.map && this.aspect > 0) { + const center = this.pointToLatLng(this.width / 2, this.height / 2); + this.map = L.map(this.$container, { + minZoom: 1, + maxZoom, + scrollWheelZoom: !this.options.disableScrollZooming, + center, + zoom: 1, + crs: L.CRS.Simple, + attributionControl: false, + editable: !!this.options.editablePolygon + }); + this.updateBounds(updateImage); + } } convertPosition(expression): L.LatLng { @@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap { if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) { return this.pointToLatLng( el[0] * this.width, - el[1] * this.height) + el[1] * this.height + ); } else if (Array.isArray(el) && el.length) { return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]); } else { return null; } - }).filter(el => !!el) + }).filter(el => !!el); } pointToLatLng(x, y): L.LatLng { @@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap { return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1); } - convertToCustomFormat(position: L.LatLng): object { - const point = this.latLngToPoint(position); - return { - [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width), - [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height) - } + convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object { + const point = this.latLngToPoint(position); + return { + [this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width), + [this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height) + }; } - convertToPolygonFormat(points: Array): Array { + convertToPolygonFormat(points: Array, width = this.width, height = this.height): Array { if (points.length) { - return points.map(point=> { + return points.map(point => { if (point.length) { - return this.convertToPolygonFormat(point); + return this.convertToPolygonFormat(point, width, height); } else { const pos = this.latLngToPoint(point); - return [calculateNewPointCoordinate(pos.x, this.width), calculateNewPointCoordinate(pos.y, this.height)]; + return [calculateNewPointCoordinate(pos.x, width), calculateNewPointCoordinate(pos.y, height)]; } - }) + }); } else { - return [] + return []; } } convertPolygonToCustomFormat(expression: any[][]): object { return { [this.options.polygonKeyName] : this.convertToPolygonFormat(expression) - } + }; } } diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts index c9e7bbe8f9..9c6bb63ddf 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/index.ts @@ -29,16 +29,16 @@ import LeafletMap from '@home/components/widget/lib/maps/leaflet-map'; import { JsonSettingsSchema } from '@shared/models/widget.models'; interface IProvider { - MapClass: Type, - schema: JsonSettingsSchema, - name: string + MapClass: Type; + schema: JsonSettingsSchema; + name: string; } export const providerSets: { [key: string]: IProvider } = { 'openstreet-map': { MapClass: OpenStreetMap, schema: openstreetMapSettingsSchema, - name: 'openstreet-map', + name: 'openstreet-map' }, 'tencent-map': { MapClass: TencentMap, diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts index 21814c19ad..f4f10a0dac 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/providers/openstreet-map.ts @@ -26,10 +26,11 @@ export class OpenStreetMap extends LeafletMap { editable: !!options.editablePolygon }).setView(options?.defaultCenterPosition, options?.defaultZoomLevel); let tileLayer; - if (options.useCustomProvider) - tileLayer = L.tileLayer(options.customProviderTileUrl); - else - tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik'); + if (options.useCustomProvider) { + tileLayer = L.tileLayer(options.customProviderTileUrl); + } else { + tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik'); + } tileLayer.addTo(map); super.initSettings(options); super.setMap(map); diff --git a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts b/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts index 66841fb5b6..3506978c4a 100644 --- a/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts +++ b/ui-ngx/src/app/modules/home/components/widget/lib/maps/schemes.ts @@ -1068,31 +1068,31 @@ export const tripAnimationSchema = { key: 'labelFunction', type: 'javascript' }, 'showTooltip', { - key: 'tooltipColor', - type: 'color' - }, { - key: 'tooltipFontColor', - type: 'color' - }, 'tooltipOpacity', { - key: 'tooltipPattern', - type: 'textarea' - }, 'useTooltipFunction', { - key: 'tooltipFunction', - type: 'javascript' - }, 'autocloseTooltip', { - key: 'markerImage', - type: 'image' - }, 'markerImageSize', 'rotationAngle', 'useMarkerImageFunction', - { - key: 'markerImageFunction', - type: 'javascript' - }, { - key: 'markerImages', - items: [ - { - key: 'markerImages[]', - type: 'image' - } - ] - }] -} + key: 'tooltipColor', + type: 'color' + }, { + key: 'tooltipFontColor', + type: 'color' + }, 'tooltipOpacity', { + key: 'tooltipPattern', + type: 'textarea' + }, 'useTooltipFunction', { + key: 'tooltipFunction', + type: 'javascript' + }, 'autocloseTooltip', { + key: 'markerImage', + type: 'image' + }, 'markerImageSize', 'rotationAngle', 'useMarkerImageFunction', + { + key: 'markerImageFunction', + type: 'javascript' + }, { + key: 'markerImages', + items: [ + { + key: 'markerImages[]', + type: 'image' + } + ] + }] +}; diff --git a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts index ffc2423d81..e3ac7f0a8f 100644 --- a/ui-ngx/src/app/modules/home/components/widget/widget.component.ts +++ b/ui-ngx/src/app/modules/home/components/widget/widget.component.ts @@ -35,7 +35,6 @@ import { } from '@angular/core'; import { DashboardWidget } from '@home/models/dashboard-component.models'; import { - Datasource, defaultLegendConfig, LegendConfig, LegendData, @@ -55,7 +54,7 @@ import { AppState } from '@core/core.state'; import { WidgetService } from '@core/http/widget.service'; import { UtilsService } from '@core/services/utils.service'; import { forkJoin, Observable, of, ReplaySubject, Subscription, throwError } from 'rxjs'; -import { deepClone, isDefined, objToBase64 } from '@core/utils'; +import { deepClone, isDefined, objToBase64URI } from '@core/utils'; import { IDynamicWidgetComponent, WidgetContext, @@ -68,7 +67,8 @@ import { StateObject, StateParams, SubscriptionEntityInfo, - SubscriptionInfo, SubscriptionMessage, + SubscriptionInfo, + SubscriptionMessage, WidgetSubscriptionContext, WidgetSubscriptionOptions } from '@core/api/widget-api.models'; @@ -80,11 +80,9 @@ import { catchError, switchMap } from 'rxjs/operators'; import { ActionNotificationShow } from '@core/notification/notification.actions'; import { TimeService } from '@core/services/time.service'; import { DeviceService } from '@app/core/http/device.service'; -import { AlarmService } from '@app/core/http/alarm.service'; import { ExceptionData } from '@shared/models/error.models'; import { WidgetComponentService } from './widget-component.service'; import { Timewindow } from '@shared/models/time/time.models'; -import { AlarmSearchStatus } from '@shared/models/alarm.models'; import { CancelAnimationFrame, RafService } from '@core/services/raf.service'; import { DashboardService } from '@core/http/dashboard.service'; import { WidgetSubscription } from '@core/api/widget-subscription'; @@ -688,7 +686,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI private destroyDynamicWidgetComponent() { if (this.widgetContext.$containerParent && this.widgetResize$) { - this.widgetResize$.disconnect() + this.widgetResize$.disconnect(); } if (this.dynamicWidgetComponentRef) { this.dynamicWidgetComponentRef.destroy(); @@ -1023,7 +1021,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI if (targetDashboardStateId) { stateObject.id = targetDashboardStateId; } - const state = objToBase64([ stateObject ]); + const state = objToBase64URI([ stateObject ]); const isSinglePage = this.route.snapshot.data.singlePageMode; let url; if (isSinglePage) { diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.ts b/ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.ts index 348f8db3fe..00863cd18e 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.ts +++ b/ui-ngx/src/app/modules/home/pages/dashboard/states/default-state-controller.component.ts @@ -23,7 +23,7 @@ import { StateControllerComponent } from './state-controller.component'; import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service'; import { EntityId } from '@app/shared/models/id/entity-id'; import { UtilsService } from '@core/services/utils.service'; -import { base64toObj, objToBase64 } from '@app/core/utils'; +import { base64toObj, objToBase64URI } from '@app/core/utils'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { EntityService } from '@core/http/entity.service'; @@ -237,7 +237,7 @@ export class DefaultStateControllerComponent extends StateControllerComponent im private updateLocation() { if (this.stateObject[0].id) { - const newState = objToBase64(this.stateObject); + const newState = objToBase64URI(this.stateObject); this.updateStateParam(newState); } } diff --git a/ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.ts b/ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.ts index 7a79736d3f..295dc57730 100644 --- a/ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.ts +++ b/ui-ngx/src/app/modules/home/pages/dashboard/states/entity-state-controller.component.ts @@ -23,7 +23,7 @@ import { StateControllerComponent } from './state-controller.component'; import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service'; import { EntityId } from '@app/shared/models/id/entity-id'; import { UtilsService } from '@core/services/utils.service'; -import { base64toObj, insertVariable, isEmpty, objToBase64 } from '@app/core/utils'; +import { base64toObj, insertVariable, isEmpty, objToBase64URI } from '@app/core/utils'; import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; import { EntityService } from '@core/http/entity.service'; import { EntityType } from '@shared/models/entity-type.models'; @@ -281,7 +281,7 @@ export class EntityStateControllerComponent extends StateControllerComponent imp if (this.isDefaultState()) { newState = null; } else { - newState = objToBase64(this.stateObject); + newState = objToBase64URI(this.stateObject); } this.updateStateParam(newState); } diff --git a/ui-ngx/yarn.lock b/ui-ngx/yarn.lock index 3bfc3830e9..4aaffa98dd 100644 --- a/ui-ngx/yarn.lock +++ b/ui-ngx/yarn.lock @@ -2138,7 +2138,7 @@ base64-arraybuffer@0.1.5: resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8" integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg= -base64-js@^1.0.2, base64-js@^1.3.1: +base64-js@^1.0.2: version "1.3.1" resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1" integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==