Commit 71062f64df1075ba2df27eff0bd17cec1af7450e

Authored by Igor Kulikov
1 parent 23903588

New widget selector backend support

Showing 28 changed files with 743 additions and 320 deletions
... ... @@ -78,6 +78,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
78 78 import org.thingsboard.server.common.data.rule.RuleChain;
79 79 import org.thingsboard.server.common.data.rule.RuleNode;
80 80 import org.thingsboard.server.common.data.widget.WidgetType;
  81 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
81 82 import org.thingsboard.server.common.data.widget.WidgetsBundle;
82 83 import org.thingsboard.server.common.msg.TbMsg;
83 84 import org.thingsboard.server.common.msg.TbMsgDataType;
... ... @@ -584,13 +585,13 @@ public abstract class BaseController {
584 585 }
585 586 }
586 587
587   - WidgetType checkWidgetTypeId(WidgetTypeId widgetTypeId, Operation operation) throws ThingsboardException {
  588 + WidgetTypeDetails checkWidgetTypeId(WidgetTypeId widgetTypeId, Operation operation) throws ThingsboardException {
588 589 try {
589 590 validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId);
590   - WidgetType widgetType = widgetTypeService.findWidgetTypeById(getCurrentUser().getTenantId(), widgetTypeId);
591   - checkNotNull(widgetType);
592   - accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, operation, widgetTypeId, widgetType);
593   - return widgetType;
  591 + WidgetTypeDetails widgetTypeDetails = widgetTypeService.findWidgetTypeDetailsById(getCurrentUser().getTenantId(), widgetTypeId);
  592 + checkNotNull(widgetTypeDetails);
  593 + accessControlService.checkPermission(getCurrentUser(), Resource.WIDGET_TYPE, operation, widgetTypeId, widgetTypeDetails);
  594 + return widgetTypeDetails;
594 595 } catch (Exception e) {
595 596 throw handleException(e, false);
596 597 }
... ...
... ... @@ -30,6 +30,8 @@ import org.thingsboard.server.common.data.id.TenantId;
30 30 import org.thingsboard.server.common.data.id.WidgetTypeId;
31 31 import org.thingsboard.server.common.data.security.Authority;
32 32 import org.thingsboard.server.common.data.widget.WidgetType;
  33 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  34 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
