Commit 5cc3a93cb9b45fd3c65fd7eec1aab1586bdd3194

Authored by Igor Kulikov
1 parent 6a237b84

Introduce default dashboard for device profile

Showing 21 changed files with 108 additions and 12 deletions
... ... @@ -84,7 +84,8 @@ ALTER TABLE dashboard
84 84 ALTER TABLE device_profile
85 85 ADD COLUMN IF NOT EXISTS image varchar(1000000),
86 86 ADD COLUMN IF NOT EXISTS firmware_id uuid,
87   - ADD COLUMN IF NOT EXISTS software_id uuid;
  87 + ADD COLUMN IF NOT EXISTS software_id uuid,
  88 + ADD COLUMN IF NOT EXISTS default_dashboard_id uuid;
88 89
89 90 ALTER TABLE device
90 91 ADD COLUMN IF NOT EXISTS firmware_id uuid,
... ... @@ -109,6 +110,12 @@ DO $$
109 110 FOREIGN KEY (firmware_id) REFERENCES firmware(id);
110 111 END IF;
111 112
  113 + IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_default_dashboard_device_profile') THEN
  114 + ALTER TABLE device_profile
  115 + ADD CONSTRAINT fk_default_dashboard_device_profile
  116 + FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id);
  117 + END IF;
  118 +
112 119 IF NOT EXISTS (SELECT 1 FROM pg_constraint WHERE conname = 'fk_firmware_device') THEN
113 120 ALTER TABLE device
114 121 ADD CONSTRAINT fk_firmware_device
... ...
... ... @@ -313,7 +313,8 @@ public abstract class BaseDeviceProfileControllerTest extends AbstractController
313 313 Collections.sort(loadedDeviceProfileInfos, deviceProfileInfoIdComparator);
314 314
315 315 List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream().map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
316   - deviceProfile.getName(), deviceProfile.getImage(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList());
  316 + deviceProfile.getName(), deviceProfile.getImage(), deviceProfile.getDefaultDashboardId(),
  317 + deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList());
317 318
318 319 Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
319 320
... ...
... ... @@ -21,6 +21,7 @@ import lombok.Data;
21 21 import lombok.EqualsAndHashCode;
22 22 import lombok.extern.slf4j.Slf4j;
23 23 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
  24 +import org.thingsboard.server.common.data.id.DashboardId;
24 25 import org.thingsboard.server.common.data.id.DeviceProfileId;
25 26 import org.thingsboard.server.common.data.id.FirmwareId;
26 27 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -49,6 +50,7 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
49 50 private DeviceTransportType transportType;
50 51 private DeviceProfileProvisionType provisionType;
51 52 private RuleChainId defaultRuleChainId;
  53 + private DashboardId defaultDashboardId;
52 54 @NoXss
53 55 private String defaultQueueName;
54 56 @Valid
... ... @@ -78,6 +80,7 @@ public class DeviceProfile extends SearchTextBased<DeviceProfileId> implements H
78 80 this.image = deviceProfile.getImage();
79 81 this.isDefault = deviceProfile.isDefault();
80 82 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId();
  83 + this.defaultDashboardId = deviceProfile.getDefaultDashboardId();
81 84 this.defaultQueueName = deviceProfile.getDefaultQueueName();
82 85 this.setProfileData(deviceProfile.getProfileData());
83 86 this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
... ...
... ... @@ -20,6 +20,7 @@ import com.fasterxml.jackson.annotation.JsonProperty;
20 20 import lombok.EqualsAndHashCode;
21 21 import lombok.ToString;
22 22 import lombok.Value;
  23 +import org.thingsboard.server.common.data.id.DashboardId;
