Browse Source

Merge branch 'master' of https://github.com/thingsboard/thingsboard

pull/3604/head
zbeacon 6 years ago
parent
commit
c2bd4117e4
  1. 4
      common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java
  2. 26
      common/queue/src/main/java/org/thingsboard/server/queue/util/TbTransportComponent.java
  3. 3
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java
  4. 72
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java
  5. 5
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DummyTransportRateLimit.java
  6. 4
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/SimpleTransportRateLimit.java
  7. 2
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimit.java
  8. 4
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimitService.java
  9. 24
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimitType.java
  10. 3
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportDeviceProfileCache.java
  11. 44
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java
  12. 3
      common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportTenantProfileCache.java
  13. 6
      ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html
  14. 7
      ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.ts
  15. 16
      ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts
  16. 35
      ui-ngx/src/app/shared/components/entity/entity-select.component.ts
  17. 10
      ui-ngx/src/app/shared/components/js-func.component.ts
  18. 49
      ui-ngx/src/app/shared/components/json-content.component.ts

4
common/message/src/main/java/org/thingsboard/server/common/msg/tools/TbRateLimits.java

@ -50,4 +50,8 @@ public class TbRateLimits {
return bucket.tryConsume(1);
}
public boolean tryConsume(long number) {
return bucket.tryConsume(number);
}
}

26
common/queue/src/main/java/org/thingsboard/server/queue/util/TbTransportComponent.java

@ -0,0 +1,26 @@
/**
* Copyright © 2016-2020 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.
*/
package org.thingsboard.server.queue.util;
import org.springframework.boot.autoconfigure.condition.ConditionalOnExpression;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
@Retention(RetentionPolicy.RUNTIME)
@ConditionalOnExpression("('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport'")
public @interface TbTransportComponent {
}

3
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/TransportService.java

