diff --git a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/AbstractSyncSessionCallback.java b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/AbstractSyncSessionCallback.java index 1097d5dd1a..03de2d0ac9 100644 --- a/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/AbstractSyncSessionCallback.java +++ b/common/transport/coap/src/main/java/org/thingsboard/server/transport/coap/callback/AbstractSyncSessionCallback.java @@ -21,6 +21,7 @@ import org.eclipse.californium.core.coap.MediaTypeRegistry; import org.eclipse.californium.core.coap.Request; import org.eclipse.californium.core.coap.Response; import org.eclipse.californium.core.server.resources.CoapExchange; +import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.gen.transport.TransportProtos; import org.thingsboard.server.transport.coap.client.TbCoapClientState; @@ -52,6 +53,11 @@ public abstract class AbstractSyncSessionCallback implements SessionMsgListener } + @Override + public void onDeviceDeleted(DeviceId deviceId) { + + } + @Override public void onToDeviceRpcRequest(UUID sessionId, TransportProtos.ToDeviceRpcRequestMsg toDeviceRequest) { logUnsupportedCommandMessage(toDeviceRequest); diff --git a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java index 06169a040d..de9619cb9f 100644 --- a/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java +++ b/common/transport/http/src/main/java/org/thingsboard/server/transport/http/DeviceApiController.java @@ -603,6 +603,13 @@ public class DeviceApiController implements TbTransportService { responseWriter.setResult(new ResponseEntity<>(JsonConverter.toJson(msg).toString(), HttpStatus.OK)); } + @Override + public void onDeviceDeleted(DeviceId deviceId) { + UUID sessionId = new UUID(sessionInfo.getSessionIdMSB(), sessionInfo.getSessionIdLSB()); + log.trace("[{}] Received device deleted notification for device with id: {}",sessionId, deviceId); + responseWriter.setResult(new ResponseEntity<>("Device was deleted!", HttpStatus.FORBIDDEN)); + } + } private static MediaType parseMediaType(String contentType) { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java index 23238a07a5..8f6fe7cdb2 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/DefaultLwM2mTransportService.java @@ -71,7 +71,7 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { private LeshanServer server; - @AfterStartUp + @AfterStartUp(order = Integer.MAX_VALUE - 1) public void init() { this.server = getLhServer(); /* @@ -83,8 +83,8 @@ public class DefaultLwM2mTransportService implements LwM2MTransportService { */ LwM2mTransportCoapResource otaCoapResource = new LwM2mTransportCoapResource(otaPackageDataCache, FIRMWARE_UPDATE_COAP_RESOURCE); this.server.coap().getServer().add(otaCoapResource); - this.startLhServer(); this.context.setServer(server); + this.startLhServer(); } private void startLhServer() { diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java index 04b8f858c6..9b04efa646 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClient.java @@ -20,6 +20,7 @@ import lombok.Getter; import lombok.Setter; import lombok.ToString; import lombok.extern.slf4j.Slf4j; +import org.eclipse.leshan.core.link.LinkParamValue; import org.eclipse.leshan.core.model.ObjectModel; import org.eclipse.leshan.core.model.ResourceModel; import org.eclipse.leshan.core.node.LwM2mMultipleResource; @@ -108,7 +109,7 @@ public class LwM2mClient implements Serializable { @Getter private Long edrxCycle; @Getter - private Registration registration; + private transient Registration registration; @Getter @Setter private boolean asleep; @@ -121,9 +122,9 @@ public class LwM2mClient implements Serializable { private boolean firstEdrxDownlink = true; @Getter - private Set clientSupportContentFormats; + private transient Set clientSupportContentFormats; @Getter - private ContentFormat defaultContentFormat; + private transient ContentFormat defaultContentFormat; @Getter private final AtomicInteger retryAttempts; @@ -430,9 +431,9 @@ public class LwM2mClient implements Serializable { static private Set clientSupportContentFormat(Registration registration) { Set contentFormats = new HashSet<>(); contentFormats.add(ContentFormat.DEFAULT); - String code = Arrays.stream(registration.getObjectLinks()).filter(link -> link.getUriReference().equals("/")).findFirst().get().getLinkParams().get("ct").getUnquoted(); - if (code != null) { - Set codes = Stream.of(code.replaceAll("\"", "").split(" ", -1)) + LinkParamValue ct = Arrays.stream(registration.getObjectLinks()).filter(link -> link.getUriReference().equals("/")).findFirst().get().getLinkParams().get("ct"); + if (ct != null) { + Set codes = Stream.of(ct.getUnquoted().replaceAll("\"", "").split(" ", -1)) .map(String::trim) .map(Integer::parseInt) .map(ContentFormat::fromCode) diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java index eb675c9461..a4c92de9b1 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/client/LwM2mClientContextImpl.java @@ -20,6 +20,7 @@ import lombok.extern.slf4j.Slf4j; import org.eclipse.leshan.core.SecurityMode; import org.eclipse.leshan.core.node.LwM2mPath; import org.eclipse.leshan.server.registration.Registration; +import org.eclipse.leshan.server.registration.RegistrationStore; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.context.annotation.Lazy; import org.springframework.stereotype.Service; @@ -72,6 +73,7 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { private final LwM2MSessionManager sessionManager; private final TransportDeviceProfileCache deviceProfileCache; private final LwM2MModelConfigService modelConfigService; + private final RegistrationStore registrationStore; @Autowired @Lazy @@ -118,8 +120,11 @@ public class LwM2mClientContextImpl implements LwM2mClientContext { private void updateFetchedClient(String nodeId, LwM2mClient client) { boolean updated = false; - if (client.getRegistration() != null) { - lwM2mClientsByRegistrationId.put(client.getRegistration().getId(), client); + Registration registration = registrationStore.getRegistrationByEndpoint(client.getEndpoint()); + + if (registration != null) { + client.setRegistration(registration); + lwM2mClientsByRegistrationId.put(registration.getId(), client); } if (client.getSession() != null) { client.refreshSessionId(nodeId); diff --git a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcDownlinkRequestCallbackProxy.java b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcDownlinkRequestCallbackProxy.java index a31c132744..c26ef2c327 100644 --- a/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcDownlinkRequestCallbackProxy.java +++ b/common/transport/lwm2m/src/main/java/org/thingsboard/server/transport/lwm2m/server/rpc/RpcDownlinkRequestCallbackProxy.java @@ -111,7 +111,11 @@ public abstract class RpcDownlinkRequestCallbackProxy implements DownlinkR } protected void sendRpcReplyOnError(Exception e) { - reply(LwM2MRpcResponseBody.builder().result(ResponseCode.INTERNAL_SERVER_ERROR.getName()).error(e.getMessage()).build()); + String error = e.getMessage(); + if (error == null) { + error = e.toString(); + } + reply(LwM2MRpcResponseBody.builder().result(ResponseCode.INTERNAL_SERVER_ERROR.getName()).error(error).build()); } } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java index 7f27c91f1c..75ec21a8df 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/MqttTransportHandler.java @@ -48,6 +48,7 @@ import org.thingsboard.server.common.data.DeviceProfile; import org.thingsboard.server.common.data.DeviceTransportType; import org.thingsboard.server.common.data.TransportPayloadType; import org.thingsboard.server.common.data.device.profile.MqttTopics; +import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.id.OtaPackageId; import org.thingsboard.server.common.data.ota.OtaPackageType; import org.thingsboard.server.common.data.rpc.RpcStatus; @@ -1066,4 +1067,11 @@ public class MqttTransportHandler extends ChannelInboundHandlerAdapter implement deviceSessionCtx.onDeviceUpdate(sessionInfo, device, deviceProfileOpt); } + @Override + public void onDeviceDeleted(DeviceId deviceId) { + context.onAuthFailure(address); + ChannelHandlerContext ctx = deviceSessionCtx.getChannel(); + ctx.close(); + } + } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java index b01e4e120e..debdab87b5 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewayDeviceSessionCtx.java @@ -19,6 +19,7 @@ import io.netty.channel.ChannelFuture; import io.netty.handler.codec.mqtt.MqttMessage; import lombok.extern.slf4j.Slf4j; import org.thingsboard.server.common.data.DeviceProfile; +import org.thingsboard.server.common.data.id.DeviceId; import org.thingsboard.server.common.data.rpc.RpcStatus; import org.thingsboard.server.common.transport.SessionMsgListener; import org.thingsboard.server.common.transport.TransportService; @@ -136,6 +137,11 @@ public class GatewayDeviceSessionCtx extends MqttDeviceAwareSessionContext imple // This feature is not supported in the TB IoT Gateway yet. } + @Override + public void onDeviceDeleted(DeviceId deviceId) { + parent.onDeviceDeleted(this.getSessionInfo().getDeviceName()); + } + private boolean isAckExpected(MqttMessage message) { return message.fixedHeader().qosLevel().value() > 0; } diff --git a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java index 7fc48d922a..d91935086b 100644 --- a/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java +++ b/common/transport/mqtt/src/main/java/org/thingsboard/server/transport/mqtt/session/GatewaySessionHandler.java @@ -178,6 +178,10 @@ public class GatewaySessionHandler { devices.forEach(this::deregisterSession); } + public void onDeviceDeleted(String deviceName) { + deregisterSession(deviceName); + } + public String getNodeId() { return context.getNodeId(); } diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java index f0c8152979..27ee61c700 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/SessionMsgListener.java @@ -45,6 +45,8 @@ public interface SessionMsgListener { void onToServerRpcResponse(ToServerRpcResponseMsg toServerResponse); + void onDeviceDeleted(DeviceId deviceId); + default void onUplinkNotification(UplinkNotificationMsg notificationMsg){}; default void onToTransportUpdateCredentials(ToTransportUpdateCredentialsProto toTransportUpdateCredentials){} @@ -54,8 +56,6 @@ public interface SessionMsgListener { default void onDeviceUpdate(TransportProtos.SessionInfoProto sessionInfo, Device device, Optional deviceProfileOpt) {} - default void onDeviceDeleted(DeviceId deviceId) {} - default void onResourceUpdate(TransportProtos.ResourceUpdateMsg resourceUpdateMsgOpt) {} default void onResourceDelete(TransportProtos.ResourceDeleteMsg resourceUpdateMsgOpt) {} diff --git a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java index e4c5f672a9..1ca7d80394 100644 --- a/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java +++ b/common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java @@ -91,6 +91,7 @@ import org.thingsboard.server.queue.provider.TbQueueProducerProvider; import org.thingsboard.server.queue.provider.TbTransportQueueFactory; import org.thingsboard.server.queue.scheduler.SchedulerComponent; import org.thingsboard.server.queue.usagestats.TbApiUsageClient; +import org.thingsboard.server.queue.util.AfterStartUp; import org.thingsboard.server.queue.util.TbTransportComponent; import javax.annotation.PostConstruct; @@ -227,6 +228,10 @@ public class DefaultTransportService implements TransportService { transportNotificationsConsumer.subscribe(Collections.singleton(tpi)); transportApiRequestTemplate.init(); mainConsumerExecutor = Executors.newSingleThreadExecutor(ThingsBoardThreadFactory.forName("transport-consumer")); + } + + @AfterStartUp + private void start() { mainConsumerExecutor.execute(() -> { while (!stopped) { try { diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java index efbb3b1068..336d75bb45 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttClientTest.java @@ -339,6 +339,21 @@ public class MqttClientTest extends AbstractContainerTest { restClient.getRestTemplate().delete(HTTPS_URL + "/api/device/" + device.getId()); } + @Test + public void deviceDeletedClosingSession() throws Exception { + restClient.login("tenant@thingsboard.org", "tenant"); + String deviceForDeletingTestName = "Device for deleting notification test"; + Device device = createDevice(deviceForDeletingTestName); + DeviceCredentials deviceCredentials = restClient.getDeviceCredentialsByDeviceId(device.getId()).get(); + + MqttMessageListener listener = new MqttMessageListener(); + MqttClient mqttClient = getMqttClient(deviceCredentials, listener); + + restClient.deleteDevice(device.getId()); + TimeUnit.SECONDS.sleep(3); + Assert.assertFalse(mqttClient.isConnected()); + } + private RuleChainId createRootRuleChainForRpcResponse() throws Exception { RuleChain newRuleChain = new RuleChain(); newRuleChain.setName("testRuleChain"); diff --git a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java index d66af565f4..951efd6dfe 100644 --- a/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java +++ b/msa/black-box-tests/src/test/java/org/thingsboard/server/msa/connectivity/MqttGatewayClientTest.java @@ -374,7 +374,15 @@ public class MqttGatewayClientTest extends AbstractContainerTest { Assert.assertEquals(clientResponse.toString(), serverResponse.getBody()); } - private void checkAttribute(boolean client, String expectedValue) throws Exception{ + @Test + public void deviceCreationAfterDeleted() throws Exception { + restClient.getRestTemplate().delete(HTTPS_URL + "/api/device/" + this.createdDevice.getId()); + Optional deletedDevice = restClient.getDeviceById(this.createdDevice.getId()); + Assert.assertTrue(deletedDevice.isEmpty()); + this.createdDevice = createDeviceThroughGateway(mqttClient, gatewayDevice); + } + + private void checkAttribute(boolean client, String expectedValue) throws Exception { JsonObject gatewayAttributesRequest = new JsonObject(); int messageId = new Random().nextInt(100); gatewayAttributesRequest.addProperty("id", messageId); diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts index 2d3b634050..c360846941 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-page.component.ts @@ -134,6 +134,7 @@ import { import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import cssjs from '@core/css/css'; import { DOCUMENT } from '@angular/common'; +import { IAliasController } from '@core/api/widget-api.models'; // @dynamic @Component({ @@ -179,6 +180,9 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC @Input() parentDashboard?: IDashboardComponent = null; + @Input() + parentAliasController?: IAliasController = null; + @ViewChild('dashboardContainer') dashboardContainer: ElementRef; prevDashboard: Dashboard; @@ -419,7 +423,7 @@ export class DashboardPageComponent extends PageComponent implements IDashboardC this.readonly = this.embedded || (this.singlePageMode && !this.widgetEditMode && !this.route.snapshot.queryParamMap.get('edit')) || this.forceFullscreen || this.isMobileApp || this.authUser.authority === Authority.CUSTOMER_USER; - this.dashboardCtx.aliasController = new AliasController(this.utils, + this.dashboardCtx.aliasController = this.parentAliasController ? this.parentAliasController : new AliasController(this.utils, this.entityService, this.translate, () => this.dashboardCtx.stateController, diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.html b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.html index b7ead22172..c03c253af2 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.html +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.html @@ -21,7 +21,8 @@ [hideToolbar]="true" [currentState]="currentState" [dashboard]="dashboard" - [parentDashboard]="parentDashboard"> + [parentDashboard]="parentDashboard" + [parentAliasController]="parentAliasController">
{{ 'dashboard.non-existent-dashboard-state-error' | translate:{stateId} }} diff --git a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.ts b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.ts index 88ddfd0082..50863b0595 100644 --- a/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.ts +++ b/ui-ngx/src/app/modules/home/components/dashboard-page/dashboard-state.component.ts @@ -19,7 +19,7 @@ import { PageComponent } from '@shared/components/page.component'; import { Store } from '@ngrx/store'; import { AppState } from '@core/core.state'; import { Dashboard, DashboardLayoutId } from '@shared/models/dashboard.models'; -import { StateObject } from '@core/api/widget-api.models'; +import { IAliasController, StateObject } from '@core/api/widget-api.models'; import { updateEntityParams, WidgetContext } from '@home/models/widget-component.models'; import { deepClone, isDefinedAndNotNull, isNotEmptyStr, objToBase64 } from '@core/utils'; import { IDashboardComponent } from '@home/models/dashboard-component.models'; @@ -63,6 +63,8 @@ export class DashboardStateComponent extends PageComponent implements OnInit, On parentDashboard: IDashboardComponent; + parentAliasController: IAliasController; + stateExists = true; private stateSubscription: Subscription; @@ -92,6 +94,7 @@ export class DashboardStateComponent extends PageComponent implements OnInit, On this.parentDashboard = this.ctx.parentDashboard ? this.ctx.parentDashboard : this.ctx.dashboard; if (this.syncParentStateParams) { + this.parentAliasController = this.parentDashboard.aliasController; this.stateSubscription = this.ctx.stateController.dashboardCtrl.dashboardCtx.stateChanged.subscribe(() => { this.updateCurrentState(); this.cd.markForCheck(); 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 0482f4cec5..bb939572f5 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 @@ -41,6 +41,22 @@ export function createTooltip(target: L.Layer, return popup; } +export function disablePopup(target: L.Layer) { + if (target.isPopupOpen()) { + target.closePopup(); + } + target.unbindPopup(); + target.off('popupopen'); +} + +export function enablePopup(target: L.Layer, popup: L.Popup, + settings: MarkerSettings | PolylineSettings | PolygonSettings, datasource: Datasource) { + target.bindPopup(popup); + target.on('popupopen', () => { + bindPopupActions(popup, settings, datasource); + }); +} + export function bindPopupActions(popup: L.Popup, settings: MarkerSettings | PolylineSettings | PolygonSettings, datasource: Datasource) { const actions = popup.getElement().getElementsByClassName('tb-custom-action'); 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 4c840a635e..d9e297b1cb 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 @@ -23,7 +23,7 @@ import { MarkerSettings, UnitedMapSettings } from './map-models'; -import { bindPopupActions, createTooltip, } from './maps-utils'; +import { bindPopupActions, createTooltip, disablePopup, enablePopup, } from './maps-utils'; import { aspectCache, fillPattern, parseWithTranslation, processPattern, safeExecute } from './common-maps-utils'; import tinycolor from 'tinycolor2'; import { isDefined, isDefinedAndNotNull } from '@core/utils'; @@ -37,6 +37,7 @@ export class Marker { tooltip: L.Popup; data: FormattedData; dataSources: FormattedData[]; + isDragging = false; constructor(private map: LeafletMap, private location: L.LatLng, public settings: UnitedMapSettings, data?: FormattedData, dataSources?, onDragendListener?) { @@ -64,17 +65,31 @@ export class Marker { } if (this.settings.markerClick) { - this.leafletMarker.on('click', (event: LeafletMouseEvent) => { - for (const action in this.settings.markerClick) { + if (!this.isDragging) { + this.leafletMarker.on('click', (event: LeafletMouseEvent) => { + for (const action in this.settings.markerClick) { if (typeof (this.settings.markerClick[action]) === 'function') { - this.settings.markerClick[action](event.originalEvent, this.data.$datasource); + this.settings.markerClick[action](event.originalEvent, this.data.$datasource); } - } - }); + } + }); + } } if (settings.draggableMarker && onDragendListener) { - this.leafletMarker.on('pm:dragend', (e) => onDragendListener(e, this.data)); + this.leafletMarker.on('pm:dragend', (e) => { + onDragendListener(e, this.data); + this.isDragging = false; + if (settings.showTooltip && settings.showTooltipAction === 'click') { + enablePopup(this.leafletMarker, this.tooltip, settings, this.data.$datasource); + } + }); + this.leafletMarker.on('pm:dragstart', (e) => { + this.isDragging = true; + if (settings.showTooltip && settings.showTooltipAction === 'click') { + disablePopup(this.leafletMarker); + } + }); } }