23 24 import org.thingsboard.server.common.data.id.EntityId;
24 25 import org.thingsboard.server.common.data.id.EntityIdFactory;
25 26
... ... @@ -31,6 +32,7 @@ import java.util.UUID;
31 32 public class DeviceProfileInfo extends EntityInfo {
32 33
33 34 private final String image;
  35 + private final DashboardId defaultDashboardId;
34 36 private final DeviceProfileType type;
35 37 private final DeviceTransportType transportType;
36 38
... ... @@ -38,17 +40,20 @@ public class DeviceProfileInfo extends EntityInfo {
38 40 public DeviceProfileInfo(@JsonProperty("id") EntityId id,
39 41 @JsonProperty("name") String name,
40 42 @JsonProperty("image") String image,
  43 + @JsonProperty("defaultDashboardId") DashboardId defaultDashboardId,
41 44 @JsonProperty("type") DeviceProfileType type,
42 45 @JsonProperty("transportType") DeviceTransportType transportType) {
43 46 super(id, name);
44 47 this.image = image;
  48 + this.defaultDashboardId = defaultDashboardId;
45 49 this.type = type;
46 50 this.transportType = transportType;
47 51 }
48 52
49   - public DeviceProfileInfo(UUID uuid, String name, String image, DeviceProfileType type, DeviceTransportType transportType) {
  53 + public DeviceProfileInfo(UUID uuid, String name, String image, UUID defaultDashboardId, DeviceProfileType type, DeviceTransportType transportType) {
50 54 super(EntityIdFactory.getByTypeAndUuid(EntityType.DEVICE_PROFILE, uuid), name);
51 55 this.image = image;
  56 + this.defaultDashboardId = defaultDashboardId != null ? new DashboardId(defaultDashboardId) : null;
52 57 this.type = type;
53 58 this.transportType = transportType;
54 59 }
... ...
... ... @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.dashboard;
18 18 import com.google.common.util.concurrent.ListenableFuture;
19 19 import lombok.extern.slf4j.Slf4j;
20 20 import org.apache.commons.lang3.StringUtils;
  21 +import org.hibernate.exception.ConstraintViolationException;
21 22 import org.springframework.beans.factory.annotation.Autowired;
22 23 import org.springframework.context.annotation.Lazy;
23 24 import org.springframework.stereotype.Service;
... ... @@ -166,7 +167,16 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb
166 167 log.trace("Executing deleteDashboard [{}]", dashboardId);
167 168 Validator.validateId(dashboardId, INCORRECT_DASHBOARD_ID + dashboardId);
168 169 deleteEntityRelations(tenantId, dashboardId);
169   - dashboardDao.removeById(tenantId, dashboardId.getId());
  170 + try {
  171 + dashboardDao.removeById(tenantId, dashboardId.getId());
  172 + } catch (Exception t) {
  173 + ConstraintViolationException e = extractConstraintViolationException(t).orElse(null);
  174 + if (e != null && e.getConstraintName() != null && e.getConstraintName().equalsIgnoreCase("fk_default_dashboard_device_profile")) {
  175 + throw new DataValidationException("The dashboard referenced by the device profiles cannot be deleted!");
  176 + } else {
  177 + throw t;
  178 + }
  179 + }
170 180 }
171 181
172 182 @Override
... ...
... ... @@ -36,6 +36,7 @@ import org.springframework.cache.CacheManager;
36 36 import org.springframework.cache.annotation.Cacheable;
37 37 import org.springframework.stereotype.Service;
38 38 import org.springframework.util.CollectionUtils;
  39 +import org.thingsboard.server.common.data.DashboardInfo;
39 40 import org.thingsboard.server.common.data.Device;
40 41 import org.thingsboard.server.common.data.DeviceProfile;
41 42 import org.thingsboard.server.common.data.DeviceProfileInfo;
... ... @@ -61,9 +62,12 @@ import org.thingsboard.server.common.data.id.DeviceProfileId;
61 62 import org.thingsboard.server.common.data.id.TenantId;
62 63 import org.thingsboard.server.common.data.page.PageData;
63 64 import org.thingsboard.server.common.data.page.PageLink;
  65 +import org.thingsboard.server.common.data.rule.RuleChain;
  66 +import org.thingsboard.server.dao.dashboard.DashboardService;
64 67 import org.thingsboard.server.dao.entity.AbstractEntityService;
65 68 import org.thingsboard.server.dao.exception.DataValidationException;
66 69 import org.thingsboard.server.dao.firmware.FirmwareService;
  70 +import org.thingsboard.server.dao.rule.RuleChainService;
67 71 import org.thingsboard.server.dao.service.DataValidator;
68 72 import org.thingsboard.server.dao.service.PaginatedRemover;
69 73 import org.thingsboard.server.dao.service.Validator;
... ... @@ -117,6 +121,12 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
117 121 @Autowired
118 122 private FirmwareService firmwareService;
119 123
  124 + @Autowired
  125 + private RuleChainService ruleChainService;
  126 +
  127 + @Autowired
  128 + private DashboardService dashboardService;
  129 +
120 130 private final Lock findOrCreateLock = new ReentrantLock();
121 131
122 132 @Cacheable(cacheNames = DEVICE_PROFILE_CACHE, key = "{#deviceProfileId.id}")
... ... @@ -336,7 +346,7 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
336 346 }
337 347
338 348 private DataValidator<DeviceProfile> deviceProfileValidator =
339   - new DataValidator<DeviceProfile>() {
  349 + new DataValidator<>() {
340 350 @Override
341 351 protected void validateDataImpl(TenantId tenantId, DeviceProfile deviceProfile) {
342 352 if (StringUtils.isEmpty(deviceProfile.getName())) {
... ... @@ -402,6 +412,20 @@ public class DeviceProfileServiceImpl extends AbstractEntityService implements D
402 412 }
403 413 }
404 414
  415 + if (deviceProfile.getDefaultRuleChainId() != null) {
  416 + RuleChain ruleChain = ruleChainService.findRuleChainById(tenantId, deviceProfile.getDefaultRuleChainId());
  417 + if (ruleChain == null) {
  418 + throw new DataValidationException("Can't assign non-existent rule chain!");
  419 + }
  420 + }
  421 +
  422 + if (deviceProfile.getDefaultDashboardId() != null) {
  423 + DashboardInfo dashboard = dashboardService.findDashboardInfoById(tenantId, deviceProfile.getDefaultDashboardId());
  424 + if (dashboard == null) {
  425 + throw new DataValidationException("Can't assign non-existent dashboard!");
  426 + }
  427 + }
  428 +
405 429 if (deviceProfile.getFirmwareId() != null) {
406 430 Firmware firmware = firmwareService.findFirmwareById(tenantId, deviceProfile.getFirmwareId());
407 431 if (firmware == null) {
... ...
... ... @@ -177,6 +177,7 @@ public class ModelConstants {
177 177 public static final String DEVICE_PROFILE_DESCRIPTION_PROPERTY = "description";
178 178 public static final String DEVICE_PROFILE_IS_DEFAULT_PROPERTY = "is_default";
179 179 public static final String DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY = "default_rule_chain_id";
  180 + public static final String DEVICE_PROFILE_DEFAULT_DASHBOARD_ID_PROPERTY = "default_dashboard_id";
180 181 public static final String DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY = "default_queue_name";
181 182 public static final String DEVICE_PROFILE_PROVISION_DEVICE_KEY = "provision_device_key";
182 183 public static final String DEVICE_PROFILE_FIRMWARE_ID_PROPERTY = "firmware_id";
... ...
... ... @@ -27,6 +27,7 @@ import org.thingsboard.server.common.data.DeviceProfileProvisionType;
27 27 import org.thingsboard.server.common.data.DeviceProfileType;
28 28 import org.thingsboard.server.common.data.DeviceTransportType;
29 29 import org.thingsboard.server.common.data.device.profile.DeviceProfileData;
  30 +import org.thingsboard.server.common.data.id.DashboardId;
30 31 import org.thingsboard.server.common.data.id.DeviceProfileId;
31 32 import org.thingsboard.server.common.data.id.FirmwareId;
32 33 import org.thingsboard.server.common.data.id.RuleChainId;
... ... @@ -83,6 +84,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
83 84 @Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_RULE_CHAIN_ID_PROPERTY, columnDefinition = "uuid")
84 85 private UUID defaultRuleChainId;
85 86
  87 + @Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_DASHBOARD_ID_PROPERTY)
  88 + private UUID defaultDashboardId;
  89 +
86 90 @Column(name = ModelConstants.DEVICE_PROFILE_DEFAULT_QUEUE_NAME_PROPERTY)
87 91 private String defaultQueueName;
88 92
... ... @@ -122,6 +126,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
122 126 if (deviceProfile.getDefaultRuleChainId() != null) {
123 127 this.defaultRuleChainId = deviceProfile.getDefaultRuleChainId().getId();
124 128 }
  129 + if (deviceProfile.getDefaultDashboardId() != null) {
  130 + this.defaultDashboardId = deviceProfile.getDefaultDashboardId().getId();
  131 + }
125 132 this.defaultQueueName = deviceProfile.getDefaultQueueName();
126 133 this.provisionDeviceKey = deviceProfile.getProvisionDeviceKey();
127 134 if (deviceProfile.getFirmwareId() != null) {
... ... @@ -164,6 +171,9 @@ public final class DeviceProfileEntity extends BaseSqlEntity<DeviceProfile> impl
164 171 if (defaultRuleChainId != null) {
165 172 deviceProfile.setDefaultRuleChainId(new RuleChainId(defaultRuleChainId));
166 173 }
  174 + if (defaultDashboardId != null) {
  175 + deviceProfile.setDefaultDashboardId(new DashboardId(defaultDashboardId));
  176 + }
167 177 deviceProfile.setDefaultQueueName(defaultQueueName);
168 178 deviceProfile.setProvisionDeviceKey(provisionDeviceKey);
169 179
... ...
... ... @@ -28,7 +28,7 @@ import java.util.UUID;
28 28
29 29 public interface DeviceProfileRepository extends PagingAndSortingRepository<DeviceProfileEntity, UUID> {
30 30
31   - @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.type, d.transportType) " +
  31 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.defaultDashboardId, d.type, d.transportType) " +
32 32 "FROM DeviceProfileEntity d " +
33 33 "WHERE d.id = :deviceProfileId")
34 34 DeviceProfileInfo findDeviceProfileInfoById(@Param("deviceProfileId") UUID deviceProfileId);
... ... @@ -39,14 +39,14 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
39 39 @Param("textSearch") String textSearch,
40 40 Pageable pageable);
41 41
42   - @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.type, d.transportType) " +
  42 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.defaultDashboardId, d.type, d.transportType) " +