@ -20,6 +20,7 @@ import org.thingsboard.server.common.data.DeviceTransportType;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.transport.auth.GetOrCreateDeviceFromGatewayResponse;
import org.thingsboard.server.common.transport.auth.ValidateDeviceCredentialsResponse;
import org.thingsboard.server.common.transport.limits.TransportRateLimitType;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.gen.transport.TransportProtos.ClaimDeviceMsg;
import org.thingsboard.server.gen.transport.TransportProtos.GetAttributeRequestMsg;
@ -69,6 +70,8 @@ public interface TransportService {
boolean checkLimits(SessionInfoProto sessionInfo, Object msg, TransportServiceCallback<Void> callback);
boolean checkLimits(SessionInfoProto sessionInfo, Object msg, TransportServiceCallback<Void> callback, int dataPoints, TransportRateLimitType... limits);
void process(SessionInfoProto sessionInfo, SessionEventMsg msg, TransportServiceCallback<Void> callback);
void process(SessionInfoProto sessionInfo, PostTelemetryMsg msg, TransportServiceCallback<Void> callback);

72
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DefaultTransportRateLimitService.java

@ -23,11 +23,13 @@ import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.transport.TransportTenantProfileCache;
import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
@Service
@TbTransportComponent
@Slf4j
public class DefaultTransportRateLimitService implements TransportRateLimitService {
@ -43,23 +45,21 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi
}
@Override
public TransportRateLimit getRateLimit(TenantId tenantId, TransportRateLimitType limitType) {
TransportRateLimit[] limits = perTenantLimits.get(tenantId);
if (limits == null) {
limits = fetchProfileAndInit(tenantId);
perTenantLimits.put(tenantId, limits);
}
return limits[limitType.ordinal()];
}
@Override
public TransportRateLimit getRateLimit(TenantId tenantId, DeviceId deviceId, TransportRateLimitType limitType) {
TransportRateLimit[] limits = perDeviceLimits.get(deviceId);
if (limits == null) {
limits = fetchProfileAndInit(tenantId);
perDeviceLimits.put(deviceId, limits);
public TransportRateLimitType checkLimits(TenantId tenantId, DeviceId deviceId, int dataPoints, TransportRateLimitType... limits) {
TransportRateLimit[] tenantLimits = getTenantRateLimits(tenantId);
TransportRateLimit[] deviceLimits = getDeviceRateLimits(tenantId, deviceId);
for (TransportRateLimitType limitType : limits) {
TransportRateLimit rateLimit;
if (limitType.isTenantLevel()) {
rateLimit = tenantLimits[limitType.ordinal()];
} else {
rateLimit = deviceLimits[limitType.ordinal()];
}
if (!rateLimit.tryConsume(limitType.isMessageLevel() ? 1L : dataPoints)) {
return limitType;
}
}
return limits[limitType.ordinal()];
return null;
}
@Override
@ -75,7 +75,17 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi
mergeLimits(tenantId, fetchProfileAndInit(tenantId));
}
public void mergeLimits(TenantId tenantId, TransportRateLimit[] newRateLimits) {
@Override
public void remove(TenantId tenantId) {
perTenantLimits.remove(tenantId);
}
@Override
public void remove(DeviceId deviceId) {
perDeviceLimits.remove(deviceId);
}
private void mergeLimits(TenantId tenantId, TransportRateLimit[] newRateLimits) {
TransportRateLimit[] oldRateLimits = perTenantLimits.get(tenantId);
if (oldRateLimits == null) {
perTenantLimits.put(tenantId, newRateLimits);
@ -90,16 +100,6 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi
}
}
@Override
public void remove(TenantId tenantId) {
perTenantLimits.remove(tenantId);
}
@Override
public void remove(DeviceId deviceId) {
perDeviceLimits.remove(deviceId);
}
private TransportRateLimit[] fetchProfileAndInit(TenantId tenantId) {
return perTenantLimits.computeIfAbsent(tenantId, tmp -> createTransportRateLimits(tenantProfileCache.get(tenantId)));
}
@ -112,4 +112,22 @@ public class DefaultTransportRateLimitService implements TransportRateLimitServi
}
return rateLimits;
}
private TransportRateLimit[] getTenantRateLimits(TenantId tenantId) {
TransportRateLimit[] limits = perTenantLimits.get(tenantId);
if (limits == null) {
limits = fetchProfileAndInit(tenantId);
perTenantLimits.put(tenantId, limits);
}
return limits;
}
private TransportRateLimit[] getDeviceRateLimits(TenantId tenantId, DeviceId deviceId) {
TransportRateLimit[] limits = perDeviceLimits.get(deviceId);
if (limits == null) {
limits = fetchProfileAndInit(tenantId);
perDeviceLimits.put(deviceId, limits);
}
return limits;
}
}

5
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/DummyTransportRateLimit.java

@ -22,6 +22,11 @@ public class DummyTransportRateLimit implements TransportRateLimit {
return "";
}
@Override
public boolean tryConsume(long number) {
return true;
}
@Override
public boolean tryConsume() {
return true;

4
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/SimpleTransportRateLimit.java

@ -31,4 +31,8 @@ public class SimpleTransportRateLimit implements TransportRateLimit {
return rateLimit.tryConsume();
}
@Override
public boolean tryConsume(long number) {
return number <= 0 || rateLimit.tryConsume(number);
}
}

2
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimit.java

@ -21,4 +21,6 @@ public interface TransportRateLimit {
boolean tryConsume();
boolean tryConsume(long number);
}

4
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimitService.java

