Merge branch 'master' into develop/3.2
This commit is contained in:
commit
3ffda44816
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.controller;
|
package org.thingsboard.server.controller;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
import org.springframework.security.access.prepost.PreAuthorize;
|
import org.springframework.security.access.prepost.PreAuthorize;
|
||||||
import org.springframework.web.bind.annotation.PathVariable;
|
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 {
|
public AdminSettings getAdminSettings(@PathVariable("key") String key) throws ThingsboardException {
|
||||||
try {
|
try {
|
||||||
accessControlService.checkPermission(getCurrentUser(), Resource.ADMIN_SETTINGS, Operation.READ);
|
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) {
|
} catch (Exception e) {
|
||||||
throw handleException(e);
|
throw handleException(e);
|
||||||
}
|
}
|
||||||
@ -74,6 +79,7 @@ public class AdminController extends BaseController {
|
|||||||
adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
|
adminSettings = checkNotNull(adminSettingsService.saveAdminSettings(TenantId.SYS_TENANT_ID, adminSettings));
|
||||||
if (adminSettings.getKey().equals("mail")) {
|
if (adminSettings.getKey().equals("mail")) {
|
||||||
mailService.updateMailConfiguration();
|
mailService.updateMailConfiguration();
|
||||||
|
((ObjectNode) adminSettings.getJsonValue()).put("password", "");
|
||||||
}
|
}
|
||||||
return adminSettings;
|
return adminSettings;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
|||||||
@ -391,8 +391,12 @@ public class BaseAlarmService extends AbstractEntityService implements AlarmServ
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Set<EntityId> getPropagationEntityIds(Alarm alarm) {
|
private Set<EntityId> getPropagationEntityIds(Alarm alarm) {
|
||||||
|
if (alarm.isPropagate()) {
|
||||||
List<EntityRelation> relations = relationService.findByTo(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM);
|
List<EntityRelation> relations = relationService.findByTo(alarm.getTenantId(), alarm.getId(), RelationTypeGroup.ALARM);
|
||||||
return relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet());
|
return relations.stream().map(EntityRelation::getFrom).collect(Collectors.toSet());
|
||||||
|
} else {
|
||||||
|
return Collections.singleton(alarm.getOriginator());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId) {
|
private void createAlarmRelation(TenantId tenantId, EntityId entityId, EntityId alarmId) {
|
||||||
|
|||||||
@ -15,6 +15,7 @@
|
|||||||
*/
|
*/
|
||||||
package org.thingsboard.server.dao.settings;
|
package org.thingsboard.server.dao.settings;
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.node.ObjectNode;
|
||||||
import lombok.extern.slf4j.Slf4j;
|
import lombok.extern.slf4j.Slf4j;
|
||||||
import org.apache.commons.lang3.StringUtils;
|
import org.apache.commons.lang3.StringUtils;
|
||||||
import org.springframework.beans.factory.annotation.Autowired;
|
import org.springframework.beans.factory.annotation.Autowired;
|
||||||
@ -51,6 +52,13 @@ public class AdminSettingsServiceImpl implements AdminSettingsService {
|
|||||||
public AdminSettings saveAdminSettings(TenantId tenantId, AdminSettings adminSettings) {
|
public AdminSettings saveAdminSettings(TenantId tenantId, AdminSettings adminSettings) {
|
||||||
log.trace("Executing saveAdminSettings [{}]", adminSettings);
|
log.trace("Executing saveAdminSettings [{}]", adminSettings);
|
||||||
adminSettingsValidator.validate(adminSettings, data -> tenantId);
|
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);
|
return adminSettingsDao.save(tenantId, adminSettings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -35,13 +35,11 @@
|
|||||||
"@ngrx/effects": "^10.0.0",
|
"@ngrx/effects": "^10.0.0",
|
||||||
"@ngrx/store": "^10.0.0",
|
"@ngrx/store": "^10.0.0",
|
||||||
"@ngrx/store-devtools": "^10.0.0",
|
"@ngrx/store-devtools": "^10.0.0",
|
||||||
"ngx-sharebuttons": "^8.0.1",
|
|
||||||
"@ngx-translate/core": "^13.0.0",
|
"@ngx-translate/core": "^13.0.0",
|
||||||
"@ngx-translate/http-loader": "^6.0.0",
|
"@ngx-translate/http-loader": "^6.0.0",
|
||||||
"ace-builds": "^1.4.12",
|
"ace-builds": "^1.4.12",
|
||||||
"angular-gridster2": "^10.1.3",
|
"angular-gridster2": "^10.1.3",
|
||||||
"angular2-hotkeys": "^2.2.0",
|
"angular2-hotkeys": "^2.2.0",
|
||||||
"base64-js": "^1.3.1",
|
|
||||||
"canvas-gauges": "^2.1.7",
|
"canvas-gauges": "^2.1.7",
|
||||||
"compass-sass-mixins": "^0.12.7",
|
"compass-sass-mixins": "^0.12.7",
|
||||||
"core-js": "^3.6.5",
|
"core-js": "^3.6.5",
|
||||||
@ -70,6 +68,7 @@
|
|||||||
"ngx-daterangepicker-material": "^3.0.4",
|
"ngx-daterangepicker-material": "^3.0.4",
|
||||||
"ngx-flowchart": "git://github.com/thingsboard/ngx-flowchart.git#master",
|
"ngx-flowchart": "git://github.com/thingsboard/ngx-flowchart.git#master",
|
||||||
"ngx-hm-carousel": "^2.0.0-rc.1",
|
"ngx-hm-carousel": "^2.0.0-rc.1",
|
||||||
|
"ngx-sharebuttons": "^8.0.1",
|
||||||
"ngx-translate-messageformat-compiler": "^4.8.0",
|
"ngx-translate-messageformat-compiler": "^4.8.0",
|
||||||
"objectpath": "^2.0.0",
|
"objectpath": "^2.0.0",
|
||||||
"prettier": "^2.0.5",
|
"prettier": "^2.0.5",
|
||||||
|
|||||||
@ -26,7 +26,6 @@ import {
|
|||||||
import { DOCUMENT } from '@angular/common';
|
import { DOCUMENT } from '@angular/common';
|
||||||
import { forkJoin, Observable, ReplaySubject, throwError } from 'rxjs';
|
import { forkJoin, Observable, ReplaySubject, throwError } from 'rxjs';
|
||||||
import { HttpClient } from '@angular/common/http';
|
import { HttpClient } from '@angular/common/http';
|
||||||
import { objToBase64 } from '@core/utils';
|
|
||||||
|
|
||||||
declare const SystemJS;
|
declare const SystemJS;
|
||||||
|
|
||||||
|
|||||||
@ -17,7 +17,6 @@
|
|||||||
import _ from 'lodash';
|
import _ from 'lodash';
|
||||||
import { Observable, Subject } from 'rxjs';
|
import { Observable, Subject } from 'rxjs';
|
||||||
import { finalize, share } from 'rxjs/operators';
|
import { finalize, share } from 'rxjs/operators';
|
||||||
import base64js from 'base64-js';
|
|
||||||
import { Datasource } from '@app/shared/models/widget.models';
|
import { Datasource } from '@app/shared/models/widget.models';
|
||||||
|
|
||||||
const varsRegex = /\${([^}]*)}/g;
|
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 {
|
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);
|
let formatted: string | number = Number(value);
|
||||||
if (isDefinedAndNotNull(dec)) {
|
if (isDefinedAndNotNull(dec)) {
|
||||||
formatted = formatted.toFixed(dec);
|
formatted = formatted.toFixed(dec);
|
||||||
@ -164,30 +164,23 @@ export function deleteNullProperties(obj: any) {
|
|||||||
|
|
||||||
export function objToBase64(obj: any): string {
|
export function objToBase64(obj: any): string {
|
||||||
const json = JSON.stringify(obj);
|
const json = JSON.stringify(obj);
|
||||||
const encoded = utf8Encode(json);
|
return btoa(encodeURIComponent(json).replace(/%([0-9A-F]{2})/g,
|
||||||
return base64js.fromByteArray(encoded);
|
function toSolidBytes(match, p1) {
|
||||||
|
return String.fromCharCode(Number('0x' + p1));
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
|
export function objToBase64URI(obj: any): string {
|
||||||
|
return encodeURIComponent(objToBase64(obj));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function base64toObj(b64Encoded: string): any {
|
export function base64toObj(b64Encoded: string): any {
|
||||||
const encoded: Uint8Array | number[] = base64js.toByteArray(b64Encoded);
|
const json = decodeURIComponent(atob(b64Encoded).split('').map((c) => {
|
||||||
const json = utf8Decode(encoded);
|
return '%' + ('00' + c.charCodeAt(0).toString(16)).slice(-2);
|
||||||
|
}).join(''));
|
||||||
return JSON.parse(json);
|
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
function utf8Decode(bytes: Uint8Array | number[]): string {
|
|
||||||
return utf8Slice(bytes, 0, bytes.length);
|
|
||||||
}
|
|
||||||
|
|
||||||
const scrollRegex = /(auto|scroll)/;
|
const scrollRegex = /(auto|scroll)/;
|
||||||
|
|
||||||
function parentNodes(node: Node, nodes: Node[]): Node[] {
|
function parentNodes(node: Node, nodes: Node[]): Node[] {
|
||||||
@ -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<T>(target: T, ignoreFields?: string[]): T {
|
export function deepClone<T>(target: T, ignoreFields?: string[]): T {
|
||||||
if (target === null) {
|
if (target === null) {
|
||||||
return target;
|
return target;
|
||||||
|
|||||||
@ -24,7 +24,7 @@ import { Router } from '@angular/router';
|
|||||||
import { DialogComponent } from '@app/shared/components/dialog.component';
|
import { DialogComponent } from '@app/shared/components/dialog.component';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { Dashboard, DashboardLayoutId } from '@app/shared/models/dashboard.models';
|
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 { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||||
import { EntityId } from '@app/shared/models/id/entity-id';
|
import { EntityId } from '@app/shared/models/id/entity-id';
|
||||||
import { Widget } from '@app/shared/models/widget.models';
|
import { Widget } from '@app/shared/models/widget.models';
|
||||||
@ -205,7 +205,7 @@ export class AddWidgetToDashboardDialogComponent extends
|
|||||||
id: targetState,
|
id: targetState,
|
||||||
params: {}
|
params: {}
|
||||||
};
|
};
|
||||||
const state = objToBase64([ stateObject ]);
|
const state = objToBase64URI([ stateObject ]);
|
||||||
url = `/dashboards/${theDashboard.id.id}?state=${state}`;
|
url = `/dashboards/${theDashboard.id.id}?state=${state}`;
|
||||||
} else {
|
} else {
|
||||||
url = `/dashboards/${theDashboard.id.id}`;
|
url = `/dashboards/${theDashboard.id.id}`;
|
||||||
|
|||||||
@ -30,6 +30,7 @@ import 'leaflet.markercluster/dist/leaflet.markercluster';
|
|||||||
import {
|
import {
|
||||||
defaultSettings,
|
defaultSettings,
|
||||||
FormattedData,
|
FormattedData,
|
||||||
|
MapProviders,
|
||||||
MapSettings,
|
MapSettings,
|
||||||
MarkerSettings,
|
MarkerSettings,
|
||||||
PolygonSettings,
|
PolygonSettings,
|
||||||
@ -74,6 +75,8 @@ export default abstract class LeafletMap {
|
|||||||
drawRoutes: boolean;
|
drawRoutes: boolean;
|
||||||
showPolygon: boolean;
|
showPolygon: boolean;
|
||||||
updatePending = false;
|
updatePending = false;
|
||||||
|
addMarkers: L.Marker[] = [];
|
||||||
|
addPolygons: L.Polygon[] = [];
|
||||||
|
|
||||||
protected constructor(public ctx: WidgetContext,
|
protected constructor(public ctx: WidgetContext,
|
||||||
public $container: HTMLElement,
|
public $container: HTMLElement,
|
||||||
@ -133,6 +136,7 @@ export default abstract class LeafletMap {
|
|||||||
shadowSize: [41, 41]
|
shadowSize: [41, 41]
|
||||||
});
|
});
|
||||||
const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
|
const newMarker = L.marker(mousePositionOnMap, { icon }).addTo(this.map);
|
||||||
|
this.addMarkers.push(newMarker);
|
||||||
const datasourcesList = document.createElement('div');
|
const datasourcesList = document.createElement('div');
|
||||||
const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
|
const customLatLng = this.convertToCustomFormat(mousePositionOnMap);
|
||||||
const header = document.createElement('p');
|
const header = document.createElement('p');
|
||||||
@ -147,10 +151,14 @@ export default abstract class LeafletMap {
|
|||||||
const updatedEnttity = { ...ds, ...customLatLng };
|
const updatedEnttity = { ...ds, ...customLatLng };
|
||||||
this.saveMarkerLocation(updatedEnttity).subscribe(() => {
|
this.saveMarkerLocation(updatedEnttity).subscribe(() => {
|
||||||
this.map.removeLayer(newMarker);
|
this.map.removeLayer(newMarker);
|
||||||
|
const markerIndex = this.addMarkers.indexOf(newMarker);
|
||||||
|
if (markerIndex > -1) {
|
||||||
|
this.addMarkers.splice(markerIndex, 1);
|
||||||
|
}
|
||||||
this.deleteMarker(ds.entityName);
|
this.deleteMarker(ds.entityName);
|
||||||
this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
|
this.createMarker(ds.entityName, updatedEnttity, this.datasources, this.options);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
datasourcesList.append(dsItem);
|
datasourcesList.append(dsItem);
|
||||||
});
|
});
|
||||||
datasourcesList.append(document.createElement('br'));
|
datasourcesList.append(document.createElement('br'));
|
||||||
@ -158,14 +166,18 @@ export default abstract class LeafletMap {
|
|||||||
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
||||||
deleteBtn.onclick = () => {
|
deleteBtn.onclick = () => {
|
||||||
this.map.removeLayer(newMarker);
|
this.map.removeLayer(newMarker);
|
||||||
|
const markerIndex = this.addMarkers.indexOf(newMarker);
|
||||||
|
if (markerIndex > -1) {
|
||||||
|
this.addMarkers.splice(markerIndex, 1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
datasourcesList.append(deleteBtn);
|
datasourcesList.append(deleteBtn);
|
||||||
const popup = L.popup();
|
const popup = L.popup();
|
||||||
popup.setContent(datasourcesList);
|
popup.setContent(datasourcesList);
|
||||||
newMarker.bindPopup(popup).openPopup();
|
newMarker.bindPopup(popup).openPopup();
|
||||||
}
|
}
|
||||||
addMarker.setPosition('topright')
|
addMarker.setPosition('topright');
|
||||||
}
|
};
|
||||||
L.Control.AddMarker = L.Control.extend({
|
L.Control.AddMarker = L.Control.extend({
|
||||||
onAdd() {
|
onAdd() {
|
||||||
const img = L.DomUtil.create('img') as any;
|
const img = L.DomUtil.create('img') as any;
|
||||||
@ -177,7 +189,7 @@ export default abstract class LeafletMap {
|
|||||||
img.draggable = true;
|
img.draggable = true;
|
||||||
const draggableImg = new L.Draggable(img);
|
const draggableImg = new L.Draggable(img);
|
||||||
draggableImg.enable();
|
draggableImg.enable();
|
||||||
draggableImg.on('dragend', dragListener)
|
draggableImg.on('dragend', dragListener);
|
||||||
return img;
|
return img;
|
||||||
},
|
},
|
||||||
onRemove() {
|
onRemove() {
|
||||||
@ -186,7 +198,7 @@ export default abstract class LeafletMap {
|
|||||||
} as any);
|
} as any);
|
||||||
L.control.addMarker = (opts) => {
|
L.control.addMarker = (opts) => {
|
||||||
return new L.Control.AddMarker(opts);
|
return new L.Control.AddMarker(opts);
|
||||||
}
|
};
|
||||||
addMarker = L.control.addMarker({ position: 'topright' }).addTo(this.map);
|
addMarker = L.control.addMarker({ position: 'topright' }).addTo(this.map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -196,14 +208,16 @@ export default abstract class LeafletMap {
|
|||||||
let mousePositionOnMap: L.LatLng[];
|
let mousePositionOnMap: L.LatLng[];
|
||||||
let addPolygon: L.Control;
|
let addPolygon: L.Control;
|
||||||
this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
|
this.map.on('mousemove', (e: L.LeafletMouseEvent) => {
|
||||||
|
const polygonOffset = this.options.provider === MapProviders.image ? 10 : 0.01;
|
||||||
const latlng1 = e.latlng;
|
const latlng1 = e.latlng;
|
||||||
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + 10);
|
const latlng2 = L.latLng(e.latlng.lat, e.latlng.lng + polygonOffset);
|
||||||
const latlng3 = L.latLng(e.latlng.lat-10, e.latlng.lng);
|
const latlng3 = L.latLng(e.latlng.lat - polygonOffset, e.latlng.lng);
|
||||||
mousePositionOnMap = [latlng1, latlng2, latlng3];
|
mousePositionOnMap = [latlng1, latlng2, latlng3];
|
||||||
});
|
});
|
||||||
const dragListener = (e: L.DragEndEvent) => {
|
const dragListener = (e: L.DragEndEvent) => {
|
||||||
if (e.type === 'dragend' && mousePositionOnMap) {
|
if (e.type === 'dragend' && mousePositionOnMap) {
|
||||||
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
|
const newPolygon = L.polygon(mousePositionOnMap).addTo(this.map);
|
||||||
|
this.addPolygons.push(newPolygon);
|
||||||
const datasourcesList = document.createElement('div');
|
const datasourcesList = document.createElement('div');
|
||||||
const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
|
const customLatLng = {[this.options.polygonKeyName]: this.convertToPolygonFormat(mousePositionOnMap)};
|
||||||
const header = document.createElement('p');
|
const header = document.createElement('p');
|
||||||
@ -218,9 +232,13 @@ export default abstract class LeafletMap {
|
|||||||
const updatedEnttity = { ...ds, ...customLatLng };
|
const updatedEnttity = { ...ds, ...customLatLng };
|
||||||
this.savePolygonLocation(updatedEnttity).subscribe(() => {
|
this.savePolygonLocation(updatedEnttity).subscribe(() => {
|
||||||
this.map.removeLayer(newPolygon);
|
this.map.removeLayer(newPolygon);
|
||||||
|
const polygonIndex = this.addPolygons.indexOf(newPolygon);
|
||||||
|
if (polygonIndex > -1) {
|
||||||
|
this.addPolygons.splice(polygonIndex, 1);
|
||||||
|
}
|
||||||
this.deletePolygon(ds.entityName);
|
this.deletePolygon(ds.entityName);
|
||||||
});
|
});
|
||||||
}
|
};
|
||||||
datasourcesList.append(dsItem);
|
datasourcesList.append(dsItem);
|
||||||
});
|
});
|
||||||
datasourcesList.append(document.createElement('br'));
|
datasourcesList.append(document.createElement('br'));
|
||||||
@ -228,14 +246,18 @@ export default abstract class LeafletMap {
|
|||||||
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
deleteBtn.appendChild(document.createTextNode('Discard changes'));
|
||||||
deleteBtn.onclick = () => {
|
deleteBtn.onclick = () => {
|
||||||
this.map.removeLayer(newPolygon);
|
this.map.removeLayer(newPolygon);
|
||||||
|
const polygonIndex = this.addPolygons.indexOf(newPolygon);
|
||||||
|
if (polygonIndex > -1) {
|
||||||
|
this.addPolygons.splice(polygonIndex, 1);
|
||||||
}
|
}
|
||||||
|
};
|
||||||
datasourcesList.append(deleteBtn);
|
datasourcesList.append(deleteBtn);
|
||||||
const popup = L.popup();
|
const popup = L.popup();
|
||||||
popup.setContent(datasourcesList);
|
popup.setContent(datasourcesList);
|
||||||
newPolygon.bindPopup(popup).openPopup();
|
newPolygon.bindPopup(popup).openPopup();
|
||||||
}
|
}
|
||||||
addPolygon.setPosition('topright')
|
addPolygon.setPosition('topright');
|
||||||
}
|
};
|
||||||
L.Control.AddPolygon = L.Control.extend({
|
L.Control.AddPolygon = L.Control.extend({
|
||||||
onAdd() {
|
onAdd() {
|
||||||
const img = L.DomUtil.create('img') as any;
|
const img = L.DomUtil.create('img') as any;
|
||||||
@ -247,7 +269,7 @@ export default abstract class LeafletMap {
|
|||||||
img.draggable = true;
|
img.draggable = true;
|
||||||
const draggableImg = new L.Draggable(img);
|
const draggableImg = new L.Draggable(img);
|
||||||
draggableImg.enable();
|
draggableImg.enable();
|
||||||
draggableImg.on('dragend', dragListener)
|
draggableImg.on('dragend', dragListener);
|
||||||
return img;
|
return img;
|
||||||
},
|
},
|
||||||
onRemove() {
|
onRemove() {
|
||||||
@ -256,7 +278,7 @@ export default abstract class LeafletMap {
|
|||||||
} as any);
|
} as any);
|
||||||
L.control.addPolygon = (opts) => {
|
L.control.addPolygon = (opts) => {
|
||||||
return new L.Control.AddPolygon(opts);
|
return new L.Control.AddPolygon(opts);
|
||||||
}
|
};
|
||||||
addPolygon = L.control.addPolygon({ position: 'topright' }).addTo(this.map);
|
addPolygon = L.control.addPolygon({ position: 'topright' }).addTo(this.map);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,8 +304,9 @@ export default abstract class LeafletMap {
|
|||||||
if (this.options.useDefaultCenterPosition) {
|
if (this.options.useDefaultCenterPosition) {
|
||||||
this.map.panTo(this.options.defaultCenterPosition);
|
this.map.panTo(this.options.defaultCenterPosition);
|
||||||
this.bounds = map.getBounds();
|
this.bounds = map.getBounds();
|
||||||
|
} else {
|
||||||
|
this.bounds = new L.LatLngBounds(null, null);
|
||||||
}
|
}
|
||||||
else this.bounds = new L.LatLngBounds(null, null);
|
|
||||||
if (this.options.draggableMarker) {
|
if (this.options.draggableMarker) {
|
||||||
this.addMarkerControl();
|
this.addMarkerControl();
|
||||||
}
|
}
|
||||||
@ -299,11 +322,11 @@ export default abstract class LeafletMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public saveMarkerLocation(_e: FormattedData, lat?: number, lng?: number): Observable<any> {
|
public saveMarkerLocation(datasource: FormattedData, lat?: number, lng?: number): Observable<any> {
|
||||||
return of(null);
|
return of(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
public savePolygonLocation(_e: FormattedData, coordinates?: Array<[number, number]>): Observable<any> {
|
public savePolygonLocation(datasource: FormattedData, coordinates?: Array<[number, number]>): Observable<any> {
|
||||||
return of(null);
|
return of(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -364,7 +387,9 @@ export default abstract class LeafletMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
convertPosition(expression: object): L.LatLng {
|
convertPosition(expression: object): L.LatLng {
|
||||||
if (!expression) return null;
|
if (!expression) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
const lat = expression[this.options.latKeyName];
|
const lat = expression[this.options.latKeyName];
|
||||||
const lng = expression[this.options.lngKeyName];
|
const lng = expression[this.options.lngKeyName];
|
||||||
if (!isDefinedAndNotNull(lat) || isString(lat) || isNaN(lat) || !isDefinedAndNotNull(lng) || isString(lng) || isNaN(lng)) {
|
if (!isDefinedAndNotNull(lat) || isString(lat) || isNaN(lat) || !isDefinedAndNotNull(lng) || isString(lng) || isNaN(lng)) {
|
||||||
@ -382,14 +407,14 @@ export default abstract class LeafletMap {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).filter(el => !!el)
|
}).filter(el => !!el);
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToCustomFormat(position: L.LatLng): object {
|
convertToCustomFormat(position: L.LatLng): object {
|
||||||
return {
|
return {
|
||||||
[this.options.latKeyName]: position.lat % 90,
|
[this.options.latKeyName]: position.lat % 90,
|
||||||
[this.options.lngKeyName]: position.lng % 180
|
[this.options.lngKeyName]: position.lng % 180
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToPolygonFormat(points: Array<any>): Array<any> {
|
convertToPolygonFormat(points: Array<any>): Array<any> {
|
||||||
@ -400,16 +425,16 @@ export default abstract class LeafletMap {
|
|||||||
} else {
|
} else {
|
||||||
return [point.lat, point.lng];
|
return [point.lat, point.lng];
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
} else {
|
} else {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convertPolygonToCustomFormat(expression: any[][]): object {
|
convertPolygonToCustomFormat(expression: any[][]): object {
|
||||||
return {
|
return {
|
||||||
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
updateData(drawRoutes: boolean, showPolygon: boolean) {
|
updateData(drawRoutes: boolean, showPolygon: boolean) {
|
||||||
@ -509,7 +534,7 @@ export default abstract class LeafletMap {
|
|||||||
this.markersCluster.addLayers(createdMarkers.map(marker => marker.leafletMarker));
|
this.markersCluster.addLayers(createdMarkers.map(marker => marker.leafletMarker));
|
||||||
}
|
}
|
||||||
if (updatedMarkers.length) {
|
if (updatedMarkers.length) {
|
||||||
this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker))
|
this.markersCluster.refreshClusters(updatedMarkers.map(marker => marker.leafletMarker));
|
||||||
}
|
}
|
||||||
if (deletedMarkers.length) {
|
if (deletedMarkers.length) {
|
||||||
this.markersCluster.removeLayers(deletedMarkers.map(marker => marker.leafletMarker));
|
this.markersCluster.removeLayers(deletedMarkers.map(marker => marker.leafletMarker));
|
||||||
@ -518,7 +543,9 @@ export default abstract class LeafletMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dragMarker = (e, data = {} as FormattedData) => {
|
dragMarker = (e, data = {} as FormattedData) => {
|
||||||
if (e.type !== 'dragend') return;
|
if (e.type !== 'dragend') {
|
||||||
|
return;
|
||||||
|
}
|
||||||
this.saveMarkerLocation({ ...data, ...this.convertToCustomFormat(e.target._latlng) }).subscribe();
|
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);
|
const newMarker = new Marker(this, this.convertPosition(data), settings, data, dataSources, this.dragMarker);
|
||||||
if (callback) {
|
if (callback) {
|
||||||
newMarker.leafletMarker.on('click', () => {
|
newMarker.leafletMarker.on('click', () => {
|
||||||
callback(data, true)
|
callback(data, true);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
if (this.bounds && updateBounds && !(this.options as MarkerSettings).useClusterMarkers) {
|
if (this.bounds && updateBounds && !(this.options as MarkerSettings).useClusterMarkers) {
|
||||||
@ -565,11 +592,10 @@ export default abstract class LeafletMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
deletePolygon(key: string) {
|
deletePolygon(key: string) {
|
||||||
let polygon = this.polygons.get(key)?.leafletPoly;
|
const polygon = this.polygons.get(key)?.leafletPoly;
|
||||||
if (polygon) {
|
if (polygon) {
|
||||||
this.map.removeLayer(polygon);
|
this.map.removeLayer(polygon);
|
||||||
this.polygons.delete(key);
|
this.polygons.delete(key);
|
||||||
polygon = null;
|
|
||||||
}
|
}
|
||||||
return polygon;
|
return polygon;
|
||||||
}
|
}
|
||||||
@ -684,7 +710,9 @@ export default abstract class LeafletMap {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dragPolygonVertex = (e?, data = {} as FormattedData) => {
|
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();
|
this.savePolygonLocation({ ...data, ...this.convertPolygonToCustomFormat(e.layer._latlngs) }).subscribe();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -62,7 +62,7 @@ export type MapSettings = {
|
|||||||
useCustomProvider: boolean,
|
useCustomProvider: boolean,
|
||||||
customProviderTileUrl: string;
|
customProviderTileUrl: string;
|
||||||
mapPageSize: number;
|
mapPageSize: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export enum MapProviders {
|
export enum MapProviders {
|
||||||
google = 'google-map',
|
google = 'google-map',
|
||||||
@ -103,7 +103,7 @@ export type MarkerSettings = {
|
|||||||
markerImageFunction?: MarkerImageFunction;
|
markerImageFunction?: MarkerImageFunction;
|
||||||
markerOffsetX: number;
|
markerOffsetX: number;
|
||||||
markerOffsetY: number;
|
markerOffsetY: number;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface FormattedData {
|
export interface FormattedData {
|
||||||
$datasource: Datasource;
|
$datasource: Datasource;
|
||||||
@ -112,13 +112,13 @@ export interface FormattedData {
|
|||||||
entityType: EntityType;
|
entityType: EntityType;
|
||||||
dsIndex: number;
|
dsIndex: number;
|
||||||
deviceType: string;
|
deviceType: string;
|
||||||
[key: string]: any
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface ReplaceInfo {
|
export interface ReplaceInfo {
|
||||||
variable: string;
|
variable: string;
|
||||||
valDec?: number;
|
valDec?: number;
|
||||||
dataKeyName: string
|
dataKeyName: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type PolygonSettings = {
|
export type PolygonSettings = {
|
||||||
@ -141,7 +141,7 @@ export type PolygonSettings = {
|
|||||||
polygonTooltipFunction: GenericFunction;
|
polygonTooltipFunction: GenericFunction;
|
||||||
polygonColorFunction?: GenericFunction;
|
polygonColorFunction?: GenericFunction;
|
||||||
editablePolygon: boolean;
|
editablePolygon: boolean;
|
||||||
}
|
};
|
||||||
|
|
||||||
export type PolylineSettings = {
|
export type PolylineSettings = {
|
||||||
usePolylineDecorator: any;
|
usePolylineDecorator: any;
|
||||||
@ -166,7 +166,7 @@ export type PolylineSettings = {
|
|||||||
colorFunction: GenericFunction;
|
colorFunction: GenericFunction;
|
||||||
strokeOpacityFunction: GenericFunction;
|
strokeOpacityFunction: GenericFunction;
|
||||||
strokeWeightFunction: GenericFunction;
|
strokeWeightFunction: GenericFunction;
|
||||||
}
|
};
|
||||||
|
|
||||||
export interface HistorySelectSettings {
|
export interface HistorySelectSettings {
|
||||||
buttonColor: string;
|
buttonColor: string;
|
||||||
@ -244,4 +244,5 @@ export const hereProviders = [
|
|||||||
'HERE.normalDay',
|
'HERE.normalDay',
|
||||||
'HERE.normalNight',
|
'HERE.normalNight',
|
||||||
'HERE.hybridDay',
|
'HERE.hybridDay',
|
||||||
'HERE.terrainDay']
|
'HERE.terrainDay'
|
||||||
|
];
|
||||||
|
|||||||
@ -18,15 +18,15 @@ import { JsonSettingsSchema } from '@shared/models/widget.models';
|
|||||||
import { MapProviders } from './map-models';
|
import { MapProviders } from './map-models';
|
||||||
|
|
||||||
export interface MapWidgetInterface {
|
export interface MapWidgetInterface {
|
||||||
resize(),
|
resize();
|
||||||
update(),
|
update();
|
||||||
onInit(),
|
onInit();
|
||||||
onDestroy();
|
onDestroy();
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface MapWidgetStaticInterface {
|
export interface MapWidgetStaticInterface {
|
||||||
settingsSchema(mapProvider?: MapProviders, drawRoutes?: boolean): JsonSettingsSchema;
|
settingsSchema(mapProvider?: MapProviders, drawRoutes?: boolean): JsonSettingsSchema;
|
||||||
getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema
|
getProvidersSchema(mapProvider?: MapProviders, ignoreImageMap?: boolean): JsonSettingsSchema;
|
||||||
dataKeySettingsSchema(): object;
|
dataKeySettingsSchema(): object;
|
||||||
actionSources(): object;
|
actionSources(): object;
|
||||||
}
|
}
|
||||||
|
|||||||
@ -33,7 +33,7 @@ import {
|
|||||||
import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface';
|
import { MapWidgetInterface, MapWidgetStaticInterface } from './map-widget.interface';
|
||||||
import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils';
|
import { addCondition, addGroupInfo, addToSchema, initSchema, mergeSchemes } from '@core/schema-utils';
|
||||||
import { WidgetContext } from '@app/modules/home/models/widget-component.models';
|
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 { Datasource, DatasourceData, JsonSettingsSchema, WidgetActionDescriptor } from '@shared/models/widget.models';
|
||||||
import { EntityId } from '@shared/models/id/entity-id';
|
import { EntityId } from '@shared/models/id/entity-id';
|
||||||
import { AttributeScope, DataKeyType, LatestTelemetry } from '@shared/models/telemetry/telemetry.models';
|
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) {
|
public static getProvidersSchema(mapProvider: MapProviders, ignoreImageMap = false) {
|
||||||
const providerSchema = _.cloneDeep(mapProviderSchema);
|
const providerSchema = _.cloneDeep(mapProviderSchema);
|
||||||
if (mapProvider)
|
if (mapProvider) {
|
||||||
providerSchema.schema.properties.provider.default = mapProvider;
|
providerSchema.schema.properties.provider.default = mapProvider;
|
||||||
|
}
|
||||||
if (ignoreImageMap) {
|
if (ignoreImageMap) {
|
||||||
providerSchema.form[0].items = providerSchema.form[0]?.items.filter(item => item.value !== 'image-map');
|
providerSchema.form[0].items = providerSchema.form[0]?.items.filter(item => item.value !== 'image-map');
|
||||||
}
|
}
|
||||||
@ -129,7 +130,7 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
} else {
|
} else {
|
||||||
const clusteringSchema = mergeSchemes([markerClusteringSettingsSchema,
|
const clusteringSchema = mergeSchemes([markerClusteringSettingsSchema,
|
||||||
addCondition(markerClusteringSettingsSchemaLeaflet,
|
addCondition(markerClusteringSettingsSchemaLeaflet,
|
||||||
`model.useClusterMarkers === true && model.provider !== "image-map"`)])
|
`model.useClusterMarkers === true && model.provider !== "image-map"`)]);
|
||||||
addToSchema(schema, clusteringSchema);
|
addToSchema(schema, clusteringSchema);
|
||||||
addGroupInfo(schema, 'Markers Clustering Settings');
|
addGroupInfo(schema, 'Markers Clustering Settings');
|
||||||
}
|
}
|
||||||
@ -154,10 +155,11 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
}
|
}
|
||||||
|
|
||||||
translate = (key: string, defaultTranslation?: string): string => {
|
translate = (key: string, defaultTranslation?: string): string => {
|
||||||
if (key)
|
if (key) {
|
||||||
return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key)
|
return (this.ctx.$injector.get(UtilsService).customTranslation(key, defaultTranslation || key)
|
||||||
|| this.ctx.$injector.get(TranslateService).instant(key));
|
|| this.ctx.$injector.get(TranslateService).instant(key));
|
||||||
else return '';
|
}
|
||||||
|
return '';
|
||||||
}
|
}
|
||||||
|
|
||||||
getDescriptors(name: string): { [name: string]: ($event: Event, datasource: Datasource) => void } {
|
getDescriptors(name: string): { [name: string]: ($event: Event, datasource: Datasource) => void } {
|
||||||
@ -211,10 +213,10 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
}
|
}
|
||||||
if (value) {
|
if (value) {
|
||||||
if (key.type === DataKeyType.attribute) {
|
if (key.type === DataKeyType.attribute) {
|
||||||
attributes.push(value)
|
attributes.push(value);
|
||||||
}
|
}
|
||||||
if (key.type === DataKeyType.timeseries) {
|
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;
|
const coordinatesProperties = this.settings.polygonKeyName;
|
||||||
e.$datasource.dataKeys.forEach(key => {
|
e.$datasource.dataKeys.forEach(key => {
|
||||||
let value;
|
let value;
|
||||||
if (coordinatesProperties == key.name) {
|
if (coordinatesProperties === key.name) {
|
||||||
value = {
|
value = {
|
||||||
key: key.name,
|
key: key.name,
|
||||||
value: isDefined(coordinates) ? coordinates : e[key.name]
|
value: isDefined(coordinates) ? coordinates : e[key.name]
|
||||||
@ -261,10 +263,10 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
}
|
}
|
||||||
if (value) {
|
if (value) {
|
||||||
if (key.type === DataKeyType.attribute) {
|
if (key.type === DataKeyType.attribute) {
|
||||||
attributes.push(value)
|
attributes.push(value);
|
||||||
}
|
}
|
||||||
if (key.type === DataKeyType.timeseries) {
|
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'];
|
const functionParams = ['data', 'dsData', 'dsIndex'];
|
||||||
this.provider = settings.provider || this.mapProvider;
|
this.provider = settings.provider || this.mapProvider;
|
||||||
if (this.provider === MapProviders.here && !settings.mapProviderHere) {
|
if (this.provider === MapProviders.here && !settings.mapProviderHere) {
|
||||||
if (settings.mapProvider && hereProviders.includes(settings.mapProvider))
|
if (settings.mapProvider && hereProviders.includes(settings.mapProvider)) {
|
||||||
settings.mapProviderHere = settings.mapProvider
|
settings.mapProviderHere = settings.mapProvider;
|
||||||
else settings.mapProviderHere = hereProviders[0];
|
} else {
|
||||||
|
settings.mapProviderHere = hereProviders[0];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
const customOptions = {
|
const customOptions = {
|
||||||
provider: this.provider,
|
provider: this.provider,
|
||||||
@ -317,14 +321,14 @@ export class MapWidgetController implements MapWidgetInterface {
|
|||||||
url: settings.markerImage,
|
url: settings.markerImage,
|
||||||
size: settings.markerImageSize || 34
|
size: settings.markerImageSize || 34
|
||||||
} : null
|
} : null
|
||||||
}
|
};
|
||||||
if (isEditMap && !settings.hasOwnProperty('draggableMarker')) {
|
if (isEditMap && !settings.hasOwnProperty('draggableMarker')) {
|
||||||
settings.draggableMarker = true;
|
settings.draggableMarker = true;
|
||||||
}
|
}
|
||||||
if (isEditMap && !settings.hasOwnProperty('editablePolygon')) {
|
if (isEditMap && !settings.hasOwnProperty('editablePolygon')) {
|
||||||
settings.editablePolygon = true;
|
settings.editablePolygon = true;
|
||||||
}
|
}
|
||||||
return { ...defaultSettings, ...settings, ...customOptions, }
|
return { ...defaultSettings, ...settings, ...customOptions, };
|
||||||
}
|
}
|
||||||
|
|
||||||
update() {
|
update() {
|
||||||
|
|||||||
@ -97,10 +97,12 @@ export function findAngle(startPoint: FormattedData, endPoint: FormattedData, la
|
|||||||
|
|
||||||
|
|
||||||
export function getDefCenterPosition(position) {
|
export function getDefCenterPosition(position) {
|
||||||
if (typeof (position) === 'string')
|
if (typeof (position) === 'string') {
|
||||||
return position.split(',');
|
return position.split(',');
|
||||||
if (typeof (position) === 'object')
|
}
|
||||||
|
if (typeof (position) === 'object') {
|
||||||
return position;
|
return position;
|
||||||
|
}
|
||||||
return [0, 0];
|
return [0, 0];
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -123,7 +125,7 @@ function imageLoader(imageUrl: string): Observable<HTMLImageElement> {
|
|||||||
document.body.removeChild(image);
|
document.body.removeChild(image);
|
||||||
observer.complete();
|
observer.complete();
|
||||||
};
|
};
|
||||||
document.body.appendChild(image)
|
document.body.appendChild(image);
|
||||||
image.src = imageUrl;
|
image.src = imageUrl;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@ -135,11 +137,11 @@ export function aspectCache(imageUrl: string): Observable<number> {
|
|||||||
if (aspect) {
|
if (aspect) {
|
||||||
return of(aspect);
|
return of(aspect);
|
||||||
}
|
}
|
||||||
else return imageLoader(imageUrl).pipe(map(image => {
|
return imageLoader(imageUrl).pipe(map(image => {
|
||||||
aspect = image.width / image.height;
|
aspect = image.width / image.height;
|
||||||
imageAspectMap[hash] = aspect;
|
imageAspectMap[hash] = aspect;
|
||||||
return aspect;
|
return aspect;
|
||||||
}))
|
}));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -221,7 +223,7 @@ function parseTemplate(template: string, data: { $datasource?: Datasource, [key:
|
|||||||
// res = compiled(data);
|
// res = compiled(data);
|
||||||
res = template;
|
res = template;
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.log(ex, template)
|
console.log(ex, template);
|
||||||
}
|
}
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
@ -263,7 +265,7 @@ export function processPattern(template: string, data: { $datasource?: Datasourc
|
|||||||
match = reg.exec(template);
|
match = reg.exec(template);
|
||||||
}
|
}
|
||||||
} catch (ex) {
|
} catch (ex) {
|
||||||
console.log(ex, template)
|
console.log(ex, template);
|
||||||
}
|
}
|
||||||
return replaceInfo;
|
return replaceInfo;
|
||||||
}
|
}
|
||||||
@ -334,7 +336,7 @@ export const parseWithTranslation = {
|
|||||||
setTranslate(translateFn: TranslateFunc) {
|
setTranslate(translateFn: TranslateFunc) {
|
||||||
this.translateFn = translateFn;
|
this.translateFn = translateFn;
|
||||||
}
|
}
|
||||||
}
|
};
|
||||||
|
|
||||||
export function parseData(input: DatasourceData[]): FormattedData[] {
|
export function parseData(input: DatasourceData[]): FormattedData[] {
|
||||||
return _(input).groupBy(el => el?.datasource?.entityName)
|
return _(input).groupBy(el => el?.datasource?.entityName)
|
||||||
@ -361,7 +363,7 @@ export function parseData(input: DatasourceData[]): FormattedData[] {
|
|||||||
|
|
||||||
export function parseArray(input: DatasourceData[]): FormattedData[][] {
|
export function parseArray(input: DatasourceData[]): FormattedData[][] {
|
||||||
return _(input).groupBy(el => el?.datasource?.entityName)
|
return _(input).groupBy(el => el?.datasource?.entityName)
|
||||||
.values().value().map((entityArray, dsIndex) =>
|
.values().value().map((entityArray) =>
|
||||||
entityArray[0].data.map((el, i) => {
|
entityArray[0].data.map((el, i) => {
|
||||||
const obj: FormattedData = {
|
const obj: FormattedData = {
|
||||||
entityName: entityArray[0]?.datasource?.entityName,
|
entityName: entityArray[0]?.datasource?.entityName,
|
||||||
|
|||||||
@ -55,7 +55,7 @@ export class Polygon {
|
|||||||
this.leafletPoly.on('click', (event: LeafletMouseEvent) => {
|
this.leafletPoly.on('click', (event: LeafletMouseEvent) => {
|
||||||
for (const action in this.settings.polygonClick) {
|
for (const action in this.settings.polygonClick) {
|
||||||
if (typeof (this.settings.polygonClick[action]) === 'function') {
|
if (typeof (this.settings.polygonClick[action]) === 'function') {
|
||||||
this.settings.polygonClick[action](event.originalEvent, polyData.datasource);
|
this.settings.polygonClick[action](event.originalEvent, polyData.$datasource);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -79,8 +79,9 @@ export class Polygon {
|
|||||||
if (settings.editablePolygon) {
|
if (settings.editablePolygon) {
|
||||||
this.leafletPoly.enableEdit(this.map);
|
this.leafletPoly.enableEdit(this.map);
|
||||||
}
|
}
|
||||||
if (settings.showPolygonTooltip)
|
if (settings.showPolygonTooltip) {
|
||||||
this.updateTooltip(this.data);
|
this.updateTooltip(this.data);
|
||||||
|
}
|
||||||
this.updatePolygonColor(settings);
|
this.updatePolygonColor(settings);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -57,7 +57,7 @@ export class Polyline {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
updatePolyline(locations: L.LatLng[], data: FormattedData, dataSources: FormattedData[], settings: PolylineSettings) {
|
updatePolyline(locations: L.LatLng[], data: FormattedData, dataSources: FormattedData[], settings: PolylineSettings) {
|
||||||
@ -65,9 +65,10 @@ export class Polyline {
|
|||||||
this.dataSources = dataSources;
|
this.dataSources = dataSources;
|
||||||
this.leafletPoly.setLatLngs(locations);
|
this.leafletPoly.setLatLngs(locations);
|
||||||
this.leafletPoly.setStyle(this.getPolyStyle(settings));
|
this.leafletPoly.setStyle(this.getPolyStyle(settings));
|
||||||
if (this.polylineDecorator)
|
if (this.polylineDecorator) {
|
||||||
this.polylineDecorator.setPaths(this.leafletPoly);
|
this.polylineDecorator.setPaths(this.leafletPoly);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
|
getPolyStyle(settings: PolylineSettings): L.PolylineOptions {
|
||||||
return {
|
return {
|
||||||
@ -78,7 +79,7 @@ export class Polyline {
|
|||||||
[this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity),
|
[this.data, this.dataSources, this.data.dsIndex], settings.strokeOpacity),
|
||||||
weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction,
|
weight: functionValueCalculator(settings.useStrokeWeightFunction, settings.strokeWeightFunction,
|
||||||
[this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight)
|
[this.data, this.dataSources, this.data.dsIndex], settings.strokeWeight)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
removePolyline() {
|
removePolyline() {
|
||||||
|
|||||||
@ -49,7 +49,7 @@ export class GoogleMap extends LeafletMap {
|
|||||||
|
|
||||||
private loadGoogle(callback, apiKey = 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q') {
|
private loadGoogle(callback, apiKey = 'AIzaSyDoEx2kaGz3PxwbI9T7ccTSg5xjdw8Nw8Q') {
|
||||||
if (gmGlobals[apiKey]) {
|
if (gmGlobals[apiKey]) {
|
||||||
callback()
|
callback();
|
||||||
} else {
|
} else {
|
||||||
this.resource.loadResource(`https://maps.googleapis.com/maps/api/js?key=${apiKey}`).subscribe(
|
this.resource.loadResource(`https://maps.googleapis.com/maps/api/js?key=${apiKey}`).subscribe(
|
||||||
() => {
|
() => {
|
||||||
|
|||||||
@ -185,7 +185,19 @@ export class ImageMap extends LeafletMap {
|
|||||||
this.updateBounds(updateImage, lastCenterPos);
|
this.updateBounds(updateImage, lastCenterPos);
|
||||||
this.map.invalidateSize(true);
|
this.map.invalidateSize(true);
|
||||||
this.updateMarkers(this.markersData);
|
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));
|
||||||
|
});
|
||||||
|
}
|
||||||
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));
|
||||||
|
});
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -227,13 +239,14 @@ export class ImageMap extends LeafletMap {
|
|||||||
if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
|
if (!Array.isArray(el[0]) && !Array.isArray(el[1]) && el.length === 2) {
|
||||||
return this.pointToLatLng(
|
return this.pointToLatLng(
|
||||||
el[0] * this.width,
|
el[0] * this.width,
|
||||||
el[1] * this.height)
|
el[1] * this.height
|
||||||
|
);
|
||||||
} else if (Array.isArray(el) && el.length) {
|
} else if (Array.isArray(el) && el.length) {
|
||||||
return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
|
return this.convertPositionPolygon(el as LatLngTuple[] | LatLngTuple[][]);
|
||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}).filter(el => !!el)
|
}).filter(el => !!el);
|
||||||
}
|
}
|
||||||
|
|
||||||
pointToLatLng(x, y): L.LatLng {
|
pointToLatLng(x, y): L.LatLng {
|
||||||
@ -244,32 +257,32 @@ export class ImageMap extends LeafletMap {
|
|||||||
return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
|
return L.CRS.Simple.latLngToPoint(latLng, maxZoom - 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToCustomFormat(position: L.LatLng): object {
|
convertToCustomFormat(position: L.LatLng, width = this.width, height = this.height): object {
|
||||||
const point = this.latLngToPoint(position);
|
const point = this.latLngToPoint(position);
|
||||||
return {
|
return {
|
||||||
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, this.width),
|
[this.options.xPosKeyName]: calculateNewPointCoordinate(point.x, width),
|
||||||
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, this.height)
|
[this.options.yPosKeyName]: calculateNewPointCoordinate(point.y, height)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
convertToPolygonFormat(points: Array<any>): Array<any> {
|
convertToPolygonFormat(points: Array<any>, width = this.width, height = this.height): Array<any> {
|
||||||
if (points.length) {
|
if (points.length) {
|
||||||
return points.map(point => {
|
return points.map(point => {
|
||||||
if (point.length) {
|
if (point.length) {
|
||||||
return this.convertToPolygonFormat(point);
|
return this.convertToPolygonFormat(point, width, height);
|
||||||
} else {
|
} else {
|
||||||
const pos = this.latLngToPoint(point);
|
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 {
|
} else {
|
||||||
return []
|
return [];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
convertPolygonToCustomFormat(expression: any[][]): object {
|
convertPolygonToCustomFormat(expression: any[][]): object {
|
||||||
return {
|
return {
|
||||||
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
[this.options.polygonKeyName] : this.convertToPolygonFormat(expression)
|
||||||
}
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -29,16 +29,16 @@ import LeafletMap from '@home/components/widget/lib/maps/leaflet-map';
|
|||||||
import { JsonSettingsSchema } from '@shared/models/widget.models';
|
import { JsonSettingsSchema } from '@shared/models/widget.models';
|
||||||
|
|
||||||
interface IProvider {
|
interface IProvider {
|
||||||
MapClass: Type<LeafletMap>,
|
MapClass: Type<LeafletMap>;
|
||||||
schema: JsonSettingsSchema,
|
schema: JsonSettingsSchema;
|
||||||
name: string
|
name: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const providerSets: { [key: string]: IProvider } = {
|
export const providerSets: { [key: string]: IProvider } = {
|
||||||
'openstreet-map': {
|
'openstreet-map': {
|
||||||
MapClass: OpenStreetMap,
|
MapClass: OpenStreetMap,
|
||||||
schema: openstreetMapSettingsSchema,
|
schema: openstreetMapSettingsSchema,
|
||||||
name: 'openstreet-map',
|
name: 'openstreet-map'
|
||||||
},
|
},
|
||||||
'tencent-map': {
|
'tencent-map': {
|
||||||
MapClass: TencentMap,
|
MapClass: TencentMap,
|
||||||
|
|||||||
@ -26,10 +26,11 @@ export class OpenStreetMap extends LeafletMap {
|
|||||||
editable: !!options.editablePolygon
|
editable: !!options.editablePolygon
|
||||||
}).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
|
}).setView(options?.defaultCenterPosition, options?.defaultZoomLevel);
|
||||||
let tileLayer;
|
let tileLayer;
|
||||||
if (options.useCustomProvider)
|
if (options.useCustomProvider) {
|
||||||
tileLayer = L.tileLayer(options.customProviderTileUrl);
|
tileLayer = L.tileLayer(options.customProviderTileUrl);
|
||||||
else
|
} else {
|
||||||
tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik');
|
tileLayer = (L.tileLayer as any).provider(options.mapProvider || 'OpenStreetMap.Mapnik');
|
||||||
|
}
|
||||||
tileLayer.addTo(map);
|
tileLayer.addTo(map);
|
||||||
super.initSettings(options);
|
super.initSettings(options);
|
||||||
super.setMap(map);
|
super.setMap(map);
|
||||||
|
|||||||
@ -1095,4 +1095,4 @@ export const tripAnimationSchema = {
|
|||||||
}
|
}
|
||||||
]
|
]
|
||||||
}]
|
}]
|
||||||
}
|
};
|
||||||
|
|||||||
@ -35,7 +35,6 @@ import {
|
|||||||
} from '@angular/core';
|
} from '@angular/core';
|
||||||
import { DashboardWidget } from '@home/models/dashboard-component.models';
|
import { DashboardWidget } from '@home/models/dashboard-component.models';
|
||||||
import {
|
import {
|
||||||
Datasource,
|
|
||||||
defaultLegendConfig,
|
defaultLegendConfig,
|
||||||
LegendConfig,
|
LegendConfig,
|
||||||
LegendData,
|
LegendData,
|
||||||
@ -55,7 +54,7 @@ import { AppState } from '@core/core.state';
|
|||||||
import { WidgetService } from '@core/http/widget.service';
|
import { WidgetService } from '@core/http/widget.service';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
import { UtilsService } from '@core/services/utils.service';
|
||||||
import { forkJoin, Observable, of, ReplaySubject, Subscription, throwError } from 'rxjs';
|
import { forkJoin, Observable, of, ReplaySubject, Subscription, throwError } from 'rxjs';
|
||||||
import { deepClone, isDefined, objToBase64 } from '@core/utils';
|
import { deepClone, isDefined, objToBase64URI } from '@core/utils';
|
||||||
import {
|
import {
|
||||||
IDynamicWidgetComponent,
|
IDynamicWidgetComponent,
|
||||||
WidgetContext,
|
WidgetContext,
|
||||||
@ -68,7 +67,8 @@ import {
|
|||||||
StateObject,
|
StateObject,
|
||||||
StateParams,
|
StateParams,
|
||||||
SubscriptionEntityInfo,
|
SubscriptionEntityInfo,
|
||||||
SubscriptionInfo, SubscriptionMessage,
|
SubscriptionInfo,
|
||||||
|
SubscriptionMessage,
|
||||||
WidgetSubscriptionContext,
|
WidgetSubscriptionContext,
|
||||||
WidgetSubscriptionOptions
|
WidgetSubscriptionOptions
|
||||||
} from '@core/api/widget-api.models';
|
} from '@core/api/widget-api.models';
|
||||||
@ -80,11 +80,9 @@ import { catchError, switchMap } from 'rxjs/operators';
|
|||||||
import { ActionNotificationShow } from '@core/notification/notification.actions';
|
import { ActionNotificationShow } from '@core/notification/notification.actions';
|
||||||
import { TimeService } from '@core/services/time.service';
|
import { TimeService } from '@core/services/time.service';
|
||||||
import { DeviceService } from '@app/core/http/device.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 { ExceptionData } from '@shared/models/error.models';
|
||||||
import { WidgetComponentService } from './widget-component.service';
|
import { WidgetComponentService } from './widget-component.service';
|
||||||
import { Timewindow } from '@shared/models/time/time.models';
|
import { Timewindow } from '@shared/models/time/time.models';
|
||||||
import { AlarmSearchStatus } from '@shared/models/alarm.models';
|
|
||||||
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
|
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
|
||||||
import { DashboardService } from '@core/http/dashboard.service';
|
import { DashboardService } from '@core/http/dashboard.service';
|
||||||
import { WidgetSubscription } from '@core/api/widget-subscription';
|
import { WidgetSubscription } from '@core/api/widget-subscription';
|
||||||
@ -688,7 +686,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
|
|||||||
|
|
||||||
private destroyDynamicWidgetComponent() {
|
private destroyDynamicWidgetComponent() {
|
||||||
if (this.widgetContext.$containerParent && this.widgetResize$) {
|
if (this.widgetContext.$containerParent && this.widgetResize$) {
|
||||||
this.widgetResize$.disconnect()
|
this.widgetResize$.disconnect();
|
||||||
}
|
}
|
||||||
if (this.dynamicWidgetComponentRef) {
|
if (this.dynamicWidgetComponentRef) {
|
||||||
this.dynamicWidgetComponentRef.destroy();
|
this.dynamicWidgetComponentRef.destroy();
|
||||||
@ -1023,7 +1021,7 @@ export class WidgetComponent extends PageComponent implements OnInit, AfterViewI
|
|||||||
if (targetDashboardStateId) {
|
if (targetDashboardStateId) {
|
||||||
stateObject.id = targetDashboardStateId;
|
stateObject.id = targetDashboardStateId;
|
||||||
}
|
}
|
||||||
const state = objToBase64([ stateObject ]);
|
const state = objToBase64URI([ stateObject ]);
|
||||||
const isSinglePage = this.route.snapshot.data.singlePageMode;
|
const isSinglePage = this.route.snapshot.data.singlePageMode;
|
||||||
let url;
|
let url;
|
||||||
if (isSinglePage) {
|
if (isSinglePage) {
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import { StateControllerComponent } from './state-controller.component';
|
|||||||
import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
|
import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
|
||||||
import { EntityId } from '@app/shared/models/id/entity-id';
|
import { EntityId } from '@app/shared/models/id/entity-id';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
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 { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||||
import { EntityService } from '@core/http/entity.service';
|
import { EntityService } from '@core/http/entity.service';
|
||||||
|
|
||||||
@ -237,7 +237,7 @@ export class DefaultStateControllerComponent extends StateControllerComponent im
|
|||||||
|
|
||||||
private updateLocation() {
|
private updateLocation() {
|
||||||
if (this.stateObject[0].id) {
|
if (this.stateObject[0].id) {
|
||||||
const newState = objToBase64(this.stateObject);
|
const newState = objToBase64URI(this.stateObject);
|
||||||
this.updateStateParam(newState);
|
this.updateStateParam(newState);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@ -23,7 +23,7 @@ import { StateControllerComponent } from './state-controller.component';
|
|||||||
import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
|
import { StatesControllerService } from '@home/pages/dashboard/states/states-controller.service';
|
||||||
import { EntityId } from '@app/shared/models/id/entity-id';
|
import { EntityId } from '@app/shared/models/id/entity-id';
|
||||||
import { UtilsService } from '@core/services/utils.service';
|
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 { DashboardUtilsService } from '@core/services/dashboard-utils.service';
|
||||||
import { EntityService } from '@core/http/entity.service';
|
import { EntityService } from '@core/http/entity.service';
|
||||||
import { EntityType } from '@shared/models/entity-type.models';
|
import { EntityType } from '@shared/models/entity-type.models';
|
||||||
@ -281,7 +281,7 @@ export class EntityStateControllerComponent extends StateControllerComponent imp
|
|||||||
if (this.isDefaultState()) {
|
if (this.isDefaultState()) {
|
||||||
newState = null;
|
newState = null;
|
||||||
} else {
|
} else {
|
||||||
newState = objToBase64(this.stateObject);
|
newState = objToBase64URI(this.stateObject);
|
||||||
}
|
}
|
||||||
this.updateStateParam(newState);
|
this.updateStateParam(newState);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2138,7 +2138,7 @@ base64-arraybuffer@0.1.5:
|
|||||||
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
resolved "https://registry.yarnpkg.com/base64-arraybuffer/-/base64-arraybuffer-0.1.5.tgz#73926771923b5a19747ad666aa5cd4bf9c6e9ce8"
|
||||||
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
|
integrity sha1-c5JncZI7Whl0etZmqlzUv5xunOg=
|
||||||
|
|
||||||
base64-js@^1.0.2, base64-js@^1.3.1:
|
base64-js@^1.0.2:
|
||||||
version "1.3.1"
|
version "1.3.1"
|
||||||
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.3.1.tgz#58ece8cb75dd07e71ed08c736abc5fac4dbf8df1"
|
||||||
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
|
integrity sha512-mLQ4i2QO1ytvGWFWmcngKO//JXAQueZvwEKtjgQFM4jIK0kU+ytMfplL8j+n5mspOfjHwoAg+9yhb7BwAHm36g==
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user