Create new input widgets for edit location enity to map (#2138)
This commit is contained in:
parent
46c7862258
commit
ac8e67eff0
File diff suppressed because one or more lines are too long
27
ui/src/app/widget/lib/add-entity-panel.scss
Normal file
27
ui/src/app/widget/lib/add-entity-panel.scss
Normal file
@ -0,0 +1,27 @@
|
||||
/**
|
||||
* Copyright © 2016-2019 The Thingsboard Authors
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
.tb-add-entity-panel {
|
||||
min-width: 150px;
|
||||
max-height: 200px;
|
||||
overflow: hidden;
|
||||
overflow-y: auto;
|
||||
background: #fff;
|
||||
border-radius: 4px;
|
||||
box-shadow:
|
||||
0 7px 8px -4px rgba(0, 0, 0, .2),
|
||||
0 13px 19px 2px rgba(0, 0, 0, .14),
|
||||
0 5px 24px 4px rgba(0, 0, 0, .12);
|
||||
}
|
||||
22
ui/src/app/widget/lib/add-entity-panel.tpl.html
Normal file
22
ui/src/app/widget/lib/add-entity-panel.tpl.html
Normal file
@ -0,0 +1,22 @@
|
||||
<!--
|
||||
|
||||
Copyright © 2016-2019 The Thingsboard Authors
|
||||
|
||||
Licensed under the Apache License, Version 2.0 (the "License");
|
||||
you may not use this file except in compliance with the License.
|
||||
You may obtain a copy of the License at
|
||||
|
||||
http://www.apache.org/licenses/LICENSE-2.0
|
||||
|
||||
Unless required by applicable law or agreed to in writing, software
|
||||
distributed under the License is distributed on an "AS IS" BASIS,
|
||||
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
See the License for the specific language governing permissions and
|
||||
limitations under the License.
|
||||
|
||||
-->
|
||||
<md-list ng-cloak>
|
||||
<md-list-item ng-repeat="entity in vm.entities" ng-click="vm.selectEntity(entity)">
|
||||
<span>{{ entity.entityLabel || entity.name }}</span>
|
||||
</md-list-item>
|
||||
</md-list>
|
||||
@ -29,7 +29,7 @@ export default class TbGoogleMap {
|
||||
this.tooltips = [];
|
||||
this.defaultMapType = gmDefaultMapType;
|
||||
this.defaultCenterPosition = defaultCenterPosition;
|
||||
this.isMarketCluster = markerClusteringSetting.isMarketCluster;
|
||||
this.isMarketCluster = markerClusteringSetting && markerClusteringSetting.isMarketCluster;
|
||||
|
||||
function clearGlobalId() {
|
||||
if (gmGlobals.loadingGmId && gmGlobals.loadingGmId === tbMap.mapId) {
|
||||
@ -234,17 +234,19 @@ export default class TbGoogleMap {
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs, onDragendListener) {
|
||||
var marker;
|
||||
if (settings.showLabel) {
|
||||
marker = new MarkerWithLabel({
|
||||
position: location,
|
||||
labelContent: '<div style="color: '+ settings.labelColor +';"><b>'+settings.labelText+'</b></div>',
|
||||
labelClass: "tb-labels"
|
||||
labelClass: "tb-labels",
|
||||
draggable: settings.drraggable,
|
||||
});
|
||||
} else {
|
||||
marker = new google.maps.Marker({
|
||||
position: location,
|
||||
draggable: settings.drraggable,
|
||||
});
|
||||
}
|
||||
var gMap = this;
|
||||
@ -268,6 +270,10 @@ export default class TbGoogleMap {
|
||||
marker.addListener('click', onClickListener);
|
||||
}
|
||||
|
||||
if (onDragendListener) {
|
||||
marker.addListener('dragend', onDragendListener);
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
@ -476,4 +482,8 @@ export default class TbGoogleMap {
|
||||
return this.tooltips;
|
||||
}
|
||||
|
||||
getCenter() {
|
||||
return this.map.getCenter().toJSON();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -300,12 +300,14 @@ export default class TbImageMap {
|
||||
onMarkerIconReady(iconInfo);
|
||||
}
|
||||
|
||||
createMarker(position, dsIndex, settings, onClickListener, markerArgs) {
|
||||
createMarker(position, dsIndex, settings, onClickListener, markerArgs, onDragendListener) {
|
||||
var pos = this.posFunction(position.x, position.y);
|
||||
var x = pos.x * this.width;
|
||||
var y = pos.y * this.height;
|
||||
var location = this.pointToLatLng(x, y);
|
||||
var marker = L.marker(location, {});//.addTo(this.map);
|
||||
var marker = L.marker(location, {
|
||||
draggable: settings.drraggable
|
||||
});//.addTo(this.map);
|
||||
marker.position = position;
|
||||
marker.offsetX = settings.markerOffsetX;
|
||||
marker.offsetY = settings.markerOffsetY;
|
||||
@ -327,10 +329,30 @@ export default class TbImageMap {
|
||||
if (onClickListener) {
|
||||
marker.on('click', onClickListener);
|
||||
}
|
||||
if (onDragendListener) {
|
||||
marker.on('dragend', ($event) => {
|
||||
let newMarkerPosition = this.latLngToPoint(marker.getLatLng());
|
||||
marker.position.x = this.constructor.calculateNewPosition(newMarkerPosition.x, this.width);
|
||||
marker.position.y = this.constructor.calculateNewPosition(newMarkerPosition.y, this.height);
|
||||
this.setMarkerPosition(marker, marker.position);
|
||||
onDragendListener($event);
|
||||
});
|
||||
}
|
||||
this.markers.push(marker);
|
||||
return marker;
|
||||
}
|
||||
|
||||
static calculateNewPosition(positon, imageSize) {
|
||||
let newPosition = positon / imageSize;
|
||||
if (newPosition < 0) {
|
||||
newPosition = 0;
|
||||
} else if (newPosition > 1) {
|
||||
newPosition = 1;
|
||||
}
|
||||
return newPosition;
|
||||
}
|
||||
|
||||
|
||||
updateMarkers() {
|
||||
this.markers.forEach((marker) => {
|
||||
this.updateMarkerLocation(marker);
|
||||
@ -439,6 +461,10 @@ export default class TbImageMap {
|
||||
return this.tooltips;
|
||||
}
|
||||
|
||||
getCenter() {
|
||||
return this.map.getCenter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
class Position {
|
||||
|
||||
@ -21,10 +21,12 @@ import TbImageMap from './image-map';
|
||||
import TbTencentMap from './tencent-map';
|
||||
|
||||
import {processPattern, arraysEqual, toLabelValueMap, fillPattern, fillPatternWithActions} from './widget-utils';
|
||||
import addEntityPanelTemplate from './add-entity-panel.tpl.html';
|
||||
import './add-entity-panel.scss';
|
||||
|
||||
export default class TbMapWidgetV2 {
|
||||
|
||||
constructor(mapProvider, drawRoutes, ctx, useDynamicLocations, $element) {
|
||||
constructor(mapProvider, drawRoutes, ctx, useDynamicLocations, $element, isEdit) {
|
||||
var tbMap = this;
|
||||
this.ctx = ctx;
|
||||
this.mapProvider = mapProvider;
|
||||
@ -33,6 +35,7 @@ export default class TbMapWidgetV2 {
|
||||
}
|
||||
this.utils = ctx.$scope.$injector.get('utils');
|
||||
this.drawRoutes = drawRoutes;
|
||||
this.isEdit = isEdit ? isEdit : false;
|
||||
this.markers = [];
|
||||
this.polygons = [];
|
||||
if (this.drawRoutes) {
|
||||
@ -292,6 +295,112 @@ export default class TbMapWidgetV2 {
|
||||
}
|
||||
}
|
||||
|
||||
selectEntity($event) {
|
||||
var tbMap = this;
|
||||
|
||||
function setDefaultPosition(entity) {
|
||||
let position = tbMap.map.getCenter();
|
||||
if (tbMap.mapProvider === "image-map") {
|
||||
position = tbMap.map.latLngToPoint(position);
|
||||
position.lat = position.x / tbMap.map.width;
|
||||
position.lng = position.y / tbMap.map.height;
|
||||
}
|
||||
|
||||
tbMap.saveMarkerLocation(
|
||||
entity,
|
||||
locationsWithoutMarker[entitiesWithoutPosition.indexOf(entity)],
|
||||
position
|
||||
);
|
||||
}
|
||||
|
||||
const element = angular.element($event.target);
|
||||
const $mdPanel = this.ctx.$scope.$injector.get('$mdPanel');
|
||||
const $document = this.ctx.$scope.$injector.get('$document');
|
||||
let position = $mdPanel.newPanelPosition()
|
||||
.relativeTo(element)
|
||||
.addPanelPosition($mdPanel.xPosition.ALIGN_END, $mdPanel.yPosition.BELOW);
|
||||
|
||||
let locationsWithoutMarker = this.locations.filter((location) => !location.marker);
|
||||
let entitiesWithoutPosition = [];
|
||||
for (let i = 0; i < locationsWithoutMarker.length; i++) {
|
||||
entitiesWithoutPosition.push(this.subscription.datasources[locationsWithoutMarker[i].dsIndex]);
|
||||
}
|
||||
|
||||
if(entitiesWithoutPosition.length === 1){
|
||||
setDefaultPosition(entitiesWithoutPosition[0]);
|
||||
} else {
|
||||
let config = {
|
||||
attachTo: angular.element($document[0].body),
|
||||
controller: addEntityPanelController,
|
||||
controllerAs: 'vm',
|
||||
templateUrl: addEntityPanelTemplate,
|
||||
panelClass: 'tb-add-entity-panel',
|
||||
position: position,
|
||||
fullscreen: false,
|
||||
locals: {
|
||||
'entities': entitiesWithoutPosition,
|
||||
'onClose': setDefaultPosition
|
||||
},
|
||||
openFrom: $event,
|
||||
clickOutsideToClose: true,
|
||||
escapeToClose: true,
|
||||
focusOnOpen: false
|
||||
};
|
||||
$mdPanel.open(config);
|
||||
}
|
||||
}
|
||||
|
||||
saveMarkerLocation(datasource, location, coordinate) {
|
||||
var tbMap = this;
|
||||
|
||||
const types = tbMap.ctx.$scope.$injector.get('types');
|
||||
const $q = tbMap.ctx.$scope.$injector.get('$q');
|
||||
const attributeService = tbMap.ctx.$scope.$injector.get('attributeService');
|
||||
|
||||
let attributesLocation = [];
|
||||
let timeseriesLocation = [];
|
||||
let promises = [];
|
||||
|
||||
let dataKeys = datasource.dataKeys;
|
||||
for (let i = 0; i < dataKeys.length; i++) {
|
||||
if (dataKeys[i].name === location.settings.latKeyName || dataKeys[i].name === location.settings.lngKeyName) {
|
||||
let newLocation = {
|
||||
key: dataKeys[i].name,
|
||||
value: dataKeys[i].name === location.settings.latKeyName ? coordinate.lat : coordinate.lng
|
||||
};
|
||||
if (dataKeys[i].type === types.dataKeyType.attribute) {
|
||||
attributesLocation.push(newLocation);
|
||||
} else if (dataKeys[i].type === types.dataKeyType.timeseries) {
|
||||
timeseriesLocation.push(newLocation);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (attributesLocation.length > 0) {
|
||||
promises.push(attributeService.saveEntityAttributes(
|
||||
datasource.entityType,
|
||||
datasource.entityId,
|
||||
types.attributesScope.server.value,
|
||||
attributesLocation,
|
||||
{
|
||||
ignoreLoading: true
|
||||
}
|
||||
))
|
||||
}
|
||||
if (timeseriesLocation.length > 0) {
|
||||
promises.push(attributeService.saveEntityTimeseries(
|
||||
datasource.entityType,
|
||||
datasource.entityId,
|
||||
"scope",
|
||||
timeseriesLocation,
|
||||
{
|
||||
ignoreLoading: true
|
||||
}
|
||||
))
|
||||
}
|
||||
return $q.all([promises]);
|
||||
}
|
||||
|
||||
update() {
|
||||
var tbMap = this;
|
||||
|
||||
@ -411,7 +520,10 @@ export default class TbMapWidgetV2 {
|
||||
function (event) {
|
||||
tbMap.callbacks.onLocationClick(location);
|
||||
locationRowClick(event, location);
|
||||
}, [location.dsIndex]);
|
||||
}, [location.dsIndex],
|
||||
function (event) {
|
||||
markerDragend(event, location)
|
||||
});
|
||||
tbMap.markers.push(location.marker);
|
||||
changed = true;
|
||||
} else {
|
||||
@ -424,6 +536,22 @@ export default class TbMapWidgetV2 {
|
||||
return changed;
|
||||
}
|
||||
|
||||
function markerDragend($event, location) {
|
||||
if (location.settings.drraggable) {
|
||||
let position = tbMap.map.getMarkerPosition(location.marker);
|
||||
if (tbMap.mapProvider === "image-map") {
|
||||
position.lat = position.x;
|
||||
position.lng = position.y;
|
||||
delete position.x;
|
||||
delete position.y;
|
||||
} else if (tbMap.mapProvider === "google-map") {
|
||||
position = position.toJSON();
|
||||
}
|
||||
|
||||
tbMap.saveMarkerLocation(tbMap.subscription.datasources[location.dsIndex], location, position);
|
||||
}
|
||||
}
|
||||
|
||||
function locationRowClick($event, location) {
|
||||
var descriptors = tbMap.ctx.actionsApi.getActionDescriptors('markerClick');
|
||||
if (descriptors.length) {
|
||||
@ -567,6 +695,7 @@ export default class TbMapWidgetV2 {
|
||||
location.settings.tooltipPattern = tbMap.utils.createLabelFromDatasource(currentDatasource, location.settings.tooltipPattern);
|
||||
location.settings.tooltipReplaceInfo = processPattern(location.settings.tooltipPattern, datasources, currentDatasourceIndex);
|
||||
}
|
||||
location.settings.drraggable = tbMap.isEdit;
|
||||
tbMap.locations.push(location);
|
||||
updateLocation(location, data, dataMap);
|
||||
if (!tbMap.locationSettings.useDefaultCenterPosition) {
|
||||
@ -1626,3 +1755,16 @@ const imageMapSettingsSchema =
|
||||
}
|
||||
]
|
||||
};
|
||||
|
||||
/*@ngInject*/
|
||||
function addEntityPanelController(mdPanelRef, entities) {
|
||||
var vm = this;
|
||||
vm.entities = entities;
|
||||
vm.selectEntity = selectEntity;
|
||||
|
||||
function selectEntity(entity) {
|
||||
mdPanelRef.close().then(() => {
|
||||
this.onClose(entity);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@ -29,7 +29,7 @@ export default class TbOpenStreetMap {
|
||||
this.dontFitMapBounds = dontFitMapBounds;
|
||||
this.minZoomLevel = minZoomLevel;
|
||||
this.tooltips = [];
|
||||
this.isMarketCluster = markerClusteringSetting.isMarketCluster;
|
||||
this.isMarketCluster = markerClusteringSetting && markerClusteringSetting.isMarketCluster;
|
||||
|
||||
if (!mapProvider) {
|
||||
mapProvider = {
|
||||
@ -150,8 +150,10 @@ export default class TbOpenStreetMap {
|
||||
onMarkerIconReady(iconInfo);
|
||||
}
|
||||
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
|
||||
var marker = L.marker(location, {});
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs, onDragendListener) {
|
||||
var marker = L.marker(location, {
|
||||
draggable: settings.drraggable
|
||||
});
|
||||
var opMap = this;
|
||||
this.createMarkerIcon(marker, settings, (iconInfo) => {
|
||||
marker.setIcon(iconInfo.icon);
|
||||
@ -171,6 +173,10 @@ export default class TbOpenStreetMap {
|
||||
marker.on('click', onClickListener);
|
||||
}
|
||||
|
||||
if (onDragendListener) {
|
||||
marker.on('dragend', onDragendListener);
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
@ -326,4 +332,8 @@ export default class TbOpenStreetMap {
|
||||
return this.tooltips;
|
||||
}
|
||||
|
||||
getCenter() {
|
||||
return this.map.getCenter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@ -28,7 +28,7 @@ export default class TbTencentMap {
|
||||
this.tooltips = [];
|
||||
this.defaultMapType = tmDefaultMapType;
|
||||
this.defaultCenterPosition =defaultCenterPosition;
|
||||
this.isMarketCluster = markerClusteringSetting.isMarketCluster;
|
||||
this.isMarketCluster = markerClusteringSetting && markerClusteringSetting.isMarketCluster;
|
||||
|
||||
function clearGlobalId() {
|
||||
if (tmGlobals.loadingTmId && tmGlobals.loadingTmId === tbMap.mapId) {
|
||||
@ -239,7 +239,7 @@ export default class TbTencentMap {
|
||||
/* eslint-enable no-undef */
|
||||
|
||||
/* eslint-disable no-undef */
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs) {
|
||||
createMarker(location, dsIndex, settings, onClickListener, markerArgs, onDragendListener) {
|
||||
var marker = new qq.maps.Marker({
|
||||
position: location
|
||||
});
|
||||
@ -260,7 +260,8 @@ export default class TbTencentMap {
|
||||
visible: true,
|
||||
position: location,
|
||||
map: tMap.map,
|
||||
zIndex: 1000
|
||||
zIndex: 1000,
|
||||
draggable: settings.drraggable
|
||||
});
|
||||
}
|
||||
});
|
||||
@ -273,6 +274,10 @@ export default class TbTencentMap {
|
||||
qq.maps.event.addListener(marker, 'click', onClickListener);
|
||||
}
|
||||
|
||||
if (onDragendListener) {
|
||||
qq.maps.event.addListener(marker, 'dragend', onDragendListener);
|
||||
}
|
||||
|
||||
return marker;
|
||||
}
|
||||
|
||||
@ -487,4 +492,8 @@ export default class TbTencentMap {
|
||||
return this.tooltips;
|
||||
}
|
||||
|
||||
getCenter() {
|
||||
return this.map.getCenter();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user