@ -21,9 +21,7 @@ import org.thingsboard.server.common.transport.profile.TenantProfileUpdateResult
public interface TransportRateLimitService {
TransportRateLimit getRateLimit(TenantId tenantId, TransportRateLimitType limit);
TransportRateLimit getRateLimit(TenantId tenantId, DeviceId deviceId, TransportRateLimitType limit);
TransportRateLimitType checkLimits(TenantId tenantId, DeviceId deviceId, int dataPoints, TransportRateLimitType... limits);
void update(TenantProfileUpdateResult update);

24
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/limits/TransportRateLimitType.java

@ -19,15 +19,29 @@ import lombok.Getter;
public enum TransportRateLimitType {
TENANT_MAX_MSGS("transport.tenant.max.msg"),
TENANT_MAX_DATA_POINTS("transport.tenant.max.dataPoints"),
DEVICE_MAX_MSGS("transport.device.max.msg"),
DEVICE_MAX_DATA_POINTS("transport.device.max.dataPoints");
TENANT_MAX_MSGS("transport.tenant.msg", true, true),
TENANT_TELEMETRY_MSGS("transport.tenant.telemetry", true, true),
TENANT_MAX_DATA_POINTS("transport.tenant.dataPoints", true, false),
DEVICE_MAX_MSGS("transport.device.msg", false, true),
DEVICE_TELEMETRY_MSGS("transport.device.telemetry", false, true),
DEVICE_MAX_DATA_POINTS("transport.device.dataPoints", false, false);
@Getter
private final String configurationKey;
@Getter
private final boolean tenantLevel;
@Getter
private final boolean deviceLevel;
@Getter
private final boolean messageLevel;
@Getter
private final boolean dataPointLevel;
TransportRateLimitType(String configurationKey) {
TransportRateLimitType(String configurationKey, boolean tenantLevel, boolean messageLevel) {
this.configurationKey = configurationKey;
this.tenantLevel = tenantLevel;
this.deviceLevel = !tenantLevel;
this.messageLevel = messageLevel;
this.dataPointLevel = !messageLevel;
}
}

3
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportDeviceProfileCache.java

@ -23,6 +23,7 @@ import org.thingsboard.server.common.data.DeviceProfile;
import org.thingsboard.server.common.data.id.DeviceProfileId;
import org.thingsboard.server.common.transport.TransportDeviceProfileCache;
import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Optional;
import java.util.concurrent.ConcurrentHashMap;
@ -30,7 +31,7 @@ import java.util.concurrent.ConcurrentMap;
@Slf4j
@Component
@ConditionalOnExpression("('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport'")
@TbTransportComponent
public class DefaultTransportDeviceProfileCache implements TransportDeviceProfileCache {
private final ConcurrentMap<DeviceProfileId, DeviceProfile> deviceProfiles = new ConcurrentHashMap<>();

44
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportService.java

@ -79,6 +79,7 @@ import org.thingsboard.server.queue.discovery.PartitionService;
import org.thingsboard.server.queue.discovery.TbServiceInfoProvider;
import org.thingsboard.server.queue.provider.TbQueueProducerProvider;
import org.thingsboard.server.queue.provider.TbTransportQueueFactory;
import org.thingsboard.server.queue.util.TbTransportComponent;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;
@ -103,7 +104,7 @@ import java.util.concurrent.atomic.AtomicInteger;
*/
@Slf4j
@Service
@ConditionalOnExpression("('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport'")
@TbTransportComponent
public class DefaultTransportService implements TransportService {
@Value("${transport.sessions.inactivity_timeout}")
@ -363,7 +364,11 @@ public class DefaultTransportService implements TransportService {
@Override
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostTelemetryMsg msg, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) {
int dataPoints = 0;
for (TransportProtos.TsKvListProto tsKv : msg.getTsKvListList()) {
dataPoints += tsKv.getKvCount();
}
if (checkLimits(sessionInfo, msg, callback, dataPoints, TELEMETRY)) {
reportActivityInternal(sessionInfo);
TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
@ -384,7 +389,7 @@ public class DefaultTransportService implements TransportService {
@Override
public void process(TransportProtos.SessionInfoProto sessionInfo, TransportProtos.PostAttributeMsg msg, TransportServiceCallback<Void> callback) {
if (checkLimits(sessionInfo, msg, callback)) {
if (checkLimits(sessionInfo, msg, callback, msg.getKvCount(), TELEMETRY)) {
reportActivityInternal(sessionInfo);
TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
@ -574,37 +579,34 @@ public class DefaultTransportService implements TransportService {
sessions.remove(toSessionId(sessionInfo));
}
private TransportRateLimitType[] DEFAULT = new TransportRateLimitType[]{TransportRateLimitType.TENANT_MAX_MSGS, TransportRateLimitType.DEVICE_MAX_MSGS};
private TransportRateLimitType[] TELEMETRY = TransportRateLimitType.values();
@Override
public boolean checkLimits(TransportProtos.SessionInfoProto sessionInfo, Object msg, TransportServiceCallback<Void> callback) {
return checkLimits(sessionInfo, msg, callback, 0, DEFAULT);
}
@Override
public boolean checkLimits(TransportProtos.SessionInfoProto sessionInfo, Object msg, TransportServiceCallback<Void> callback, int dataPoints, TransportRateLimitType... limits) {
if (log.isTraceEnabled()) {
log.trace("[{}] Processing msg: {}", toSessionId(sessionInfo), msg);
}
TenantId tenantId = new TenantId(new UUID(sessionInfo.getTenantIdMSB(), sessionInfo.getTenantIdLSB()));
TransportRateLimit tenantRateLimit = rateLimitService.getRateLimit(tenantId, TransportRateLimitType.TENANT_MAX_MSGS);
if (!tenantRateLimit.tryConsume()) {
if (callback != null) {
callback.onError(new TbRateLimitsException(EntityType.TENANT));
}
if (log.isTraceEnabled()) {
log.trace("[{}][{}] Tenant level rate limit detected: {}", toSessionId(sessionInfo), tenantId, msg);
}
return false;
}
DeviceId deviceId = new DeviceId(new UUID(sessionInfo.getDeviceIdMSB(), sessionInfo.getDeviceIdLSB()));
TransportRateLimit deviceRateLimit = rateLimitService.getRateLimit(tenantId, deviceId, TransportRateLimitType.DEVICE_MAX_MSGS);
if (!deviceRateLimit.tryConsume()) {
TransportRateLimitType limit = rateLimitService.checkLimits(tenantId, deviceId, 0, limits);
if (limit == null) {
return true;
} else {
if (callback != null) {
callback.onError(new TbRateLimitsException(EntityType.DEVICE));
callback.onError(new TbRateLimitsException(limit.isTenantLevel() ? EntityType.TENANT : EntityType.DEVICE));
}
if (log.isTraceEnabled()) {
log.trace("[{}][{}] Device level rate limit detected: {}", toSessionId(sessionInfo), deviceId, msg);
log.trace("[{}][{}] {} rateLimit detected: {}", toSessionId(sessionInfo), tenantId, limit, msg);
}
return false;
}
return true;
}
protected void processToTransportMsg(TransportProtos.ToTransportMsg toSessionMsg) {

3
common/transport/transport-api/src/main/java/org/thingsboard/server/common/transport/service/DefaultTransportTenantProfileCache.java

@ -33,6 +33,7 @@ import org.thingsboard.server.common.transport.util.DataDecodingEncodingService;
import org.thingsboard.server.gen.transport.TransportProtos;
import org.thingsboard.server.queue.discovery.TenantRoutingInfo;
import org.thingsboard.server.queue.discovery.TenantRoutingInfoService;
import org.thingsboard.server.queue.util.TbTransportComponent;
import java.util.Collections;
import java.util.Optional;
@ -43,7 +44,7 @@ import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
@Component
@ConditionalOnExpression("('${service.type:null}'=='monolith' && '${transport.api_enabled:true}'=='true') || '${service.type:null}'=='tb-transport'")
@TbTransportComponent
@Slf4j
public class DefaultTransportTenantProfileCache implements TransportTenantProfileCache {

6
ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.html

@ -91,6 +91,12 @@
</mat-error>
</mat-form-field>
</div>
<div fxLayout="column" fxLayoutAlign="flex-end start">
<tb-rule-chain-autocomplete
labelText="device-profile.default-rule-chain"
formControlName="defaultRuleChainId">
</tb-rule-chain-autocomplete>
</div>
</div>
<mat-checkbox formControlName="gateway" style="padding-bottom: 16px;">
{{ 'device.is-gateway' | translate }}

7
ui-ngx/src/app/modules/home/components/wizard/device-wizard-dialog.component.ts

@ -42,6 +42,7 @@ import { ErrorStateMatcher } from '@angular/material/core';
import { StepperSelectionEvent } from '@angular/cdk/stepper';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { MediaBreakpoints } from '@shared/models/constants';
import { RuleChainId } from '@shared/models/id/rule-chain-id';
@Component({
selector: 'tb-device-wizard',
@ -103,6 +104,7 @@ export class DeviceWizardDialogComponent extends
addProfileType: [0],
deviceProfileId: [null, Validators.required],
newDeviceProfileTitle: [{value: null, disabled: true}],
defaultRuleChainId: [{value: null, disabled: true}],
description: ['']
}
);
@ -114,6 +116,7 @@ export class DeviceWizardDialogComponent extends
this.deviceWizardFormGroup.get('deviceProfileId').enable();
this.deviceWizardFormGroup.get('newDeviceProfileTitle').setValidators(null);
this.deviceWizardFormGroup.get('newDeviceProfileTitle').disable();
this.deviceWizardFormGroup.get('defaultRuleChainId').disable();
this.deviceWizardFormGroup.updateValueAndValidity();
this.createProfile = false;
this.createTransportConfiguration = false;
@ -122,6 +125,7 @@ export class DeviceWizardDialogComponent extends
this.deviceWizardFormGroup.get('deviceProfileId').disable();
this.deviceWizardFormGroup.get('newDeviceProfileTitle').setValidators([Validators.required]);
this.deviceWizardFormGroup.get('newDeviceProfileTitle').enable();
this.deviceWizardFormGroup.get('defaultRuleChainId').enable();
this.deviceWizardFormGroup.updateValueAndValidity();
this.createProfile = true;
this.createTransportConfiguration = this.deviceWizardFormGroup.get('transportType').value &&
@ -274,6 +278,9 @@ export class DeviceWizardDialogComponent extends
provisionConfiguration: deviceProvisionConfiguration
}
};
if (this.deviceWizardFormGroup.get('defaultRuleChainId').value) {
deviceProfile.defaultRuleChainId = new RuleChainId(this.deviceWizardFormGroup.get('defaultRuleChainId').value);
}
return this.deviceProfileService.saveDeviceProfile(deviceProfile).pipe(
map(profile => profile.id),
tap((profileId) => {

16
ui-ngx/src/app/modules/home/pages/admin/oauth2-settings.component.ts

@ -142,6 +142,7 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
tenantNamePattern = {value: null, disabled: true};
}
const basicGroup = this.fb.group({
emailAttributeKey: [mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required],
firstNameAttributeKey: [mapperConfigBasic?.firstNameAttributeKey ? mapperConfigBasic.firstNameAttributeKey : ''],
lastNameAttributeKey: [mapperConfigBasic?.lastNameAttributeKey ? mapperConfigBasic.lastNameAttributeKey : ''],
tenantNameStrategy: [mapperConfigBasic?.tenantNameStrategy ? mapperConfigBasic.tenantNameStrategy : TenantNameStrategy.DOMAIN],
@ -151,11 +152,6 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
alwaysFullScreen: [isDefinedAndNotNull(mapperConfigBasic?.alwaysFullScreen) ? mapperConfigBasic.alwaysFullScreen : false]
});
if (MapperConfigType.GITHUB !== type) {
basicGroup.addControl('emailAttributeKey',
this.fb.control( mapperConfigBasic?.emailAttributeKey ? mapperConfigBasic.emailAttributeKey : 'email', Validators.required));
}
this.subscriptions.push(basicGroup.get('tenantNameStrategy').valueChanges.subscribe((domain) => {
if (domain === 'CUSTOM') {
basicGroup.get('tenantNamePattern').enable();
@ -358,11 +354,15 @@ export class OAuth2SettingsComponent extends PageComponent implements OnInit, Ha
mapperConfig.addControl('custom', this.formCustomGroup(predefinedValue?.custom));
} else {
mapperConfig.removeControl('custom');
if (mapperConfig.get('basic')) {
mapperConfig.setControl('basic', this.formBasicGroup(type, predefinedValue?.basic));
} else {
if (!mapperConfig.get('basic')) {
mapperConfig.addControl('basic', this.formBasicGroup(type, predefinedValue?.basic));
}
if (type === MapperConfigType.GITHUB) {
mapperConfig.get('basic.emailAttributeKey').disable();
mapperConfig.get('basic.emailAttributeKey').patchValue(null, {emitEvent: false});
} else {
mapperConfig.get('basic.emailAttributeKey').enable();
}
}
}

35
ui-ngx/src/app/shared/components/entity/entity-select.component.ts

@ -97,10 +97,6 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
ngOnInit() {
this.entitySelectFormGroup.get('entityType').valueChanges.subscribe(
(value) => {
if(value === AliasEntityType.CURRENT_TENANT || value === AliasEntityType.CURRENT_USER ||
value === AliasEntityType.CURRENT_USER_OWNER) {
this.modelValue.id = NULL_UUID;
}
this.updateView(value, this.modelValue.id);
}
);
@ -140,20 +136,23 @@ export class EntitySelectComponent implements ControlValueAccessor, OnInit, Afte
}
updateView(entityType: EntityType | AliasEntityType | null, entityId: string | null) {
if (this.modelValue.entityType !== entityType ||
this.modelValue.id !== entityId) {
this.modelValue = {
entityType,
id: this.modelValue.entityType !== entityType ? null : entityId
};
if (this.modelValue.entityType && (this.modelValue.id ||
this.modelValue.entityType === AliasEntityType.CURRENT_TENANT ||
this.modelValue.entityType === AliasEntityType.CURRENT_USER ||
this.modelValue.entityType === AliasEntityType.CURRENT_USER_OWNER)) {
this.propagateChange(this.modelValue);
} else {
this.propagateChange(null);
}
if (this.modelValue.entityType !== entityType || this.modelValue.id !== entityId) {
this.modelValue = {
entityType,
id: this.modelValue.entityType !== entityType ? null : entityId
};
if (this.modelValue.entityType === AliasEntityType.CURRENT_TENANT
|| this.modelValue.entityType === AliasEntityType.CURRENT_USER
|| this.modelValue.entityType === AliasEntityType.CURRENT_USER_OWNER) {
this.modelValue.id = NULL_UUID;
}
if (this.modelValue.entityType && this.modelValue.id) {
this.propagateChange(this.modelValue);
} else {
this.propagateChange(null);
}
}
}
}

10
ui-ngx/src/app/shared/components/js-func.component.ts

@ -36,7 +36,6 @@ import { TranslateService } from '@ngx-translate/core';
import { CancelAnimationFrame, RafService } from '@core/services/raf.service';
import { ResizeObserver } from '@juggle/resize-observer';
import { TbEditorCompleter } from '@shared/models/ace/completion.models';
import { widgetEditorCompleter } from '@home/pages/widget/widget-editor.models';
@Component({
selector: 'tb-js-func',
@ -64,6 +63,7 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor,
private jsEditor: ace.Ace.Editor;
private editorsResizeCaf: CancelAnimationFrame;
private editorResize$: ResizeObserver;
private ignoreChange = false;
toastTargetId = `jsFuncEditor-${guid()}`;
@ -154,8 +154,10 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor,
this.jsEditor.session.setUseWrapMode(true);
this.jsEditor.setValue(this.modelValue ? this.modelValue : '', -1);
this.jsEditor.on('change', () => {
this.cleanupJsErrors();
this.updateView();
if (!this.ignoreChange) {
this.cleanupJsErrors();
this.updateView();
}
});
if (this.editorCompleter) {
this.jsEditor.completers = [this.editorCompleter, ...(this.jsEditor.completers || [])];
@ -332,7 +334,9 @@ export class JsFuncComponent implements OnInit, OnDestroy, ControlValueAccessor,
writeValue(value: string): void {
this.modelValue = value;
if (this.jsEditor) {
this.ignoreChange = true;
this.jsEditor.setValue(this.modelValue ? this.modelValue : '', -1);
this.ignoreChange = false;
}
}

49
ui-ngx/src/app/shared/components/json-content.component.ts

@ -61,6 +61,7 @@ export class JsonContentComponent implements OnInit, ControlValueAccessor, Valid
private jsonEditor: ace.Ace.Editor;
private editorsResizeCaf: CancelAnimationFrame;
private editorResize$: ResizeObserver;
private ignoreChange = false;
toastTargetId = `jsonContentEditor-${guid()}`;
@ -140,8 +141,13 @@ export class JsonContentComponent implements OnInit, ControlValueAccessor, Valid
this.jsonEditor.session.setUseWrapMode(true);
this.jsonEditor.setValue(this.contentBody ? this.contentBody : '', -1);
this.jsonEditor.on('change', () => {
this.cleanupJsonErrors();
this.updateView();
if (!this.ignoreChange) {
this.cleanupJsonErrors();
this.updateView();
}
});
this.jsonEditor.on('blur', () => {
this.contentValid = !this.validateContent || this.doValidate(true);
});
this.editorResize$ = new ResizeObserver(() => {
this.onAceEditorResize();
@ -210,34 +216,36 @@ export class JsonContentComponent implements OnInit, ControlValueAccessor, Valid
this.cleanupJsonErrors();
this.contentValid = true;
this.propagateChange(this.contentBody);
this.contentValid = this.doValidate();
this.contentValid = this.doValidate(true);
this.propagateChange(this.contentBody);
}
}
private doValidate(): boolean {
private doValidate(showErrorToast = false): boolean {
try {
if (this.validateContent && this.contentType === ContentType.JSON) {
JSON.parse(this.contentBody);
}
return true;
} catch (ex) {
let errorInfo = 'Error:';
if (ex.name) {
errorInfo += ' ' + ex.name + ':';
}
if (ex.message) {
errorInfo += ' ' + ex.message;
if (showErrorToast) {
let errorInfo = 'Error:';
if (ex.name) {
errorInfo += ' ' + ex.name + ':';
}
if (ex.message) {
errorInfo += ' ' + ex.message;
}
this.store.dispatch(new ActionNotificationShow(
{
message: errorInfo,
type: 'error',
target: this.toastTargetId,
verticalPosition: 'bottom',
horizontalPosition: 'left'
}));
this.errorShowed = true;
}
this.store.dispatch(new ActionNotificationShow(
{
message: errorInfo,
type: 'error',
target: this.toastTargetId,
verticalPosition: 'bottom',
horizontalPosition: 'left'
}));
this.errorShowed = true;
return false;
}
}
@ -256,8 +264,9 @@ export class JsonContentComponent implements OnInit, ControlValueAccessor, Valid
this.contentBody = value;
this.contentValid = true;
if (this.jsonEditor) {
this.ignoreChange = true;
this.jsonEditor.setValue(this.contentBody ? this.contentBody : '', -1);
// this.jsonEditor.
this.ignoreChange = false;
}
}

Loading…
Cancel
Save