43 43 "FROM DeviceProfileEntity d WHERE " +
44 44 "d.tenantId = :tenantId AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
45 45 Page<DeviceProfileInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId,
46 46 @Param("textSearch") String textSearch,
47 47 Pageable pageable);
48 48
49   - @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.type, d.transportType) " +
  49 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.defaultDashboardId, d.type, d.transportType) " +
50 50 "FROM DeviceProfileEntity d WHERE " +
51 51 "d.tenantId = :tenantId AND d.transportType = :transportType AND LOWER(d.searchText) LIKE LOWER(CONCAT(:textSearch, '%'))")
52 52 Page<DeviceProfileInfo> findDeviceProfileInfos(@Param("tenantId") UUID tenantId,
... ... @@ -58,7 +58,7 @@ public interface DeviceProfileRepository extends PagingAndSortingRepository<Devi
58 58 "WHERE d.tenantId = :tenantId AND d.isDefault = true")
59 59 DeviceProfileEntity findByDefaultTrueAndTenantId(@Param("tenantId") UUID tenantId);
60 60
61   - @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.type, d.transportType) " +
  61 + @Query("SELECT new org.thingsboard.server.common.data.DeviceProfileInfo(d.id, d.name, d.image, d.defaultDashboardId, d.type, d.transportType) " +
62 62 "FROM DeviceProfileEntity d " +
63 63 "WHERE d.tenantId = :tenantId AND d.isDefault = true")
64 64 DeviceProfileInfo findDefaultDeviceProfileInfo(@Param("tenantId") UUID tenantId);
... ...
... ... @@ -87,7 +87,9 @@ public class AlarmDataAdapter {
87 87 alarm.setSeverity(AlarmSeverity.valueOf(row.get(ModelConstants.ALARM_SEVERITY_PROPERTY).toString()));
88 88 alarm.setStatus(AlarmStatus.valueOf(row.get(ModelConstants.ALARM_STATUS_PROPERTY).toString()));
89 89 alarm.setTenantId(new TenantId((UUID) row.get(ModelConstants.TENANT_ID_PROPERTY)));
90   - alarm.setCustomerId(new CustomerId((UUID) row.get(ModelConstants.CUSTOMER_ID_PROPERTY)));
  90 + Object customerIdObj = row.get(ModelConstants.CUSTOMER_ID_PROPERTY);
  91 + CustomerId customerId = customerIdObj != null ? new CustomerId((UUID) customerIdObj) : null;
  92 + alarm.setCustomerId(customerId);
91 93 if (row.get(ModelConstants.ALARM_PROPAGATE_RELATION_TYPES) != null) {
92 94 String propagateRelationTypes = row.get(ModelConstants.ALARM_PROPAGATE_RELATION_TYPES).toString();
93 95 if (!StringUtils.isEmpty(propagateRelationTypes)) {
... ...
... ... @@ -140,11 +140,11 @@ public class TenantServiceImpl extends AbstractEntityService implements TenantSe
140 140 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
141 141 customerService.deleteCustomersByTenantId(tenantId);
142 142 widgetsBundleService.deleteWidgetsBundlesByTenantId(tenantId);
143   - dashboardService.deleteDashboardsByTenantId(tenantId);
144 143 entityViewService.deleteEntityViewsByTenantId(tenantId);
145 144 assetService.deleteAssetsByTenantId(tenantId);
146 145 deviceService.deleteDevicesByTenantId(tenantId);
147 146 deviceProfileService.deleteDeviceProfilesByTenantId(tenantId);
  147 + dashboardService.deleteDashboardsByTenantId(tenantId);
148 148 edgeService.deleteEdgesByTenantId(tenantId);
149 149 userService.deleteTenantAdmins(tenantId);
150 150 ruleChainService.deleteRuleChainsByTenantId(tenantId);
... ...
... ... @@ -195,11 +195,13 @@ CREATE TABLE IF NOT EXISTS device_profile (
195 195 firmware_id uuid,
196 196 software_id uuid,
197 197 default_rule_chain_id uuid,
  198 + default_dashboard_id uuid,
198 199 default_queue_name varchar(255),
199 200 provision_device_key varchar,
200 201 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
201 202 CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
202 203 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
  204 + CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
203 205 CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id),
204 206 CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id)
205 207 );
... ...
... ... @@ -214,11 +214,13 @@ CREATE TABLE IF NOT EXISTS device_profile (
214 214 firmware_id uuid,
215 215 software_id uuid,
216 216 default_rule_chain_id uuid,
  217 + default_dashboard_id uuid,
217 218 default_queue_name varchar(255),
218 219 provision_device_key varchar,
219 220 CONSTRAINT device_profile_name_unq_key UNIQUE (tenant_id, name),
220 221 CONSTRAINT device_provision_key_unq_key UNIQUE (provision_device_key),
221 222 CONSTRAINT fk_default_rule_chain_device_profile FOREIGN KEY (default_rule_chain_id) REFERENCES rule_chain(id),
  223 + CONSTRAINT fk_default_dashboard_device_profile FOREIGN KEY (default_dashboard_id) REFERENCES dashboard(id),
222 224 CONSTRAINT fk_firmware_device_profile FOREIGN KEY (firmware_id) REFERENCES firmware(id),
223 225 CONSTRAINT fk_software_device_profile FOREIGN KEY (software_id) REFERENCES firmware(id)
224 226 );
... ...
... ... @@ -333,7 +333,8 @@ public class BaseDeviceProfileServiceTest extends AbstractServiceTest {
333 333
334 334 List<DeviceProfileInfo> deviceProfileInfos = deviceProfiles.stream()
335 335 .map(deviceProfile -> new DeviceProfileInfo(deviceProfile.getId(),
336   - deviceProfile.getName(), deviceProfile.getImage(), deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList());
  336 + deviceProfile.getName(), deviceProfile.getImage(), deviceProfile.getDefaultDashboardId(),
  337 + deviceProfile.getType(), deviceProfile.getTransportType())).collect(Collectors.toList());
337 338
338 339 Assert.assertEquals(deviceProfileInfos, loadedDeviceProfileInfos);
339 340
... ...
... ... @@ -45,6 +45,10 @@
45 45 labelText="device-profile.default-rule-chain"
46 46 formControlName="defaultRuleChainId">
47 47 </tb-rule-chain-autocomplete>
  48 + <tb-dashboard-autocomplete
  49 + placeholder="{{'device-profile.default-dashboard' | translate}}"
  50 + formControlName="defaultDashboardId">
  51 + </tb-dashboard-autocomplete>
48 52 <tb-queue-type-list
49 53 [queueType]="serviceType"
50 54 formControlName="defaultQueueName">
... ...
... ... @@ -49,6 +49,7 @@ import { RuleChainId } from '@shared/models/id/rule-chain-id';
49 49 import { StepperSelectionEvent } from '@angular/cdk/stepper';
50 50 import { deepTrim } from '@core/utils';
51 51 import { ServiceType } from '@shared/models/queue.models';
  52 +import { DashboardId } from '@shared/models/id/dashboard-id';
52 53
53 54 export interface AddDeviceProfileDialogData {
54 55 deviceProfileName: string;
... ... @@ -108,6 +109,7 @@ export class AddDeviceProfileDialogComponent extends
108 109 type: [DeviceProfileType.DEFAULT, [Validators.required]],
109 110 image: [null, []],
110 111 defaultRuleChainId: [null, []],
  112 + defaultDashboardId: [null, []],
111 113 defaultQueueName: ['', []],
112 114 description: ['', []]
113 115 }
... ... @@ -199,6 +201,9 @@ export class AddDeviceProfileDialogComponent extends
199 201 if (this.deviceProfileDetailsFormGroup.get('defaultRuleChainId').value) {
200 202 deviceProfile.defaultRuleChainId = new RuleChainId(this.deviceProfileDetailsFormGroup.get('defaultRuleChainId').value);
201 203 }
  204 + if (this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value) {
  205 + deviceProfile.defaultDashboardId = new DashboardId(this.deviceProfileDetailsFormGroup.get('defaultDashboardId').value);
  206 + }
202 207 this.deviceProfileService.saveDeviceProfile(deepTrim(deviceProfile)).subscribe(
203 208 (savedDeviceProfile) => {
204 209 this.dialogRef.close(savedDeviceProfile);
... ...
... ... @@ -59,6 +59,10 @@
59 59 labelText="device-profile.default-rule-chain"
60 60 formControlName="defaultRuleChainId">
61 61 </tb-rule-chain-autocomplete>
  62 + <tb-dashboard-autocomplete
  63 + placeholder="{{'device-profile.default-dashboard' | translate}}"
  64 + formControlName="defaultDashboardId">
  65 + </tb-dashboard-autocomplete>
62 66 <tb-queue-type-list
63 67 [queueType]="serviceType"
64 68 formControlName="defaultQueueName">
... ...
... ... @@ -41,6 +41,7 @@ import { RuleChainId } from '@shared/models/id/rule-chain-id';
41 41 import { ServiceType } from '@shared/models/queue.models';
42 42 import { EntityId } from '@shared/models/id/entity-id';
43 43 import { FirmwareType } from '@shared/models/firmware.models';
  44 +import { DashboardId } from '@shared/models/id/dashboard-id';
44 45
45 46 @Component({
46 47 selector: 'tb-device-profile',
... ... @@ -112,6 +113,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
112 113 provisionConfiguration: [deviceProvisionConfiguration, Validators.required]
113 114 }),
114 115 defaultRuleChainId: [entity && entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null, []],
  116 + defaultDashboardId: [entity && entity.defaultDashboardId ? entity.defaultDashboardId.id : null, []],
115 117 defaultQueueName: [entity ? entity.defaultQueueName : '', []],
116 118 firmwareId: [entity ? entity.firmwareId : null],
117 119 softwareId: [entity ? entity.softwareId : null],
... ... @@ -190,6 +192,7 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
190 192 provisionConfiguration: deviceProvisionConfiguration
191 193 }}, {emitEvent: false});
192 194 this.entityForm.patchValue({defaultRuleChainId: entity.defaultRuleChainId ? entity.defaultRuleChainId.id : null}, {emitEvent: false});
  195 + this.entityForm.patchValue({defaultDashboardId: entity.defaultDashboardId ? entity.defaultDashboardId.id : null}, {emitEvent: false});