33 35 import org.thingsboard.server.dao.model.ModelConstants;
34 36 import org.thingsboard.server.queue.util.TbCoreComponent;
35 37 import org.thingsboard.server.service.security.permission.Operation;
... ... @@ -45,7 +47,7 @@ public class WidgetTypeController extends BaseController {
45 47 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
46 48 @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.GET)
47 49 @ResponseBody
48   - public WidgetType getWidgetTypeById(@PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException {
  50 + public WidgetTypeDetails getWidgetTypeById(@PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException {
49 51 checkParameter("widgetTypeId", strWidgetTypeId);
50 52 try {
51 53 WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId));
... ... @@ -58,17 +60,17 @@ public class WidgetTypeController extends BaseController {
58 60 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
59 61 @RequestMapping(value = "/widgetType", method = RequestMethod.POST)
60 62 @ResponseBody
61   - public WidgetType saveWidgetType(@RequestBody WidgetType widgetType) throws ThingsboardException {
  63 + public WidgetTypeDetails saveWidgetType(@RequestBody WidgetTypeDetails widgetTypeDetails) throws ThingsboardException {
62 64 try {
63 65 if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) {
64   - widgetType.setTenantId(TenantId.SYS_TENANT_ID);
  66 + widgetTypeDetails.setTenantId(TenantId.SYS_TENANT_ID);
65 67 } else {
66   - widgetType.setTenantId(getCurrentUser().getTenantId());
  68 + widgetTypeDetails.setTenantId(getCurrentUser().getTenantId());
67 69 }
68 70
69   - checkEntity(widgetType.getId(), widgetType, Resource.WIDGET_TYPE);
  71 + checkEntity(widgetTypeDetails.getId(), widgetTypeDetails, Resource.WIDGET_TYPE);
70 72
71   - return checkNotNull(widgetTypeService.saveWidgetType(widgetType));
  73 + return checkNotNull(widgetTypeService.saveWidgetType(widgetTypeDetails));
72 74 } catch (Exception e) {
73 75 throw handleException(e);
74 76 }
... ... @@ -107,6 +109,44 @@ public class WidgetTypeController extends BaseController {
107 109 }
108 110 }
109 111
  112 + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
  113 + @RequestMapping(value = "/widgetTypesDetails", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET)
  114 + @ResponseBody
  115 + public List<WidgetTypeDetails> getBundleWidgetTypesDetails(
  116 + @RequestParam boolean isSystem,
  117 + @RequestParam String bundleAlias) throws ThingsboardException {
  118 + try {
  119 + TenantId tenantId;
  120 + if (isSystem) {
  121 + tenantId = TenantId.SYS_TENANT_ID;
  122 + } else {
  123 + tenantId = getCurrentUser().getTenantId();
  124 + }
  125 + return checkNotNull(widgetTypeService.findWidgetTypesDetailsByTenantIdAndBundleAlias(tenantId, bundleAlias));
  126 + } catch (Exception e) {
  127 + throw handleException(e);
  128 + }
  129 + }
  130 +
  131 + @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
  132 + @RequestMapping(value = "/widgetTypesInfos", params = {"isSystem", "bundleAlias"}, method = RequestMethod.GET)
  133 + @ResponseBody
  134 + public List<WidgetTypeInfo> getBundleWidgetTypesInfos(
  135 + @RequestParam boolean isSystem,
  136 + @RequestParam String bundleAlias) throws ThingsboardException {
  137 + try {
  138 + TenantId tenantId;
  139 + if (isSystem) {
  140 + tenantId = TenantId.SYS_TENANT_ID;
  141 + } else {
  142 + tenantId = getCurrentUser().getTenantId();
  143 + }
  144 + return checkNotNull(widgetTypeService.findWidgetTypesInfosByTenantIdAndBundleAlias(tenantId, bundleAlias));
  145 + } catch (Exception e) {
  146 + throw handleException(e);
  147 + }
  148 + }
  149 +
110 150 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
111 151 @RequestMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"}, method = RequestMethod.GET)
112 152 @ResponseBody
... ...
... ... @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplat
30 30 import org.thingsboard.server.common.data.rule.RuleChain;
31 31 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
32 32 import org.thingsboard.server.common.data.widget.WidgetType;
  33 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
33 34 import org.thingsboard.server.common.data.widget.WidgetsBundle;
34 35 import org.thingsboard.server.dao.dashboard.DashboardService;
35 36 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
... ... @@ -168,9 +169,9 @@ public class InstallScripts {
168 169 widgetTypesArrayJson.forEach(
169 170 widgetTypeJson -> {
170 171 try {
171   - WidgetType widgetType = objectMapper.treeToValue(widgetTypeJson, WidgetType.class);
172   - widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
173   - widgetTypeService.saveWidgetType(widgetType);
  172 + WidgetTypeDetails widgetTypeDetails = objectMapper.treeToValue(widgetTypeJson, WidgetTypeDetails.class);
  173 + widgetTypeDetails.setBundleAlias(savedWidgetsBundle.getAlias());
  174 + widgetTypeService.saveWidgetType(widgetTypeDetails);
174 175 } catch (Exception e) {
175 176 log.error("Unable to load widget type from json: [{}]", path.toString());
176 177 throw new RuntimeException("Unable to load widget type from json", e);
... ...
... ... @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.Tenant;
26 26 import org.thingsboard.server.common.data.User;
27 27 import org.thingsboard.server.common.data.security.Authority;
28 28 import org.thingsboard.server.common.data.widget.WidgetType;
  29 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
29 30 import org.thingsboard.server.common.data.widget.WidgetsBundle;
30 31
31 32 import java.util.ArrayList;
... ... @@ -76,11 +77,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
76 77
77 78 @Test
78 79 public void testSaveWidgetType() throws Exception {
79   - WidgetType widgetType = new WidgetType();
  80 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
80 81 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
81 82 widgetType.setName("Widget Type");
82 83 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
83   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  84 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
84 85
85 86 Assert.assertNotNull(savedWidgetType);
86 87 Assert.assertNotNull(savedWidgetType.getId());
... ... @@ -95,42 +96,42 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
95 96
96 97 doPost("/api/widgetType", savedWidgetType, WidgetType.class);
97 98
98   - WidgetType foundWidgetType = doGet("/api/widgetType/" + savedWidgetType.getId().getId().toString(), WidgetType.class);
  99 + WidgetTypeDetails foundWidgetType = doGet("/api/widgetType/" + savedWidgetType.getId().getId().toString(), WidgetTypeDetails.class);
99 100 Assert.assertEquals(foundWidgetType.getName(), savedWidgetType.getName());
100 101 }
101 102
102 103 @Test
103 104 public void testUpdateWidgetTypeFromDifferentTenant() throws Exception {
104   - WidgetType widgetType = new WidgetType();
  105 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
105 106 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
106 107 widgetType.setName("Widget Type");
107 108 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
108   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  109 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
109 110
110 111 loginDifferentTenant();
111   - doPost("/api/widgetType", savedWidgetType, WidgetType.class, status().isForbidden());
  112 + doPost("/api/widgetType", savedWidgetType, WidgetTypeDetails.class, status().isForbidden());
112 113 deleteDifferentTenant();
113 114 }
114 115
115 116 @Test
116 117 public void testFindWidgetTypeById() throws Exception {
117   - WidgetType widgetType = new WidgetType();
  118 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
118 119 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
119 120 widgetType.setName("Widget Type");
120 121 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
121   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
122   - WidgetType foundWidgetType = doGet("/api/widgetType/" + savedWidgetType.getId().getId().toString(), WidgetType.class);
  122 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
  123 + WidgetTypeDetails foundWidgetType = doGet("/api/widgetType/" + savedWidgetType.getId().getId().toString(), WidgetTypeDetails.class);
123 124 Assert.assertNotNull(foundWidgetType);
124 125 Assert.assertEquals(savedWidgetType, foundWidgetType);
125 126 }
126 127
127 128 @Test
128 129 public void testDeleteWidgetType() throws Exception {
129   - WidgetType widgetType = new WidgetType();
  130 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
130 131 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
131 132 widgetType.setName("Widget Type");
132 133 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
133   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  134 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
134 135
135 136 doDelete("/api/widgetType/"+savedWidgetType.getId().getId().toString())
136 137 .andExpect(status().isOk());
... ... @@ -141,7 +142,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
141 142
142 143 @Test
143 144 public void testSaveWidgetTypeWithEmptyName() throws Exception {
144   - WidgetType widgetType = new WidgetType();
  145 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
145 146 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
146 147 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
147 148 doPost("/api/widgetType", widgetType)
... ... @@ -151,7 +152,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
151 152
152 153 @Test
153 154 public void testSaveWidgetTypeWithEmptyBundleAlias() throws Exception {
154   - WidgetType widgetType = new WidgetType();
  155 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
155 156 widgetType.setName("Widget Type");
156 157 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
157 158 doPost("/api/widgetType", widgetType)
... ... @@ -161,7 +162,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
161 162
162 163 @Test
163 164 public void testSaveWidgetTypeWithEmptyDescriptor() throws Exception {
164   - WidgetType widgetType = new WidgetType();
  165 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
165 166 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
166 167 widgetType.setName("Widget Type");
167 168 widgetType.setDescriptor(new ObjectMapper().readValue("{}", JsonNode.class));
... ... @@ -172,7 +173,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
172 173
173 174 @Test
174 175 public void testSaveWidgetTypeWithInvalidBundleAlias() throws Exception {
175   - WidgetType widgetType = new WidgetType();
  176 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
176 177 widgetType.setBundleAlias("some_alias");
177 178 widgetType.setName("Widget Type");
178 179 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
... ... @@ -183,11 +184,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
183 184
184 185 @Test
185 186 public void testUpdateWidgetTypeBundleAlias() throws Exception {
186   - WidgetType widgetType = new WidgetType();
  187 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
187 188 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
188 189 widgetType.setName("Widget Type");
189 190 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
190   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  191 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
191 192 savedWidgetType.setBundleAlias("some_alias");
192 193 doPost("/api/widgetType", savedWidgetType)
193 194 .andExpect(status().isBadRequest())
... ... @@ -197,11 +198,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
197 198
198 199 @Test
199 200 public void testUpdateWidgetTypeAlias() throws Exception {
200   - WidgetType widgetType = new WidgetType();
  201 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
201 202 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
202 203 widgetType.setName("Widget Type");
203 204 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
204   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  205 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
205 206 savedWidgetType.setAlias("some_alias");
206 207 doPost("/api/widgetType", savedWidgetType)
207 208 .andExpect(status().isBadRequest())
... ... @@ -213,15 +214,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
213 214 public void testGetBundleWidgetTypes() throws Exception {
214 215 List<WidgetType> widgetTypes = new ArrayList<>();
215 216 for (int i=0;i<89;i++) {
216   - WidgetType widgetType = new WidgetType();
  217 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
217 218 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
218 219 widgetType.setName("Widget Type " + i);
219 220 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
220   - widgetTypes.add(doPost("/api/widgetType", widgetType, WidgetType.class));
  221 + widgetTypes.add(new WidgetType(doPost("/api/widgetType", widgetType, WidgetTypeDetails.class)));
221 222 }
222 223
223 224 List<WidgetType> loadedWidgetTypes = doGetTyped("/api/widgetTypes?isSystem={isSystem}&bundleAlias={bundleAlias}",
224   - new TypeReference<List<WidgetType>>(){}, false, savedWidgetsBundle.getAlias());
  225 + new TypeReference<>(){}, false, savedWidgetsBundle.getAlias());
225 226
226 227 Collections.sort(widgetTypes, idComparator);
227 228 Collections.sort(loadedWidgetTypes, idComparator);
... ... @@ -231,15 +232,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
231 232
232 233 @Test
233 234 public void testGetWidgetType() throws Exception {
234   - WidgetType widgetType = new WidgetType();
  235 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
235 236 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
236 237 widgetType.setName("Widget Type");
237 238 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
238   - WidgetType savedWidgetType = doPost("/api/widgetType", widgetType, WidgetType.class);
  239 + WidgetTypeDetails savedWidgetType = doPost("/api/widgetType", widgetType, WidgetTypeDetails.class);
239 240 WidgetType foundWidgetType = doGet("/api/widgetType?isSystem={isSystem}&bundleAlias={bundleAlias}&alias={alias}",
240 241 WidgetType.class, false, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias());
241 242 Assert.assertNotNull(foundWidgetType);
242   - Assert.assertEquals(savedWidgetType, foundWidgetType);
  243 + Assert.assertEquals(new WidgetType(savedWidgetType), foundWidgetType);
243 244 }
244 245
245 246 }
... ...
... ... @@ -18,6 +18,8 @@ package org.thingsboard.server.dao.widget;
18 18 import org.thingsboard.server.common.data.id.TenantId;
19 19 import org.thingsboard.server.common.data.id.WidgetTypeId;
20 20 import org.thingsboard.server.common.data.widget.WidgetType;
  21 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  22 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
21 23
22 24 import java.util.List;
23 25
... ... @@ -25,12 +27,18 @@ public interface WidgetTypeService {
25 27
26 28 WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId);
27 29
28   - WidgetType saveWidgetType(WidgetType widgetType);
  30 + WidgetTypeDetails findWidgetTypeDetailsById(TenantId tenantId, WidgetTypeId widgetTypeId);
  31 +
  32 + WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetType);
29 33
30 34 void deleteWidgetType(TenantId tenantId, WidgetTypeId widgetTypeId);
31 35
32 36 List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias);
33 37
  38 + List<WidgetTypeDetails> findWidgetTypesDetailsByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias);
  39 +
  40 + List<WidgetTypeInfo> findWidgetTypesInfosByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias);
  41 +
34 42 WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias);
35 43
36 44 void deleteWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias);
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.widget;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.BaseData;
  20 +import org.thingsboard.server.common.data.HasTenantId;
  21 +import org.thingsboard.server.common.data.id.TenantId;
  22 +import org.thingsboard.server.common.data.id.WidgetTypeId;
  23 +
  24 +@Data
  25 +public class BaseWidgetType extends BaseData<WidgetTypeId> implements HasTenantId {
  26 +
  27 + private static final long serialVersionUID = 8388684344603660756L;
  28 +
  29 + private TenantId tenantId;
  30 + private String bundleAlias;
  31 + private String alias;
  32 + private String name;
  33 +
  34 + public BaseWidgetType() {
  35 + super();
  36 + }
  37 +
  38 + public BaseWidgetType(WidgetTypeId id) {
  39 + super(id);
  40 + }
  41 +
  42 + public BaseWidgetType(BaseWidgetType widgetType) {
  43 + super(widgetType);
  44 + this.tenantId = widgetType.getTenantId();
  45 + this.bundleAlias = widgetType.getBundleAlias();
  46 + this.alias = widgetType.getAlias();
  47 + this.name = widgetType.getName();
  48 + }
  49 +}
... ...
... ... @@ -16,23 +16,12 @@
16 16 package org.thingsboard.server.common.data.widget;
17 17
18 18 import com.fasterxml.jackson.databind.JsonNode;
19   -import lombok.EqualsAndHashCode;
20   -import org.thingsboard.server.common.data.BaseData;
21   -import org.thingsboard.server.common.data.HasTenantId;
22   -import org.thingsboard.server.common.data.id.TenantId;
  19 +import lombok.Data;
23 20 import org.thingsboard.server.common.data.id.WidgetTypeId;
24 21
25   -@EqualsAndHashCode(callSuper = true)
26   -public class WidgetType extends BaseData<WidgetTypeId> implements HasTenantId {
  22 +@Data
  23 +public class WidgetType extends BaseWidgetType {
27 24
28   - private static final long serialVersionUID = 8388684344603660756L;
29   -
30   - private TenantId tenantId;
31   - private String bundleAlias;
32   - private String alias;
33   - private String name;
34   - private String image;
35   - private String description;
36 25 private transient JsonNode descriptor;
37 26
38 27 public WidgetType() {
... ... @@ -43,76 +32,13 @@ public class WidgetType extends BaseData<WidgetTypeId> implements HasTenantId {
43 32 super(id);
44 33 }
45 34
  35 + public WidgetType(BaseWidgetType baseWidgetType) {
  36 + super(baseWidgetType);
  37 + }
  38 +
46 39 public WidgetType(WidgetType widgetType) {
47 40 super(widgetType);
48   - this.tenantId = widgetType.getTenantId();
49   - this.bundleAlias = widgetType.getBundleAlias();
50   - this.alias = widgetType.getAlias();
51   - this.name = widgetType.getName();
52   - this.image = widgetType.getImage();
53   - this.description = widgetType.getDescription();
54 41 this.descriptor = widgetType.getDescriptor();
55 42 }
56 43
57   - public TenantId getTenantId() {
58   - return tenantId;
59   - }
60   -
61   - public void setTenantId(TenantId tenantId) {
62   - this.tenantId = tenantId;
63   - }
64   -
65   - public String getBundleAlias() {
66   - return bundleAlias;
67   - }
68   -
69   - public void setBundleAlias(String bundleAlias) {
70   - this.bundleAlias = bundleAlias;
71   - }
72   -
73   - public String getAlias() {
74   - return alias;
75   - }
76   -
77   - public void setAlias(String alias) {
78   - this.alias = alias;
79   - }
80   -
81   - public String getName() {
82   - return name;
83   - }
84   -
85   - public void setName(String name) {
86   - this.name = name;
87   - }
88   -
89   - public String getImage() { return image; }
90   -
91   - public void setImage(String image) { this.image = image; }
92   -
93   - public String getDescription() { return description; }
94   -
95   - public void setDescription(String description) { this.description = description; }
96   -
97   - public JsonNode getDescriptor() {
98   - return descriptor;
99   - }
100   -
101   - public void setDescriptor(JsonNode descriptor) {
102   - this.descriptor = descriptor;
103   - }
104   -
105   - @Override
106   - public String toString() {
107   - final StringBuilder sb = new StringBuilder("WidgetType{");
108   - sb.append("tenantId=").append(tenantId);
109   - sb.append(", bundleAlias='").append(bundleAlias).append('\'');
110   - sb.append(", alias='").append(alias).append('\'');
111   - sb.append(", name='").append(name).append('\'');
112   - sb.append(", image='").append(image).append('\'');
113   - sb.append(", description='").append(description).append('\'');
114   - sb.append(", descriptor=").append(descriptor);
115   - sb.append('}');
116   - return sb.toString();
117   - }
118 44 }
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.widget;
  17 +
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import lombok.Data;
  20 +import org.thingsboard.server.common.data.id.WidgetTypeId;
  21 +
  22 +@Data
  23 +public class WidgetTypeDetails extends WidgetType {
  24 +
  25 + private String image;
  26 + private String description;
  27 +
  28 + public WidgetTypeDetails() {
  29 + super();
  30 + }
  31 +
  32 + public WidgetTypeDetails(WidgetTypeId id) {
  33 + super(id);
  34 + }
  35 +
  36 + public WidgetTypeDetails(BaseWidgetType baseWidgetType) {
  37 + super(baseWidgetType);
  38 + }
  39 +
  40 + public WidgetTypeDetails(WidgetTypeDetails widgetTypeDetails) {
  41 + super(widgetTypeDetails);
  42 + this.image = widgetTypeDetails.getImage();
  43 + this.description = widgetTypeDetails.getDescription();
  44 + }
  45 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.common.data.widget;
  17 +
  18 +import lombok.Data;
  19 +import org.thingsboard.server.common.data.id.WidgetTypeId;
  20 +
  21 +@Data
  22 +public class WidgetTypeInfo extends BaseWidgetType {
  23 +
  24 + private String image;
  25 + private String description;
  26 + private String widgetType;
  27 +
  28 + public WidgetTypeInfo() {
  29 + super();
  30 + }
  31 +
  32 + public WidgetTypeInfo(WidgetTypeId id) {
  33 + super(id);
  34 + }
  35 +
  36 + public WidgetTypeInfo(BaseWidgetType baseWidgetType) {
  37 + super(baseWidgetType);
  38 + }
  39 +
  40 + public WidgetTypeInfo(WidgetTypeInfo widgetTypeInfo) {
  41 + super(widgetTypeInfo);
  42 + this.image = widgetTypeInfo.getImage();
  43 + this.description = widgetTypeInfo.getDescription();
  44 + this.widgetType = widgetTypeInfo.getWidgetType();
  45 + }
  46 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.id.TenantId;
  21 +import org.thingsboard.server.common.data.id.WidgetTypeId;
  22 +import org.thingsboard.server.common.data.widget.BaseWidgetType;
  23 +import org.thingsboard.server.dao.model.BaseEntity;
  24 +import org.thingsboard.server.dao.model.BaseSqlEntity;
  25 +import org.thingsboard.server.dao.model.ModelConstants;
  26 +
  27 +import javax.persistence.Column;
  28 +import javax.persistence.MappedSuperclass;
  29 +import java.util.UUID;
  30 +
  31 +@Data
  32 +@EqualsAndHashCode(callSuper = true)
  33 +@MappedSuperclass
  34 +public abstract class AbstractWidgetTypeEntity<T extends BaseWidgetType> extends BaseSqlEntity<T> implements BaseEntity<T> {
  35 +
  36 + @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY)
  37 + private UUID tenantId;
  38 +
  39 + @Column(name = ModelConstants.WIDGET_TYPE_BUNDLE_ALIAS_PROPERTY)
  40 + private String bundleAlias;
  41 +
  42 + @Column(name = ModelConstants.WIDGET_TYPE_ALIAS_PROPERTY)
  43 + private String alias;
  44 +
  45 + @Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
  46 + private String name;
  47 +
  48 + public AbstractWidgetTypeEntity() {
  49 + super();
  50 + }
  51 +
  52 + public AbstractWidgetTypeEntity(BaseWidgetType widgetType) {
  53 + if (widgetType.getId() != null) {
  54 + this.setUuid(widgetType.getId().getId());
  55 + }
  56 + this.setCreatedTime(widgetType.getCreatedTime());
  57 + if (widgetType.getTenantId() != null) {
  58 + this.tenantId = widgetType.getTenantId().getId();
  59 + }
  60 + this.bundleAlias = widgetType.getBundleAlias();
  61 + this.alias = widgetType.getAlias();
  62 + this.name = widgetType.getName();
  63 + }
  64 +
  65 + public AbstractWidgetTypeEntity(AbstractWidgetTypeEntity widgetTypeEntity) {
  66 + this.setId(widgetTypeEntity.getId());
  67 + this.setCreatedTime(widgetTypeEntity.getCreatedTime());
  68 + this.tenantId = widgetTypeEntity.getTenantId();
  69 + this.bundleAlias = widgetTypeEntity.getBundleAlias();
  70 + this.alias = widgetTypeEntity.getAlias();
  71 + this.name = widgetTypeEntity.getName();
  72 + }
  73 +
  74 + protected BaseWidgetType toBaseWidgetType() {
  75 + BaseWidgetType widgetType = new BaseWidgetType(new WidgetTypeId(getUuid()));
  76 + widgetType.setCreatedTime(createdTime);
  77 + if (tenantId != null) {
  78 + widgetType.setTenantId(new TenantId(tenantId));
  79 + }
  80 + widgetType.setBundleAlias(bundleAlias);
  81 + widgetType.setAlias(alias);
  82 + widgetType.setName(name);
  83 + return widgetType;
  84 + }
  85 +
  86 +}
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.sql;
  17 +
  18 +import com.fasterxml.jackson.databind.JsonNode;
  19 +import lombok.Data;
  20 +import lombok.EqualsAndHashCode;
  21 +import org.hibernate.annotations.Type;
  22 +import org.hibernate.annotations.TypeDef;
  23 +import org.thingsboard.server.common.data.widget.BaseWidgetType;
  24 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  25 +import org.thingsboard.server.dao.model.ModelConstants;
  26 +import org.thingsboard.server.dao.util.mapping.JsonStringType;
  27 +
  28 +import javax.persistence.Column;
  29 +import javax.persistence.Entity;
  30 +import javax.persistence.Table;
  31 +
  32 +@Data
  33 +@EqualsAndHashCode(callSuper = true)
  34 +@Entity
  35 +@TypeDef(name = "json", typeClass = JsonStringType.class)
  36 +@Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
  37 +public class WidgetTypeDetailsEntity extends AbstractWidgetTypeEntity<WidgetTypeDetails> {
  38 +
  39 + @Column(name = ModelConstants.WIDGET_TYPE_IMAGE_PROPERTY)
  40 + private String image;
  41 +
  42 + @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTION_PROPERTY)
  43 + private String description;
  44 +
  45 + @Type(type="json")
  46 + @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
  47 + private JsonNode descriptor;
  48 +
  49 + public WidgetTypeDetailsEntity() {
  50 + super();
  51 + }
  52 +
  53 + public WidgetTypeDetailsEntity(WidgetTypeDetails widgetTypeDetails) {
  54 + super(widgetTypeDetails);
  55 + this.image = widgetTypeDetails.getImage();
  56 + this.description = widgetTypeDetails.getDescription();
  57 + this.descriptor = widgetTypeDetails.getDescriptor();
  58 + }
  59 +
  60 + @Override
  61 + public WidgetTypeDetails toData() {
  62 + BaseWidgetType baseWidgetType = super.toBaseWidgetType();
  63 + WidgetTypeDetails widgetTypeDetails = new WidgetTypeDetails(baseWidgetType);
  64 + widgetTypeDetails.setImage(image);
  65 + widgetTypeDetails.setDescription(description);
  66 + widgetTypeDetails.setDescriptor(descriptor);
  67 + return widgetTypeDetails;
  68 + }
  69 +}
... ...
... ... @@ -20,11 +20,8 @@ import lombok.Data;
20 20 import lombok.EqualsAndHashCode;
21 21 import org.hibernate.annotations.Type;
22 22 import org.hibernate.annotations.TypeDef;
23   -import org.thingsboard.server.common.data.id.TenantId;
24   -import org.thingsboard.server.common.data.id.WidgetTypeId;
  23 +import org.thingsboard.server.common.data.widget.BaseWidgetType;
25 24 import org.thingsboard.server.common.data.widget.WidgetType;
26   -import org.thingsboard.server.dao.model.BaseEntity;
27   -import org.thingsboard.server.dao.model.BaseSqlEntity;
28 25 import org.thingsboard.server.dao.model.ModelConstants;
29 26 import org.thingsboard.server.dao.util.mapping.JsonStringType;
30 27
... ... @@ -38,25 +35,7 @@ import java.util.UUID;
38 35 @Entity
39 36 @TypeDef(name = "json", typeClass = JsonStringType.class)
40 37 @Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME)
41   -public final class WidgetTypeEntity extends BaseSqlEntity<WidgetType> implements BaseEntity<WidgetType> {
42   -
43   - @Column(name = ModelConstants.WIDGET_TYPE_TENANT_ID_PROPERTY)
44   - private UUID tenantId;
45   -
46   - @Column(name = ModelConstants.WIDGET_TYPE_BUNDLE_ALIAS_PROPERTY)
47   - private String bundleAlias;
48   -
49   - @Column(name = ModelConstants.WIDGET_TYPE_ALIAS_PROPERTY)
50   - private String alias;
51   -
52   - @Column(name = ModelConstants.WIDGET_TYPE_NAME_PROPERTY)
53   - private String name;
54   -
55   - @Column(name = ModelConstants.WIDGET_TYPE_IMAGE_PROPERTY)
56   - private String image;
57   -
58   - @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTION_PROPERTY)
59   - private String description;
  38 +public final class WidgetTypeEntity extends AbstractWidgetTypeEntity<WidgetType> {
60 39
61 40 @Type(type="json")
62 41 @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
... ... @@ -66,34 +45,10 @@ public final class WidgetTypeEntity extends BaseSqlEntity<WidgetType> implement
66 45 super();
67 46 }
68 47
69   - public WidgetTypeEntity(WidgetType widgetType) {
70   - if (widgetType.getId() != null) {
71   - this.setUuid(widgetType.getId().getId());
72   - }
73   - this.setCreatedTime(widgetType.getCreatedTime());
74   - if (widgetType.getTenantId() != null) {
75   - this.tenantId = widgetType.getTenantId().getId();
76   - }
77   - this.bundleAlias = widgetType.getBundleAlias();
78   - this.alias = widgetType.getAlias();
79   - this.name = widgetType.getName();
80   - this.image = widgetType.getImage();
81   - this.description = widgetType.getDescription();
82   - this.descriptor = widgetType.getDescriptor();
83   - }
84   -
85 48 @Override
86 49 public WidgetType toData() {
87   - WidgetType widgetType = new WidgetType(new WidgetTypeId(this.getUuid()));
88   - widgetType.setCreatedTime(createdTime);
89   - if (tenantId != null) {
90   - widgetType.setTenantId(new TenantId(tenantId));
91   - }
92   - widgetType.setBundleAlias(bundleAlias);
93   - widgetType.setAlias(alias);
94   - widgetType.setName(name);
95   - widgetType.setImage(image);
96   - widgetType.setDescription(description);
  50 + BaseWidgetType baseWidgetType = super.toBaseWidgetType();
  51 + WidgetType widgetType = new WidgetType(baseWidgetType);
97 52 widgetType.setDescriptor(descriptor);
98 53 return widgetType;
99 54 }
... ...
  1 +/**
  2 + * Copyright © 2016-2021 The Thingsboard Authors
  3 + *
  4 + * Licensed under the Apache License, Version 2.0 (the "License");
  5 + * you may not use this file except in compliance with the License.
  6 + * You may obtain a copy of the License at
  7 + *
  8 + * http://www.apache.org/licenses/LICENSE-2.0
  9 + *
  10 + * Unless required by applicable law or agreed to in writing, software
  11 + * distributed under the License is distributed on an "AS IS" BASIS,
  12 + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13 + * See the License for the specific language governing permissions and
  14 + * limitations under the License.
  15 + */
  16 +package org.thingsboard.server.dao.model.sql;
  17 +
  18 +import lombok.Data;
  19 +import lombok.EqualsAndHashCode;
  20 +import org.thingsboard.server.common.data.widget.BaseWidgetType;
  21 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
  22 +
  23 +@Data
  24 +@EqualsAndHashCode(callSuper = true)
  25 +public final class WidgetTypeInfoEntity extends AbstractWidgetTypeEntity<WidgetTypeInfo> {
  26 +
  27 + private String image;
  28 + private String description;
  29 + private String widgetType;
  30 +
  31 + public WidgetTypeInfoEntity() {
  32 + super();
  33 + }
  34 +
  35 + public WidgetTypeInfoEntity(WidgetTypeDetailsEntity widgetTypeDetailsEntity) {
  36 + super(widgetTypeDetailsEntity);
  37 + this.image = widgetTypeDetailsEntity.getImage();
  38 + this.description = widgetTypeDetailsEntity.getDescription();
  39 + if (widgetTypeDetailsEntity.getDescriptor() != null && widgetTypeDetailsEntity.getDescriptor().has("type")) {
  40 + this.widgetType = widgetTypeDetailsEntity.getDescriptor().get("type").asText();
  41 + } else {
  42 + this.widgetType = "";
  43 + }
  44 + }
  45 +
  46 + @Override
  47 + public WidgetTypeInfo toData() {
  48 + BaseWidgetType baseWidgetType = super.toBaseWidgetType();
  49 + WidgetTypeInfo widgetTypeInfo = new WidgetTypeInfo(baseWidgetType);
  50 + widgetTypeInfo.setImage(image);
  51 + widgetTypeInfo.setDescription(description);
  52 + widgetTypeInfo.setWidgetType(widgetType);
  53 + return widgetTypeInfo;
  54 + }
  55 +
  56 +}
... ...
... ... @@ -18,8 +18,12 @@ package org.thingsboard.server.dao.sql.widget;
18 18 import org.springframework.beans.factory.annotation.Autowired;
19 19 import org.springframework.data.repository.CrudRepository;
20 20 import org.springframework.stereotype.Component;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 22 import org.thingsboard.server.common.data.widget.WidgetType;
  23 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  24 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
22 25 import org.thingsboard.server.dao.DaoUtil;
  26 +import org.thingsboard.server.dao.model.sql.WidgetTypeDetailsEntity;
23 27 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
24 28 import org.thingsboard.server.dao.sql.JpaAbstractDao;
25 29 import org.thingsboard.server.dao.widget.WidgetTypeDao;
... ... @@ -31,28 +35,43 @@ import java.util.UUID;
31 35 * Created by Valerii Sosliuk on 4/29/2017.
32 36 */
33 37 @Component
34   -public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeEntity, WidgetType> implements WidgetTypeDao {
  38 +public class JpaWidgetTypeDao extends JpaAbstractDao<WidgetTypeDetailsEntity, WidgetTypeDetails> implements WidgetTypeDao {
35 39
36 40 @Autowired
37 41 private WidgetTypeRepository widgetTypeRepository;
38 42
39 43 @Override
40   - protected Class<WidgetTypeEntity> getEntityClass() {
41   - return WidgetTypeEntity.class;
  44 + protected Class<WidgetTypeDetailsEntity> getEntityClass() {
  45 + return WidgetTypeDetailsEntity.class;
42 46 }
43 47
44 48 @Override
45   - protected CrudRepository<WidgetTypeEntity, UUID> getCrudRepository() {
  49 + protected CrudRepository<WidgetTypeDetailsEntity, UUID> getCrudRepository() {
46 50 return widgetTypeRepository;
47 51 }
48 52
49 53 @Override
  54 + public WidgetType findWidgetTypeById(TenantId tenantId, UUID widgetTypeId) {
  55 + return DaoUtil.getData(widgetTypeRepository.findWidgetTypeById(widgetTypeId));
  56 + }
  57 +
  58 + @Override
50 59 public List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias) {
  60 + return DaoUtil.convertDataList(widgetTypeRepository.findWidgetTypesByTenantIdAndBundleAlias(tenantId, bundleAlias));
  61 + }
  62 +
  63 + @Override
  64 + public List<WidgetTypeDetails> findWidgetTypesDetailsByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias) {
51 65 return DaoUtil.convertDataList(widgetTypeRepository.findByTenantIdAndBundleAlias(tenantId, bundleAlias));
52 66 }
53 67
54 68 @Override
  69 + public List<WidgetTypeInfo> findWidgetTypesInfosByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias) {
  70 + return DaoUtil.convertDataList(widgetTypeRepository.findWidgetTypesInfosByTenantIdAndBundleAlias(tenantId, bundleAlias));
  71 + }
  72 +
  73 + @Override
55 74 public WidgetType findByTenantIdBundleAliasAndAlias(UUID tenantId, String bundleAlias, String alias) {
56   - return DaoUtil.getData(widgetTypeRepository.findByTenantIdAndBundleAliasAndAlias(tenantId, bundleAlias, alias));
  75 + return DaoUtil.getData(widgetTypeRepository.findWidgetTypeByTenantIdAndBundleAliasAndAlias(tenantId, bundleAlias, alias));
57 76 }
58 77 }
... ...
... ... @@ -15,18 +15,35 @@
15 15 */
16 16 package org.thingsboard.server.dao.sql.widget;
17 17
  18 +import org.springframework.data.jpa.repository.Query;
18 19 import org.springframework.data.repository.CrudRepository;
  20 +import org.springframework.data.repository.query.Param;
  21 +import org.thingsboard.server.dao.model.sql.WidgetTypeDetailsEntity;
19 22 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
  23 +import org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity;
20 24
21 25 import java.util.List;
22 26 import java.util.UUID;
23 27
24   -/**
25   - * Created by Valerii Sosliuk on 4/29/2017.
26   - */
27   -public interface WidgetTypeRepository extends CrudRepository<WidgetTypeEntity, UUID> {
  28 +public interface WidgetTypeRepository extends CrudRepository<WidgetTypeDetailsEntity, UUID> {
  29 +
  30 + @Query("SELECT wt FROM WidgetTypeEntity wt WHERE wt.id = :widgetTypeId")
  31 + WidgetTypeEntity findWidgetTypeById(@Param("widgetTypeId") UUID widgetTypeId);
  32 +
  33 + @Query("SELECT wt FROM WidgetTypeEntity wt WHERE wt.tenantId = :tenantId AND wt.bundleAlias = :bundleAlias")
  34 + List<WidgetTypeEntity> findWidgetTypesByTenantIdAndBundleAlias(@Param("tenantId") UUID tenantId,
  35 + @Param("bundleAlias") String bundleAlias);
  36 +
  37 + @Query("SELECT new org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity(wtd) FROM WidgetTypeDetailsEntity wtd " +
  38 + "WHERE wtd.tenantId = :tenantId AND wtd.bundleAlias = :bundleAlias")
  39 + List<WidgetTypeInfoEntity> findWidgetTypesInfosByTenantIdAndBundleAlias(@Param("tenantId") UUID tenantId,
  40 + @Param("bundleAlias") String bundleAlias);
28 41
29   - List<WidgetTypeEntity> findByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
  42 + List<WidgetTypeDetailsEntity> findByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
30 43
31   - WidgetTypeEntity findByTenantIdAndBundleAliasAndAlias(UUID tenantId, String bundleAlias, String alias);
  44 + @Query("SELECT wt FROM WidgetTypeEntity wt " +
  45 + "WHERE wt.tenantId = :tenantId AND wt.bundleAlias = :bundleAlias AND wt.alias = :alias")
  46 + WidgetTypeEntity findWidgetTypeByTenantIdAndBundleAliasAndAlias(@Param("tenantId") UUID tenantId,
  47 + @Param("bundleAlias") String bundleAlias,
  48 + @Param("alias") String alias);
32 49 }
... ...
... ... @@ -17,6 +17,8 @@ package org.thingsboard.server.dao.widget;
17 17
18 18 import org.thingsboard.server.common.data.id.TenantId;
19 19 import org.thingsboard.server.common.data.widget.WidgetType;
  20 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  21 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
20 22 import org.thingsboard.server.dao.Dao;
21 23
22 24 import java.util.List;
... ... @@ -25,15 +27,24 @@ import java.util.UUID;
25 27 /**
26 28 * The Interface WidgetTypeDao.
27 29 */
28   -public interface WidgetTypeDao extends Dao<WidgetType> {
  30 +public interface WidgetTypeDao extends Dao<WidgetTypeDetails> {
29 31
30 32 /**
31 33 * Save or update widget type object
32 34 *
33   - * @param widgetType the widget type object
  35 + * @param widgetTypeDetails the widget type details object
34 36 * @return saved widget type object
35 37 */
36   - WidgetType save(TenantId tenantId, WidgetType widgetType);
  38 + WidgetTypeDetails save(TenantId tenantId, WidgetTypeDetails widgetTypeDetails);
  39 +
  40 + /**
  41 + * Find widget type by tenantId and widgetTypeId.
  42 + *
  43 + * @param tenantId the tenantId
  44 + * @param widgetTypeId the widget type id
  45 + * @return the widget type object
  46 + */
  47 + WidgetType findWidgetTypeById(TenantId tenantId, UUID widgetTypeId);
37 48
38 49 /**
39 50 * Find widget types by tenantId and bundleAlias.
... ... @@ -45,6 +56,24 @@ public interface WidgetTypeDao extends Dao<WidgetType> {
45 56 List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
46 57
47 58 /**
  59 + * Find widget types details by tenantId and bundleAlias.
  60 + *
  61 + * @param tenantId the tenantId
  62 + * @param bundleAlias the bundle alias
  63 + * @return the list of widget types details objects
  64 + */
  65 + List<WidgetTypeDetails> findWidgetTypesDetailsByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
  66 +
  67 + /**
  68 + * Find widget types infos by tenantId and bundleAlias.
  69 + *
  70 + * @param tenantId the tenantId
  71 + * @param bundleAlias the bundle alias
  72 + * @return the list of widget types infos objects
  73 + */
  74 + List<WidgetTypeInfo> findWidgetTypesInfosByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias);
  75 +
  76 + /**
48 77 * Find widget type by tenantId, bundleAlias and alias.
49 78 *
50 79 * @param tenantId the tenantId
... ...
... ... @@ -23,6 +23,8 @@ import org.thingsboard.server.common.data.Tenant;
23 23 import org.thingsboard.server.common.data.id.TenantId;
24 24 import org.thingsboard.server.common.data.id.WidgetTypeId;
25 25 import org.thingsboard.server.common.data.widget.WidgetType;
  26 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
  27 +import org.thingsboard.server.common.data.widget.WidgetTypeInfo;
26 28 import org.thingsboard.server.common.data.widget.WidgetsBundle;
27 29 import org.thingsboard.server.dao.exception.DataValidationException;
28 30 import org.thingsboard.server.dao.model.ModelConstants;
... ... @@ -51,14 +53,21 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
51 53 public WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId) {
52 54 log.trace("Executing findWidgetTypeById [{}]", widgetTypeId);
53 55 Validator.validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId);
  56 + return widgetTypeDao.findWidgetTypeById(tenantId, widgetTypeId.getId());
  57 + }
  58 +
  59 + @Override
  60 + public WidgetTypeDetails findWidgetTypeDetailsById(TenantId tenantId, WidgetTypeId widgetTypeId) {
  61 + log.trace("Executing findWidgetTypeDetailsById [{}]", widgetTypeId);
  62 + Validator.validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId);
54 63 return widgetTypeDao.findById(tenantId, widgetTypeId.getId());
55 64 }
56 65
57 66 @Override
58   - public WidgetType saveWidgetType(WidgetType widgetType) {
59   - log.trace("Executing saveWidgetType [{}]", widgetType);
60   - widgetTypeValidator.validate(widgetType, WidgetType::getTenantId);
61   - return widgetTypeDao.save(widgetType.getTenantId(), widgetType);
  67 + public WidgetTypeDetails saveWidgetType(WidgetTypeDetails widgetTypeDetails) {
  68 + log.trace("Executing saveWidgetType [{}]", widgetTypeDetails);
  69 + widgetTypeValidator.validate(widgetTypeDetails, WidgetType::getTenantId);
  70 + return widgetTypeDao.save(widgetTypeDetails.getTenantId(), widgetTypeDetails);
62 71 }
63 72
64 73 @Override
... ... @@ -77,6 +86,22 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
77 86 }
78 87
79 88 @Override
  89 + public List<WidgetTypeDetails> findWidgetTypesDetailsByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias) {
  90 + log.trace("Executing findWidgetTypesDetailsByTenantIdAndBundleAlias, tenantId [{}], bundleAlias [{}]", tenantId, bundleAlias);
  91 + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  92 + Validator.validateString(bundleAlias, INCORRECT_BUNDLE_ALIAS + bundleAlias);
  93 + return widgetTypeDao.findWidgetTypesDetailsByTenantIdAndBundleAlias(tenantId.getId(), bundleAlias);
  94 + }
  95 +
  96 + @Override
  97 + public List<WidgetTypeInfo> findWidgetTypesInfosByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias) {
  98 + log.trace("Executing findWidgetTypesInfosByTenantIdAndBundleAlias, tenantId [{}], bundleAlias [{}]", tenantId, bundleAlias);
  99 + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
  100 + Validator.validateString(bundleAlias, INCORRECT_BUNDLE_ALIAS + bundleAlias);
  101 + return widgetTypeDao.findWidgetTypesInfosByTenantIdAndBundleAlias(tenantId.getId(), bundleAlias);
  102 + }
  103 +
  104 + @Override
80 105 public WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias) {
81 106 log.trace("Executing findWidgetTypeByTenantIdBundleAliasAndAlias, tenantId [{}], bundleAlias [{}], alias [{}]", tenantId, bundleAlias, alias);
82 107 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
... ... @@ -96,24 +121,24 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
96 121 }
97 122 }
98 123
99   - private DataValidator<WidgetType> widgetTypeValidator =
100   - new DataValidator<WidgetType>() {
  124 + private DataValidator<WidgetTypeDetails> widgetTypeValidator =
  125 + new DataValidator<>() {
101 126 @Override
102   - protected void validateDataImpl(TenantId tenantId, WidgetType widgetType) {
103   - if (StringUtils.isEmpty(widgetType.getName())) {
  127 + protected void validateDataImpl(TenantId tenantId, WidgetTypeDetails widgetTypeDetails) {
  128 + if (StringUtils.isEmpty(widgetTypeDetails.getName())) {
104 129 throw new DataValidationException("Widgets type name should be specified!");
105 130 }
106   - if (StringUtils.isEmpty(widgetType.getBundleAlias())) {
  131 + if (StringUtils.isEmpty(widgetTypeDetails.getBundleAlias())) {
107 132 throw new DataValidationException("Widgets type bundle alias should be specified!");
108 133 }
109   - if (widgetType.getDescriptor() == null || widgetType.getDescriptor().size() == 0) {
  134 + if (widgetTypeDetails.getDescriptor() == null || widgetTypeDetails.getDescriptor().size() == 0) {
110 135 throw new DataValidationException("Widgets type descriptor can't be empty!");
111 136 }
112   - if (widgetType.getTenantId() == null) {
113   - widgetType.setTenantId(new TenantId(ModelConstants.NULL_UUID));
  137 + if (widgetTypeDetails.getTenantId() == null) {
  138 + widgetTypeDetails.setTenantId(new TenantId(ModelConstants.NULL_UUID));
114 139 }
115   - if (!widgetType.getTenantId().getId().equals(ModelConstants.NULL_UUID)) {
116   - Tenant tenant = tenantDao.findById(tenantId, widgetType.getTenantId().getId());
  140 + if (!widgetTypeDetails.getTenantId().getId().equals(ModelConstants.NULL_UUID)) {
  141 + Tenant tenant = tenantDao.findById(tenantId, widgetTypeDetails.getTenantId().getId());
117 142 if (tenant == null) {
118 143 throw new DataValidationException("Widget type is referencing to non-existent tenant!");
119 144 }
... ... @@ -121,37 +146,37 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
121 146 }
122 147
123 148 @Override
124   - protected void validateCreate(TenantId tenantId, WidgetType widgetType) {
125   - WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(widgetType.getTenantId().getId(), widgetType.getBundleAlias());
  149 + protected void validateCreate(TenantId tenantId, WidgetTypeDetails widgetTypeDetails) {
  150 + WidgetsBundle widgetsBundle = widgetsBundleService.findWidgetsBundleByTenantIdAndAlias(widgetTypeDetails.getTenantId().getId(), widgetTypeDetails.getBundleAlias());
126 151 if (widgetsBundle == null) {
127 152 throw new DataValidationException("Widget type is referencing to non-existent widgets bundle!");
128 153 }
129   - String alias = widgetType.getAlias();
  154 + String alias = widgetTypeDetails.getAlias();
130 155 if (alias == null || alias.trim().isEmpty()) {
131   - alias = widgetType.getName().toLowerCase().replaceAll("\\W+", "_");
  156 + alias = widgetTypeDetails.getName().toLowerCase().replaceAll("\\W+", "_");
132 157 }
133 158 String originalAlias = alias;
134 159 int c = 1;
135 160 WidgetType withSameAlias;
136 161 do {
137   - withSameAlias = widgetTypeDao.findByTenantIdBundleAliasAndAlias(widgetType.getTenantId().getId(), widgetType.getBundleAlias(), alias);
  162 + withSameAlias = widgetTypeDao.findByTenantIdBundleAliasAndAlias(widgetTypeDetails.getTenantId().getId(), widgetTypeDetails.getBundleAlias(), alias);
138 163 if (withSameAlias != null) {
139 164 alias = originalAlias + (++c);
140 165 }
141 166 } while (withSameAlias != null);
142   - widgetType.setAlias(alias);
  167 + widgetTypeDetails.setAlias(alias);
143 168 }
144 169
145 170 @Override
146   - protected void validateUpdate(TenantId tenantId, WidgetType widgetType) {
147   - WidgetType storedWidgetType = widgetTypeDao.findById(tenantId, widgetType.getId().getId());
148   - if (!storedWidgetType.getTenantId().getId().equals(widgetType.getTenantId().getId())) {
  171 + protected void validateUpdate(TenantId tenantId, WidgetTypeDetails widgetTypeDetails) {
  172 + WidgetType storedWidgetType = widgetTypeDao.findById(tenantId, widgetTypeDetails.getId().getId());
  173 + if (!storedWidgetType.getTenantId().getId().equals(widgetTypeDetails.getTenantId().getId())) {
149 174 throw new DataValidationException("Can't move existing widget type to different tenant!");
150 175 }
151   - if (!storedWidgetType.getBundleAlias().equals(widgetType.getBundleAlias())) {
  176 + if (!storedWidgetType.getBundleAlias().equals(widgetTypeDetails.getBundleAlias())) {
152 177 throw new DataValidationException("Update of widget type bundle alias is prohibited!");
153 178 }
154   - if (!storedWidgetType.getAlias().equals(widgetType.getAlias())) {
  179 + if (!storedWidgetType.getAlias().equals(widgetTypeDetails.getAlias())) {
155 180 throw new DataValidationException("Update of widget type alias is prohibited!");
156 181 }
157 182 }
... ...
... ... @@ -25,6 +25,7 @@ import org.junit.Test;
25 25 import org.thingsboard.server.common.data.Tenant;
26 26 import org.thingsboard.server.common.data.id.TenantId;
27 27 import org.thingsboard.server.common.data.widget.WidgetType;
  28 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
28 29 import org.thingsboard.server.common.data.widget.WidgetsBundle;
29 30 import org.thingsboard.server.dao.exception.DataValidationException;
30 31 import org.thingsboard.server.dao.model.ModelConstants;
... ... @@ -62,12 +63,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
62 63 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
63 64
64 65
65   - WidgetType widgetType = new WidgetType();
  66 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
66 67 widgetType.setTenantId(tenantId);
67 68 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
68 69 widgetType.setName("Widget Type");
69 70 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
70   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  71 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
71 72
72 73 Assert.assertNotNull(savedWidgetType);
73 74 Assert.assertNotNull(savedWidgetType.getId());
... ... @@ -94,7 +95,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
94 95 widgetsBundle.setTitle("Widgets bundle");
95 96 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
96 97
97   - WidgetType widgetType = new WidgetType();
  98 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
98 99 widgetType.setTenantId(tenantId);
99 100 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
100 101 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
... ... @@ -107,7 +108,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
107 108
108 109 @Test(expected = DataValidationException.class)
109 110 public void testSaveWidgetTypeWithEmptyBundleAlias() throws IOException {
110   - WidgetType widgetType = new WidgetType();
  111 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
111 112 widgetType.setTenantId(tenantId);
112 113 widgetType.setName("Widget Type");
113 114 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
... ... @@ -121,7 +122,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
121 122 widgetsBundle.setTitle("Widgets bundle");
122 123 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
123 124
124   - WidgetType widgetType = new WidgetType();
  125 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
125 126 widgetType.setTenantId(tenantId);
126 127 widgetType.setName("Widget Type");
127 128 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
... ... @@ -140,7 +141,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
140 141 widgetsBundle.setTitle("Widgets bundle");
141 142 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
142 143
143   - WidgetType widgetType = new WidgetType();
  144 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
144 145 widgetType.setTenantId(new TenantId(Uuids.timeBased()));
145 146 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
146 147 widgetType.setName("Widget Type");
... ... @@ -154,7 +155,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
154 155
155 156 @Test(expected = DataValidationException.class)
156 157 public void testSaveWidgetTypeWithInvalidBundleAlias() throws IOException {
157   - WidgetType widgetType = new WidgetType();
  158 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
158 159 widgetType.setTenantId(tenantId);
159 160 widgetType.setBundleAlias("some_alias");
160 161 widgetType.setName("Widget Type");
... ... @@ -169,12 +170,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
169 170 widgetsBundle.setTitle("Widgets bundle");
170 171 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
171 172
172   - WidgetType widgetType = new WidgetType();
  173 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
173 174 widgetType.setTenantId(tenantId);
174 175 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
175 176 widgetType.setName("Widget Type");
176 177 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
177   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  178 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
178 179 savedWidgetType.setTenantId(new TenantId(ModelConstants.NULL_UUID));
179 180 try {
180 181 widgetTypeService.saveWidgetType(savedWidgetType);
... ... @@ -190,12 +191,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
190 191 widgetsBundle.setTitle("Widgets bundle");
191 192 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
192 193
193   - WidgetType widgetType = new WidgetType();
  194 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
194 195 widgetType.setTenantId(tenantId);
195 196 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
196 197 widgetType.setName("Widget Type");
197 198 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
198   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  199 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
199 200 savedWidgetType.setBundleAlias("some_alias");
200 201 try {
201 202 widgetTypeService.saveWidgetType(savedWidgetType);
... ... @@ -211,12 +212,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
211 212 widgetsBundle.setTitle("Widgets bundle");
212 213 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
213 214
214   - WidgetType widgetType = new WidgetType();
  215 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
215 216 widgetType.setTenantId(tenantId);
216 217 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
217 218 widgetType.setName("Widget Type");
218 219 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
219   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  220 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
220 221 savedWidgetType.setAlias("some_alias");
221 222 try {
222 223 widgetTypeService.saveWidgetType(savedWidgetType);
... ... @@ -232,13 +233,13 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
232 233 widgetsBundle.setTitle("Widgets bundle");
233 234 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
234 235
235   - WidgetType widgetType = new WidgetType();
  236 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
236 237 widgetType.setTenantId(tenantId);
237 238 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
238 239 widgetType.setName("Widget Type");
239 240 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
240   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
241   - WidgetType foundWidgetType = widgetTypeService.findWidgetTypeById(tenantId, savedWidgetType.getId());
  241 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  242 + WidgetTypeDetails foundWidgetType = widgetTypeService.findWidgetTypeDetailsById(tenantId, savedWidgetType.getId());
242 243 Assert.assertNotNull(foundWidgetType);
243 244 Assert.assertEquals(savedWidgetType, foundWidgetType);
244 245
... ... @@ -252,12 +253,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
252 253 widgetsBundle.setTitle("Widgets bundle");
253 254 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
254 255
255   - WidgetType widgetType = new WidgetType();
  256 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
256 257 widgetType.setTenantId(tenantId);
257 258 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
258 259 widgetType.setName("Widget Type");
259 260 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
260   - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
  261 + WidgetType savedWidgetType = new WidgetType(widgetTypeService.saveWidgetType(widgetType));
261 262 WidgetType foundWidgetType = widgetTypeService.findWidgetTypeByTenantIdBundleAliasAndAlias(tenantId, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias());
262 263 Assert.assertNotNull(foundWidgetType);
263 264 Assert.assertEquals(savedWidgetType, foundWidgetType);
... ... @@ -272,7 +273,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
272 273 widgetsBundle.setTitle("Widgets bundle");
273 274 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
274 275
275   - WidgetType widgetType = new WidgetType();
  276 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
276 277 widgetType.setTenantId(tenantId);
277 278 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
278 279 widgetType.setName("Widget Type");
... ... @@ -296,12 +297,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
296 297
297 298 List<WidgetType> widgetTypes = new ArrayList<>();
298 299 for (int i=0;i<121;i++) {
299   - WidgetType widgetType = new WidgetType();
  300 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
300 301 widgetType.setTenantId(tenantId);
301 302 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
302 303 widgetType.setName("Widget Type " + i);
303 304 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
304   - widgetTypes.add(widgetTypeService.saveWidgetType(widgetType));
  305 + widgetTypes.add(new WidgetType(widgetTypeService.saveWidgetType(widgetType)));
305 306 }
306 307
307 308 List<WidgetType> loadedWidgetTypes = widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(tenantId, savedWidgetsBundle.getAlias());
... ...
... ... @@ -21,11 +21,23 @@ import { HttpClient } from '@angular/common/http';
21 21 import { PageLink } from '@shared/models/page/page-link';
22 22 import { PageData } from '@shared/models/page/page-data';
23 23 import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
24   -import { Widget, WidgetType, widgetType, widgetTypesData } from '@shared/models/widget.models';
  24 +import {
  25 + Widget,
  26 + WidgetType,
  27 + widgetType,
  28 + WidgetTypeDetails,
  29 + WidgetTypeInfo,
  30 + widgetTypesData
  31 +} from '@shared/models/widget.models';
25 32 import { UtilsService } from '@core/services/utils.service';
26 33 import { TranslateService } from '@ngx-translate/core';
27 34 import { ResourcesService } from '../services/resources.service';
28   -import { toWidgetInfo, toWidgetType, WidgetInfo } from '@app/modules/home/models/widget-component.models';
  35 +import {
  36 + toWidgetInfo,
  37 + toWidgetType,
  38 + toWidgetTypeDetails,
  39 + WidgetInfo
  40 +} from '@app/modules/home/models/widget-component.models';
29 41 import { filter, map, mergeMap, tap } from 'rxjs/operators';
30 42 import { WidgetTypeId } from '@shared/models/id/widget-type-id';
31 43 import { NULL_UUID } from '@shared/models/id/has-uuid';
... ... @@ -117,6 +129,18 @@ export class WidgetService {
117 129 defaultHttpOptionsFromConfig(config));
118 130 }
119 131
  132 + public getBundleWidgetTypesDetails(bundleAlias: string, isSystem: boolean,
  133 + config?: RequestConfig): Observable<Array<WidgetTypeDetails>> {
  134 + return this.http.get<Array<WidgetTypeDetails>>(`/api/widgetTypesDetails?isSystem=${isSystem}&bundleAlias=${bundleAlias}`,
  135 + defaultHttpOptionsFromConfig(config));
  136 + }
  137 +
  138 + public getBundleWidgetTypeInfos(bundleAlias: string, isSystem: boolean,
  139 + config?: RequestConfig): Observable<Array<WidgetTypeInfo>> {
  140 + return this.http.get<Array<WidgetTypeInfo>>(`/api/widgetTypesInfos?isSystem=${isSystem}&bundleAlias=${bundleAlias}`,
  141 + defaultHttpOptionsFromConfig(config));
  142 + }
  143 +
120 144 public loadBundleLibraryWidgets(bundleAlias: string, isSystem: boolean,
121 145 config?: RequestConfig): Observable<Array<Widget>> {
122 146 return this.getBundleWidgetTypes(bundleAlias, isSystem, config).pipe(
... ... @@ -144,8 +168,6 @@ export class WidgetService {
144 168 typeAlias: widgetTypeInfo.alias,
145 169 type: widgetTypeInfo.type,
146 170 title: widgetTypeInfo.widgetName,
147   - image: widgetTypeInfo.image,
148   - description: widgetTypeInfo.description,
149 171 sizeX,
150 172 sizeY,
151 173 row: top,
... ... @@ -178,22 +200,22 @@ export class WidgetService {
178 200 defaultHttpOptionsFromConfig(config));
179 201 }
180 202
181   - public saveWidgetType(widgetInfo: WidgetInfo,
182   - id: WidgetTypeId,
183   - bundleAlias: string,
184   - createdTime: number,
185   - config?: RequestConfig): Observable<WidgetType> {
186   - const widgetTypeInstance = toWidgetType(widgetInfo, id, undefined, bundleAlias, createdTime);
187   - return this.http.post<WidgetType>('/api/widgetType', widgetTypeInstance,
  203 + public saveWidgetTypeDetails(widgetInfo: WidgetInfo,
  204 + id: WidgetTypeId,
  205 + bundleAlias: string,
  206 + createdTime: number,
  207 + config?: RequestConfig): Observable<WidgetTypeDetails> {
  208 + const widgetTypeDetails = toWidgetTypeDetails(widgetInfo, id, undefined, bundleAlias, createdTime);
  209 + return this.http.post<WidgetTypeDetails>('/api/widgetType', widgetTypeDetails,
188 210 defaultHttpOptionsFromConfig(config)).pipe(
189 211 tap((savedWidgetType) => {
190 212 this.widgetTypeUpdatedSubject.next(savedWidgetType);
191 213 }));
192 214 }
193 215
194   - public saveImportedWidgetType(widgetTypeInstance: WidgetType,
195   - config?: RequestConfig): Observable<WidgetType> {
196   - return this.http.post<WidgetType>('/api/widgetType', widgetTypeInstance,
  216 + public saveImportedWidgetTypeDetails(widgetTypeDetails: WidgetTypeDetails,
  217 + config?: RequestConfig): Observable<WidgetTypeDetails> {
  218 + return this.http.post<WidgetTypeDetails>('/api/widgetType', widgetTypeDetails,
197 219 defaultHttpOptionsFromConfig(config)).pipe(
198 220 tap((savedWidgetType) => {
199 221 this.widgetTypeUpdatedSubject.next(savedWidgetType);
... ... @@ -215,8 +237,8 @@ export class WidgetService {
215 237 }
216 238
217 239 public getWidgetTypeById(widgetTypeId: string,
218   - config?: RequestConfig): Observable<WidgetType> {
219   - return this.http.get<WidgetType>(`/api/widgetType/${widgetTypeId}`,
  240 + config?: RequestConfig): Observable<WidgetTypeDetails> {
  241 + return this.http.get<WidgetTypeDetails>(`/api/widgetType/${widgetTypeId}`,
220 242 defaultHttpOptionsFromConfig(config));
221 243 }
222 244
... ...
... ... @@ -470,8 +470,6 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
470 470 typeAlias: widgetInfo.alias,
471 471 type: widgetInfo.type,
472 472 title: widgetInfo.widgetName,
473   - image: widgetInfo.image,
474   - description: widgetInfo.description,
475 473 sizeX,
476 474 sizeY,
477 475 row: 0,
... ...
... ... @@ -97,17 +97,16 @@ export class DashboardWidgetSelectComponent implements OnInit {
97 97 if (this.widgetsBundle !== null) {
98 98 const bundleAlias = this.widgetsBundle.alias;
99 99 const isSystem = this.widgetsBundle.tenantId.id === NULL_UUID;
100   - this.widgetsInfo = this.widgetsService.getBundleWidgetTypes(bundleAlias, isSystem).pipe(
  100 + this.widgetsInfo = this.widgetsService.getBundleWidgetTypeInfos(bundleAlias, isSystem).pipe(
101 101 map(widgets => widgets.sort((a, b) => b.createdTime - a.createdTime)),
102   - map(widgets => widgets.map((type) => {
103   - const widgetTypeInfo = toWidgetInfo(type);
104   - this.widgetsType.add(widgetTypeInfo.type);
  102 + map(widgets => widgets.map((widgetTypeInfo) => {
  103 + this.widgetsType.add(widgetTypeInfo.widgetType);
105 104 const widget: WidgetInfo = {
106 105 isSystemType: isSystem,
107 106 bundleAlias,
108 107 typeAlias: widgetTypeInfo.alias,
109   - type: widgetTypeInfo.type,
110   - title: widgetTypeInfo.widgetName,
  108 + type: widgetTypeInfo.widgetType,
  109 + title: widgetTypeInfo.name,
111 110 image: widgetTypeInfo.image,
112 111 description: widgetTypeInfo.description
113 112 };
... ...
... ... @@ -14,7 +14,7 @@
14 14 /// limitations under the License.
15 15 ///
16 16
17   -import { Widget, WidgetType } from '@app/shared/models/widget.models';
  17 +import { Widget, WidgetType, WidgetTypeDetails } from '@app/shared/models/widget.models';
18 18 import { DashboardLayoutId } from '@shared/models/dashboard.models';
19 19 import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
20 20
... ... @@ -25,7 +25,7 @@ export interface ImportWidgetResult {
25 25
26 26 export interface WidgetsBundleItem {
27 27 widgetsBundle: WidgetsBundle;
28   - widgetTypes: WidgetType[];
  28 + widgetTypes: WidgetTypeDetails[];
29 29 }
30 30
31 31 export interface CsvToJsonConfig {
... ...
... ... @@ -38,7 +38,7 @@ import { forkJoin, Observable, of } from 'rxjs';
38 38 import { catchError, map, mergeMap, tap } from 'rxjs/operators';
39 39 import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
40 40 import { EntityService } from '@core/http/entity.service';
41   -import { Widget, WidgetSize, WidgetType } from '@shared/models/widget.models';
  41 +import { Widget, WidgetSize, WidgetType, WidgetTypeDetails } from '@shared/models/widget.models';
42 42 import {
43 43 EntityAliasesDialogComponent,
44 44 EntityAliasesDialogData
... ... @@ -234,13 +234,13 @@ export class ImportExportService {
234 234
235 235 public exportWidgetType(widgetTypeId: string) {
236 236 this.widgetService.getWidgetTypeById(widgetTypeId).subscribe(
237   - (widgetType) => {
238   - if (isDefined(widgetType.bundleAlias)) {
239   - delete widgetType.bundleAlias;
  237 + (widgetTypeDetails) => {
  238 + if (isDefined(widgetTypeDetails.bundleAlias)) {
  239 + delete widgetTypeDetails.bundleAlias;
240 240 }
241   - let name = widgetType.name;
  241 + let name = widgetTypeDetails.name;
242 242 name = name.toLowerCase().replace(/\W/g, '_');
243   - this.exportToPc(this.prepareExport(widgetType), name);
  243 + this.exportToPc(this.prepareExport(widgetTypeDetails), name);
244 244 },
245 245 (e) => {
246 246 this.handleExportError(e, 'widget-type.export-failed-error');
... ... @@ -250,15 +250,15 @@ export class ImportExportService {
250 250
251 251 public importWidgetType(bundleAlias: string): Observable<WidgetType> {
252 252 return this.openImportDialog('widget-type.import', 'widget-type.widget-type-file').pipe(
253   - mergeMap((widgetType: WidgetType) => {
254   - if (!this.validateImportedWidgetType(widgetType)) {
  253 + mergeMap((widgetTypeDetails: WidgetTypeDetails) => {
  254 + if (!this.validateImportedWidgetTypeDetails(widgetTypeDetails)) {
255 255 this.store.dispatch(new ActionNotificationShow(
256 256 {message: this.translate.instant('widget-type.invalid-widget-type-file-error'),
257 257 type: 'error'}));
258 258 throw new Error('Invalid widget type file');
259 259 } else {
260   - widgetType.bundleAlias = bundleAlias;
261   - return this.widgetService.saveImportedWidgetType(widgetType);
  260 + widgetTypeDetails.bundleAlias = bundleAlias;
  261 + return this.widgetService.saveImportedWidgetTypeDetails(widgetTypeDetails);
262 262 }
263 263 }),
264 264 catchError((err) => {
... ... @@ -272,18 +272,18 @@ export class ImportExportService {
272 272 (widgetsBundle) => {
273 273 const bundleAlias = widgetsBundle.alias;
274 274 const isSystem = widgetsBundle.tenantId.id === NULL_UUID;
275   - this.widgetService.getBundleWidgetTypes(bundleAlias, isSystem).subscribe(
276   - (widgetTypes) => {
277   - widgetTypes = widgetTypes.sort((a, b) => a.createdTime - b.createdTime);
  275 + this.widgetService.getBundleWidgetTypesDetails(bundleAlias, isSystem).subscribe(
  276 + (widgetTypesDetails) => {
  277 + widgetTypesDetails = widgetTypesDetails.sort((a, b) => a.createdTime - b.createdTime);
278 278 const widgetsBundleItem: WidgetsBundleItem = {
279 279 widgetsBundle: this.prepareExport(widgetsBundle),
280 280 widgetTypes: []
281 281 };
282   - for (const widgetType of widgetTypes) {
283   - if (isDefined(widgetType.bundleAlias)) {
284   - delete widgetType.bundleAlias;
  282 + for (const widgetTypeDetails of widgetTypesDetails) {
  283 + if (isDefined(widgetTypeDetails.bundleAlias)) {
  284 + delete widgetTypeDetails.bundleAlias;
285 285 }
286   - widgetsBundleItem.widgetTypes.push(this.prepareExport(widgetType));
  286 + widgetsBundleItem.widgetTypes.push(this.prepareExport(widgetTypeDetails));
287 287 }
288 288 let name = widgetsBundle.title;
289 289 name = name.toLowerCase().replace(/\W/g, '_');
... ... @@ -313,12 +313,12 @@ export class ImportExportService {
313 313 return this.widgetService.saveWidgetsBundle(widgetsBundle).pipe(
314 314 mergeMap((savedWidgetsBundle) => {
315 315 const bundleAlias = savedWidgetsBundle.alias;
316   - const widgetTypes = widgetsBundleItem.widgetTypes;
317   - if (widgetTypes.length) {
  316 + const widgetTypesDetails = widgetsBundleItem.widgetTypes;
  317 + if (widgetTypesDetails.length) {
318 318 const saveWidgetTypesObservables: Array<Observable<WidgetType>> = [];
319   - for (const widgetType of widgetTypes) {
320   - widgetType.bundleAlias = bundleAlias;
321   - saveWidgetTypesObservables.push(this.widgetService.saveImportedWidgetType(widgetType));
  319 + for (const widgetTypeDetails of widgetTypesDetails) {
  320 + widgetTypeDetails.bundleAlias = bundleAlias;
  321 + saveWidgetTypesObservables.push(this.widgetService.saveImportedWidgetTypeDetails(widgetTypeDetails));
322 322 }
323 323 return forkJoin(saveWidgetTypesObservables).pipe(
324 324 map(() => savedWidgetsBundle)
... ... @@ -508,9 +508,9 @@ export class ImportExportService {
508 508 return true;
509 509 }
510 510
511   - private validateImportedWidgetType(widgetType: WidgetType): boolean {
512   - if (isUndefined(widgetType.name)
513   - || isUndefined(widgetType.descriptor)) {
  511 + private validateImportedWidgetTypeDetails(widgetTypeDetails: WidgetTypeDetails): boolean {
  512 + if (isUndefined(widgetTypeDetails.name)
  513 + || isUndefined(widgetTypeDetails.descriptor)) {
514 514 return false;
515 515 }
516 516 return true;
... ... @@ -527,9 +527,9 @@ export class ImportExportService {
527 527 if (isUndefined(widgetsBundle.title)) {
528 528 return false;
529 529 }
530   - const widgetTypes = widgetsBundleItem.widgetTypes;
531   - for (const widgetType of widgetTypes) {
532   - if (!this.validateImportedWidgetType(widgetType)) {
  530 + const widgetTypesDetails = widgetsBundleItem.widgetTypes;
  531 + for (const widgetTypeDetails of widgetTypesDetails) {
  532 + if (!this.validateImportedWidgetTypeDetails(widgetTypeDetails)) {
533 533 return false;
534 534 }
535 535 }
... ...
... ... @@ -104,8 +104,6 @@ export class WidgetComponentService {
104 104 controllerScript: this.utils.editWidgetInfo.controllerScript,
105 105 settingsSchema: this.utils.editWidgetInfo.settingsSchema,
106 106 dataKeySettingsSchema: this.utils.editWidgetInfo.dataKeySettingsSchema,
107   - image: this.utils.editWidgetInfo.image,
108   - description: this.utils.editWidgetInfo.description,
109 107 defaultConfig: this.utils.editWidgetInfo.defaultConfig
110 108 }, new WidgetTypeId('1'), new TenantId( NULL_UUID ), 'customWidgetBundle', undefined
111 109 );
... ...
... ... @@ -27,7 +27,7 @@ import {
27 27 WidgetControllerDescriptor,
28 28 WidgetType,
29 29 widgetType,
30   - WidgetTypeDescriptor,
  30 + WidgetTypeDescriptor, WidgetTypeDetails,
31 31 WidgetTypeParameters
32 32 } from '@shared/models/widget.models';
33 33 import { Timewindow, WidgetTimewindow } from '@shared/models/time/time.models';
... ... @@ -347,8 +347,8 @@ export interface WidgetInfo extends WidgetTypeDescriptor, WidgetControllerDescri
347 347 alias: string;
348 348 typeSettingsSchema?: string | any;
349 349 typeDataKeySettingsSchema?: string | any;
350   - image: string;
351   - description: string;
  350 + image?: string;
  351 + description?: string;
352 352 componentFactory?: ComponentFactory<IDynamicWidgetComponent>;
353 353 }
354 354
... ... @@ -427,11 +427,16 @@ export interface WidgetTypeInstance {
427 427 onDestroy?: () => void;
428 428 }
429 429
  430 +export function detailsToWidgetInfo(widgetTypeDetailsEntity: WidgetTypeDetails): WidgetInfo {
  431 + const widgetInfo = toWidgetInfo(widgetTypeDetailsEntity);
  432 + widgetInfo.image = widgetTypeDetailsEntity.image;
  433 + widgetInfo.description = widgetTypeDetailsEntity.description;
  434 + return widgetInfo;
  435 +}
  436 +
430 437 export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo {
431 438 return {
432 439 widgetName: widgetTypeEntity.name,
433   - image: widgetTypeEntity.image,
434   - description: widgetTypeEntity.description,
435 440 alias: widgetTypeEntity.alias,
436 441 type: widgetTypeEntity.descriptor.type,
437 442 sizeX: widgetTypeEntity.descriptor.sizeX,
... ... @@ -446,6 +451,16 @@ export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo {
446 451 };
447 452 }
448 453
  454 +export function toWidgetTypeDetails(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: TenantId,
  455 + bundleAlias: string, createdTime: number): WidgetTypeDetails {
  456 + const widgetTypeEntity = toWidgetType(widgetInfo, id, tenantId, bundleAlias, createdTime);
  457 + const widgetTypeDetails: WidgetTypeDetails = {...widgetTypeEntity,
  458 + description: widgetInfo.description,
  459 + image: widgetInfo.image
  460 + };
  461 + return widgetTypeDetails;
  462 +}
  463 +
449 464 export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: TenantId,
450 465 bundleAlias: string, createdTime: number): WidgetType {
451 466 const descriptor: WidgetTypeDescriptor = {
... ... @@ -467,8 +482,6 @@ export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId:
467 482 bundleAlias,
468 483 alias: widgetInfo.alias,
469 484 name: widgetInfo.widgetName,
470   - image: widgetInfo.image,
471   - description: widgetInfo.description,
472 485 descriptor
473 486 };
474 487 }
... ...
... ... @@ -20,8 +20,15 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
20 20 import { Store } from '@ngrx/store';
21 21 import { AppState } from '@core/core.state';
22 22 import { WidgetService } from '@core/http/widget.service';
23   -import { toWidgetInfo, WidgetInfo } from '@home/models/widget-component.models';
24   -import { Widget, WidgetConfig, WidgetType, widgetType, widgetTypesData } from '@shared/models/widget.models';
  23 +import { detailsToWidgetInfo, toWidgetInfo, WidgetInfo } from '@home/models/widget-component.models';
  24 +import {
  25 + Widget,
  26 + WidgetConfig,
  27 + WidgetType,
  28 + widgetType,
  29 + WidgetTypeDetails,
  30 + widgetTypesData
  31 +} from '@shared/models/widget.models';
25 32 import { ActivatedRoute, Router } from '@angular/router';
26 33 import { deepClone } from '@core/utils';
27 34 import { HasDirtyFlag } from '@core/guards/confirm-on-exit.guard';
... ... @@ -108,7 +115,7 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
108 115 isReadOnly: boolean;
109 116
110 117 widgetsBundle: WidgetsBundle;
111   - widgetType: WidgetType;
  118 + widgetTypeDetails: WidgetTypeDetails;
112 119 widget: WidgetInfo;
113 120 origWidget: WidgetInfo;
114 121
... ... @@ -175,14 +182,14 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
175 182 } else {
176 183 this.isReadOnly = this.authUser.authority !== Authority.SYS_ADMIN;
177 184 }
178   - this.widgetType = data.widgetEditorData.widgetType;
  185 + this.widgetTypeDetails = data.widgetEditorData.widgetTypeDetails;
179 186 this.widget = data.widgetEditorData.widget;
180   - if (this.widgetType) {
  187 + if (this.widgetTypeDetails) {
181 188 const config = JSON.parse(this.widget.defaultConfig);
182 189 this.widget.defaultConfig = JSON.stringify(config);
183 190 }
184 191 this.origWidget = deepClone(this.widget);
185   - if (!this.widgetType) {
  192 + if (!this.widgetTypeDetails) {
186 193 this.isDirty = true;
187 194 }
188 195 }
... ... @@ -515,11 +522,11 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
515 522 }
516 523
517 524 private commitSaveWidget() {
518   - const id = (this.widgetType && this.widgetType.id) ? this.widgetType.id : undefined;
519   - const createdTime = (this.widgetType && this.widgetType.createdTime) ? this.widgetType.createdTime : undefined;
520   - this.widgetService.saveWidgetType(this.widget, id, this.widgetsBundle.alias, createdTime).subscribe(
521   - (widgetTypeInstance) => {
522   - this.setWidgetType(widgetTypeInstance);
  525 + const id = (this.widgetTypeDetails && this.widgetTypeDetails.id) ? this.widgetTypeDetails.id : undefined;
  526 + const createdTime = (this.widgetTypeDetails && this.widgetTypeDetails.createdTime) ? this.widgetTypeDetails.createdTime : undefined;
  527 + this.widgetService.saveWidgetTypeDetails(this.widget, id, this.widgetsBundle.alias, createdTime).subscribe(
  528 + (widgetTypeDetails) => {
  529 + this.setWidgetTypeDetails(widgetTypeDetails);
523 530 this.saveWidgetPending = false;
524 531 this.store.dispatch(new ActionNotificationShow(
525 532 {message: this.translate.instant('widget.widget-saved'), type: 'success', duration: 500}));
... ... @@ -544,9 +551,9 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
544 551 config.title = this.widget.widgetName;
545 552 this.widget.defaultConfig = JSON.stringify(config);
546 553 this.isDirty = false;
547   - this.widgetService.saveWidgetType(this.widget, undefined, saveWidgetAsData.bundleAlias, undefined).subscribe(
548   - (widgetTypeInstance) => {
549   - this.router.navigateByUrl(`/widgets-bundles/${saveWidgetAsData.bundleId}/widgetTypes/${widgetTypeInstance.id.id}`);
  554 + this.widgetService.saveWidgetTypeDetails(this.widget, undefined, saveWidgetAsData.bundleAlias, undefined).subscribe(
  555 + (widgetTypeDetails) => {
  556 + this.router.navigateByUrl(`/widgets-bundles/${saveWidgetAsData.bundleId}/widgetTypes/${widgetTypeDetails.id.id}`);
550 557 }
551 558 );
552 559 }
... ... @@ -555,9 +562,9 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
555 562 );
556 563 }
557 564
558   - private setWidgetType(widgetTypeInstance: WidgetType) {
559   - this.widgetType = widgetTypeInstance;
560   - this.widget = toWidgetInfo(this.widgetType);
  565 + private setWidgetTypeDetails(widgetTypeDetails: WidgetTypeDetails) {
  566 + this.widgetTypeDetails = widgetTypeDetails;
  567 + this.widget = detailsToWidgetInfo(this.widgetTypeDetails);
561 568 const config = JSON.parse(this.widget.defaultConfig);
562 569 this.widget.defaultConfig = JSON.stringify(config);
563 570 this.origWidget = deepClone(this.widget);
... ...
... ... @@ -27,14 +27,14 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
27 27 import { WidgetService } from '@core/http/widget.service';
28 28 import { WidgetEditorComponent } from '@home/pages/widget/widget-editor.component';
29 29 import { map } from 'rxjs/operators';
30   -import { toWidgetInfo, WidgetInfo } from '@home/models/widget-component.models';
31   -import { widgetType, WidgetType } from '@app/shared/models/widget.models';
  30 +import { detailsToWidgetInfo, toWidgetInfo, WidgetInfo } from '@home/models/widget-component.models';
  31 +import { widgetType, WidgetType, WidgetTypeDetails } from '@app/shared/models/widget.models';
32 32 import { ConfirmOnExitGuard } from '@core/guards/confirm-on-exit.guard';
33 33 import { WidgetsData } from '@home/models/dashboard-component.models';
34 34 import { NULL_UUID } from '@shared/models/id/has-uuid';
35 35
36 36 export interface WidgetEditorData {
37   - widgetType: WidgetType;
  37 + widgetTypeDetails: WidgetTypeDetails;
38 38 widget: WidgetInfo;
39 39 }
40 40
... ... @@ -83,8 +83,8 @@ export class WidgetEditorDataResolver implements Resolve<WidgetEditorData> {
83 83 return this.widgetsService.getWidgetTypeById(widgetTypeId).pipe(
84 84 map((result) => {
85 85 return {
86   - widgetType: result,
87   - widget: toWidgetInfo(result)
  86 + widgetTypeDetails: result,
  87 + widget: detailsToWidgetInfo(result)
88 88 };
89 89 })
90 90 );
... ... @@ -106,7 +106,7 @@ export class WidgetEditorAddDataResolver implements Resolve<WidgetEditorData> {
106 106 map((widget) => {
107 107 widget.widgetName = null;
108 108 return {
109   - widgetType: null,
  109 + widgetTypeDetails: null,
110 110 widget
111 111 };
112 112 })
... ...
... ... @@ -165,14 +165,26 @@ export interface WidgetControllerDescriptor {
165 165 actionSources?: {[actionSourceId: string]: WidgetActionSource};
166 166 }
167 167
168   -export interface WidgetType extends BaseData<WidgetTypeId> {
  168 +export interface BaseWidgetType extends BaseData<WidgetTypeId> {
169 169 tenantId: TenantId;
170 170 bundleAlias: string;
171 171 alias: string;
172 172 name: string;
  173 +}
  174 +
  175 +export interface WidgetType extends BaseWidgetType {
  176 + descriptor: WidgetTypeDescriptor;
  177 +}
  178 +
  179 +export interface WidgetTypeInfo extends BaseWidgetType {
  180 + image: string;
  181 + description: string;
  182 + widgetType: widgetType;
  183 +}
  184 +
  185 +export interface WidgetTypeDetails extends WidgetType {
173 186 image: string;
174 187 description: string;
175   - descriptor: WidgetTypeDescriptor;
176 188 }
177 189
178 190 export enum LegendDirection {
... ... @@ -417,8 +429,8 @@ export interface WidgetInfo {
417 429 typeAlias: string;
418 430 type: widgetType;
419 431 title: string;
420   - image: string;
421   - description: string;
  432 + image?: string;
  433 + description?: string;
422 434 }
423 435
424 436 export interface GroupInfo {
... ...