193 196 this.entityForm.patchValue({defaultQueueName: entity.defaultQueueName}, {emitEvent: false});
194 197 this.entityForm.patchValue({firmwareId: entity.firmwareId}, {emitEvent: false});
195 198 this.entityForm.patchValue({softwareId: entity.softwareId}, {emitEvent: false});
... ... @@ -200,6 +203,9 @@ export class DeviceProfileComponent extends EntityComponent<DeviceProfile> {
200 203 if (formValue.defaultRuleChainId) {
201 204 formValue.defaultRuleChainId = new RuleChainId(formValue.defaultRuleChainId);
202 205 }
  206 + if (formValue.defaultDashboardId) {
  207 + formValue.defaultDashboardId = new DashboardId(formValue.defaultDashboardId);
  208 + }
203 209 const deviceProvisionConfiguration: DeviceProvisionConfiguration = formValue.profileData.provisionConfiguration;
204 210 formValue.provisionType = deviceProvisionConfiguration.type;
205 211 formValue.provisionDeviceKey = deviceProvisionConfiguration.provisionDeviceKey;
... ...
... ... @@ -139,6 +139,11 @@ export class DashboardAutocompleteComponent implements ControlValueAccessor, OnI
139 139
140 140 setDisabledState(isDisabled: boolean): void {
141 141 this.disabled = isDisabled;
  142 + if (this.disabled) {
  143 + this.selectDashboardFormGroup.disable({emitEvent: false});
  144 + } else {
  145 + this.selectDashboardFormGroup.enable({emitEvent: false});
  146 + }
142 147 }
143 148
144 149 writeValue(value: DashboardInfo | string | null): void {
... ...
... ... @@ -28,6 +28,7 @@ import { TimeUnit } from '@shared/models/time/time.models';
28 28 import * as _moment from 'moment';
29 29 import { AbstractControl, ValidationErrors } from '@angular/forms';
30 30 import { FirmwareId } from '@shared/models/id/firmware-id';
  31 +import { DashboardId } from '@shared/models/id/dashboard-id';
31 32
32 33 export enum DeviceProfileType {
33 34 DEFAULT = 'DEFAULT',
... ... @@ -497,6 +498,7 @@ export interface DeviceProfile extends BaseData<DeviceProfileId> {
497 498 provisionType: DeviceProvisionType;
498 499 provisionDeviceKey?: string;
499 500 defaultRuleChainId?: RuleChainId;
  501 + defaultDashboardId?: DashboardId;
500 502 defaultQueueName?: string;
501 503 firmwareId?: FirmwareId;
502 504 softwareId?: FirmwareId;
... ... @@ -507,6 +509,7 @@ export interface DeviceProfileInfo extends EntityInfoData {
507 509 type: DeviceProfileType;
508 510 transportType: DeviceTransportType;
509 511 image?: string;
  512 + defaultDashboardId?: DashboardId;
510 513 }
511 514
512 515 export interface DefaultDeviceConfiguration {
... ...
... ... @@ -1048,6 +1048,7 @@
1048 1048 "profile-configuration": "Profile configuration",
1049 1049 "transport-configuration": "Transport configuration",
1050 1050 "default-rule-chain": "Default rule chain",
  1051 + "default-dashboard": "Default dashboard",
1051 1052 "select-queue-hint": "Select from a drop-down list or add a custom name.",
1052 1053 "delete-device-profile-title": "Are you sure you want to delete the device profile '{{deviceProfileName}}'?",
1053 1054 "delete-device-profile-text": "Be careful, after the confirmation the device profile and all related data will become unrecoverable.",
... ...