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,6 +78,7 @@ import org.thingsboard.server.common.data.plugin.ComponentType;
78 import org.thingsboard.server.common.data.rule.RuleChain; 78 import org.thingsboard.server.common.data.rule.RuleChain;
79 import org.thingsboard.server.common.data.rule.RuleNode; 79 import org.thingsboard.server.common.data.rule.RuleNode;
80 import org.thingsboard.server.common.data.widget.WidgetType; 80 import org.thingsboard.server.common.data.widget.WidgetType;
  81 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
81 import org.thingsboard.server.common.data.widget.WidgetsBundle; 82 import org.thingsboard.server.common.data.widget.WidgetsBundle;
82 import org.thingsboard.server.common.msg.TbMsg; 83 import org.thingsboard.server.common.msg.TbMsg;
83 import org.thingsboard.server.common.msg.TbMsgDataType; 84 import org.thingsboard.server.common.msg.TbMsgDataType;
@@ -584,13 +585,13 @@ public abstract class BaseController { @@ -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 try { 589 try {
589 validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId); 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 } catch (Exception e) { 595 } catch (Exception e) {
595 throw handleException(e, false); 596 throw handleException(e, false);
596 } 597 }
@@ -30,6 +30,8 @@ import org.thingsboard.server.common.data.id.TenantId; @@ -30,6 +30,8 @@ import org.thingsboard.server.common.data.id.TenantId;
30 import org.thingsboard.server.common.data.id.WidgetTypeId; 30 import org.thingsboard.server.common.data.id.WidgetTypeId;
31 import org.thingsboard.server.common.data.security.Authority; 31 import org.thingsboard.server.common.data.security.Authority;
32 import org.thingsboard.server.common.data.widget.WidgetType; 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 import org.thingsboard.server.dao.model.ModelConstants; 35 import org.thingsboard.server.dao.model.ModelConstants;
34 import org.thingsboard.server.queue.util.TbCoreComponent; 36 import org.thingsboard.server.queue.util.TbCoreComponent;
35 import org.thingsboard.server.service.security.permission.Operation; 37 import org.thingsboard.server.service.security.permission.Operation;
@@ -45,7 +47,7 @@ public class WidgetTypeController extends BaseController { @@ -45,7 +47,7 @@ public class WidgetTypeController extends BaseController {
45 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") 47 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
46 @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.GET) 48 @RequestMapping(value = "/widgetType/{widgetTypeId}", method = RequestMethod.GET)
47 @ResponseBody 49 @ResponseBody
48 - public WidgetType getWidgetTypeById(@PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException { 50 + public WidgetTypeDetails getWidgetTypeById(@PathVariable("widgetTypeId") String strWidgetTypeId) throws ThingsboardException {
49 checkParameter("widgetTypeId", strWidgetTypeId); 51 checkParameter("widgetTypeId", strWidgetTypeId);
50 try { 52 try {
51 WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId)); 53 WidgetTypeId widgetTypeId = new WidgetTypeId(toUUID(strWidgetTypeId));
@@ -58,17 +60,17 @@ public class WidgetTypeController extends BaseController { @@ -58,17 +60,17 @@ public class WidgetTypeController extends BaseController {
58 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')") 60 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN')")
59 @RequestMapping(value = "/widgetType", method = RequestMethod.POST) 61 @RequestMapping(value = "/widgetType", method = RequestMethod.POST)
60 @ResponseBody 62 @ResponseBody
61 - public WidgetType saveWidgetType(@RequestBody WidgetType widgetType) throws ThingsboardException { 63 + public WidgetTypeDetails saveWidgetType(@RequestBody WidgetTypeDetails widgetTypeDetails) throws ThingsboardException {
62 try { 64 try {
63 if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) { 65 if (Authority.SYS_ADMIN.equals(getCurrentUser().getAuthority())) {
64 - widgetType.setTenantId(TenantId.SYS_TENANT_ID); 66 + widgetTypeDetails.setTenantId(TenantId.SYS_TENANT_ID);
65 } else { 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 } catch (Exception e) { 74 } catch (Exception e) {
73 throw handleException(e); 75 throw handleException(e);
74 } 76 }
@@ -107,6 +109,44 @@ public class WidgetTypeController extends BaseController { @@ -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 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')") 150 @PreAuthorize("hasAnyAuthority('SYS_ADMIN', 'TENANT_ADMIN', 'CUSTOMER_USER')")
111 @RequestMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"}, method = RequestMethod.GET) 151 @RequestMapping(value = "/widgetType", params = {"isSystem", "bundleAlias", "alias"}, method = RequestMethod.GET)
112 @ResponseBody 152 @ResponseBody
@@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplat @@ -30,6 +30,7 @@ import org.thingsboard.server.common.data.oauth2.OAuth2ClientRegistrationTemplat
30 import org.thingsboard.server.common.data.rule.RuleChain; 30 import org.thingsboard.server.common.data.rule.RuleChain;
31 import org.thingsboard.server.common.data.rule.RuleChainMetaData; 31 import org.thingsboard.server.common.data.rule.RuleChainMetaData;
32 import org.thingsboard.server.common.data.widget.WidgetType; 32 import org.thingsboard.server.common.data.widget.WidgetType;
  33 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
33 import org.thingsboard.server.common.data.widget.WidgetsBundle; 34 import org.thingsboard.server.common.data.widget.WidgetsBundle;
34 import org.thingsboard.server.dao.dashboard.DashboardService; 35 import org.thingsboard.server.dao.dashboard.DashboardService;
35 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService; 36 import org.thingsboard.server.dao.oauth2.OAuth2ConfigTemplateService;
@@ -168,9 +169,9 @@ public class InstallScripts { @@ -168,9 +169,9 @@ public class InstallScripts {
168 widgetTypesArrayJson.forEach( 169 widgetTypesArrayJson.forEach(
169 widgetTypeJson -> { 170 widgetTypeJson -> {
170 try { 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 } catch (Exception e) { 175 } catch (Exception e) {
175 log.error("Unable to load widget type from json: [{}]", path.toString()); 176 log.error("Unable to load widget type from json: [{}]", path.toString());
176 throw new RuntimeException("Unable to load widget type from json", e); 177 throw new RuntimeException("Unable to load widget type from json", e);
@@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.Tenant; @@ -26,6 +26,7 @@ import org.thingsboard.server.common.data.Tenant;
26 import org.thingsboard.server.common.data.User; 26 import org.thingsboard.server.common.data.User;
27 import org.thingsboard.server.common.data.security.Authority; 27 import org.thingsboard.server.common.data.security.Authority;
28 import org.thingsboard.server.common.data.widget.WidgetType; 28 import org.thingsboard.server.common.data.widget.WidgetType;
  29 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
29 import org.thingsboard.server.common.data.widget.WidgetsBundle; 30 import org.thingsboard.server.common.data.widget.WidgetsBundle;
30 31
31 import java.util.ArrayList; 32 import java.util.ArrayList;
@@ -76,11 +77,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -76,11 +77,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
76 77
77 @Test 78 @Test
78 public void testSaveWidgetType() throws Exception { 79 public void testSaveWidgetType() throws Exception {
79 - WidgetType widgetType = new WidgetType(); 80 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
80 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 81 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
81 widgetType.setName("Widget Type"); 82 widgetType.setName("Widget Type");
82 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 Assert.assertNotNull(savedWidgetType); 86 Assert.assertNotNull(savedWidgetType);
86 Assert.assertNotNull(savedWidgetType.getId()); 87 Assert.assertNotNull(savedWidgetType.getId());
@@ -95,42 +96,42 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -95,42 +96,42 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
95 96
96 doPost("/api/widgetType", savedWidgetType, WidgetType.class); 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 Assert.assertEquals(foundWidgetType.getName(), savedWidgetType.getName()); 100 Assert.assertEquals(foundWidgetType.getName(), savedWidgetType.getName());
100 } 101 }
101 102
102 @Test 103 @Test
103 public void testUpdateWidgetTypeFromDifferentTenant() throws Exception { 104 public void testUpdateWidgetTypeFromDifferentTenant() throws Exception {
104 - WidgetType widgetType = new WidgetType(); 105 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
105 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 106 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
106 widgetType.setName("Widget Type"); 107 widgetType.setName("Widget Type");
107 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 loginDifferentTenant(); 111 loginDifferentTenant();
111 - doPost("/api/widgetType", savedWidgetType, WidgetType.class, status().isForbidden()); 112 + doPost("/api/widgetType", savedWidgetType, WidgetTypeDetails.class, status().isForbidden());
112 deleteDifferentTenant(); 113 deleteDifferentTenant();
113 } 114 }
114 115
115 @Test 116 @Test
116 public void testFindWidgetTypeById() throws Exception { 117 public void testFindWidgetTypeById() throws Exception {
117 - WidgetType widgetType = new WidgetType(); 118 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
118 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 119 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
119 widgetType.setName("Widget Type"); 120 widgetType.setName("Widget Type");
120 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 Assert.assertNotNull(foundWidgetType); 124 Assert.assertNotNull(foundWidgetType);
124 Assert.assertEquals(savedWidgetType, foundWidgetType); 125 Assert.assertEquals(savedWidgetType, foundWidgetType);
125 } 126 }
126 127
127 @Test 128 @Test
128 public void testDeleteWidgetType() throws Exception { 129 public void testDeleteWidgetType() throws Exception {
129 - WidgetType widgetType = new WidgetType(); 130 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
130 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 131 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
131 widgetType.setName("Widget Type"); 132 widgetType.setName("Widget Type");
132 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 doDelete("/api/widgetType/"+savedWidgetType.getId().getId().toString()) 136 doDelete("/api/widgetType/"+savedWidgetType.getId().getId().toString())
136 .andExpect(status().isOk()); 137 .andExpect(status().isOk());
@@ -141,7 +142,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -141,7 +142,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
141 142
142 @Test 143 @Test
143 public void testSaveWidgetTypeWithEmptyName() throws Exception { 144 public void testSaveWidgetTypeWithEmptyName() throws Exception {
144 - WidgetType widgetType = new WidgetType(); 145 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
145 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 146 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
146 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 147 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
147 doPost("/api/widgetType", widgetType) 148 doPost("/api/widgetType", widgetType)
@@ -151,7 +152,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -151,7 +152,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
151 152
152 @Test 153 @Test
153 public void testSaveWidgetTypeWithEmptyBundleAlias() throws Exception { 154 public void testSaveWidgetTypeWithEmptyBundleAlias() throws Exception {
154 - WidgetType widgetType = new WidgetType(); 155 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
155 widgetType.setName("Widget Type"); 156 widgetType.setName("Widget Type");
156 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 157 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
157 doPost("/api/widgetType", widgetType) 158 doPost("/api/widgetType", widgetType)
@@ -161,7 +162,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -161,7 +162,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
161 162
162 @Test 163 @Test
163 public void testSaveWidgetTypeWithEmptyDescriptor() throws Exception { 164 public void testSaveWidgetTypeWithEmptyDescriptor() throws Exception {
164 - WidgetType widgetType = new WidgetType(); 165 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
165 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 166 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
166 widgetType.setName("Widget Type"); 167 widgetType.setName("Widget Type");
167 widgetType.setDescriptor(new ObjectMapper().readValue("{}", JsonNode.class)); 168 widgetType.setDescriptor(new ObjectMapper().readValue("{}", JsonNode.class));
@@ -172,7 +173,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -172,7 +173,7 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
172 173
173 @Test 174 @Test
174 public void testSaveWidgetTypeWithInvalidBundleAlias() throws Exception { 175 public void testSaveWidgetTypeWithInvalidBundleAlias() throws Exception {
175 - WidgetType widgetType = new WidgetType(); 176 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
176 widgetType.setBundleAlias("some_alias"); 177 widgetType.setBundleAlias("some_alias");
177 widgetType.setName("Widget Type"); 178 widgetType.setName("Widget Type");
178 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 179 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
@@ -183,11 +184,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -183,11 +184,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
183 184
184 @Test 185 @Test
185 public void testUpdateWidgetTypeBundleAlias() throws Exception { 186 public void testUpdateWidgetTypeBundleAlias() throws Exception {
186 - WidgetType widgetType = new WidgetType(); 187 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
187 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 188 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
188 widgetType.setName("Widget Type"); 189 widgetType.setName("Widget Type");
189 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 savedWidgetType.setBundleAlias("some_alias"); 192 savedWidgetType.setBundleAlias("some_alias");
192 doPost("/api/widgetType", savedWidgetType) 193 doPost("/api/widgetType", savedWidgetType)
193 .andExpect(status().isBadRequest()) 194 .andExpect(status().isBadRequest())
@@ -197,11 +198,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -197,11 +198,11 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
197 198
198 @Test 199 @Test
199 public void testUpdateWidgetTypeAlias() throws Exception { 200 public void testUpdateWidgetTypeAlias() throws Exception {
200 - WidgetType widgetType = new WidgetType(); 201 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
201 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 202 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
202 widgetType.setName("Widget Type"); 203 widgetType.setName("Widget Type");
203 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 savedWidgetType.setAlias("some_alias"); 206 savedWidgetType.setAlias("some_alias");
206 doPost("/api/widgetType", savedWidgetType) 207 doPost("/api/widgetType", savedWidgetType)
207 .andExpect(status().isBadRequest()) 208 .andExpect(status().isBadRequest())
@@ -213,15 +214,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -213,15 +214,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
213 public void testGetBundleWidgetTypes() throws Exception { 214 public void testGetBundleWidgetTypes() throws Exception {
214 List<WidgetType> widgetTypes = new ArrayList<>(); 215 List<WidgetType> widgetTypes = new ArrayList<>();
215 for (int i=0;i<89;i++) { 216 for (int i=0;i<89;i++) {
216 - WidgetType widgetType = new WidgetType(); 217 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
217 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 218 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
218 widgetType.setName("Widget Type " + i); 219 widgetType.setName("Widget Type " + i);
219 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 List<WidgetType> loadedWidgetTypes = doGetTyped("/api/widgetTypes?isSystem={isSystem}&bundleAlias={bundleAlias}", 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 Collections.sort(widgetTypes, idComparator); 227 Collections.sort(widgetTypes, idComparator);
227 Collections.sort(loadedWidgetTypes, idComparator); 228 Collections.sort(loadedWidgetTypes, idComparator);
@@ -231,15 +232,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes @@ -231,15 +232,15 @@ public abstract class BaseWidgetTypeControllerTest extends AbstractControllerTes
231 232
232 @Test 233 @Test
233 public void testGetWidgetType() throws Exception { 234 public void testGetWidgetType() throws Exception {
234 - WidgetType widgetType = new WidgetType(); 235 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
235 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 236 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
236 widgetType.setName("Widget Type"); 237 widgetType.setName("Widget Type");
237 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 WidgetType foundWidgetType = doGet("/api/widgetType?isSystem={isSystem}&bundleAlias={bundleAlias}&alias={alias}", 240 WidgetType foundWidgetType = doGet("/api/widgetType?isSystem={isSystem}&bundleAlias={bundleAlias}&alias={alias}",
240 WidgetType.class, false, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias()); 241 WidgetType.class, false, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias());
241 Assert.assertNotNull(foundWidgetType); 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,6 +18,8 @@ package org.thingsboard.server.dao.widget;
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.id.WidgetTypeId; 19 import org.thingsboard.server.common.data.id.WidgetTypeId;
20 import org.thingsboard.server.common.data.widget.WidgetType; 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 import java.util.List; 24 import java.util.List;
23 25
@@ -25,12 +27,18 @@ public interface WidgetTypeService { @@ -25,12 +27,18 @@ public interface WidgetTypeService {
25 27
26 WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId); 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 void deleteWidgetType(TenantId tenantId, WidgetTypeId widgetTypeId); 34 void deleteWidgetType(TenantId tenantId, WidgetTypeId widgetTypeId);
31 35
32 List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias); 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 WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias); 42 WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias);
35 43
36 void deleteWidgetTypesByTenantIdAndBundleAlias(TenantId tenantId, String bundleAlias); 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,23 +16,12 @@
16 package org.thingsboard.server.common.data.widget; 16 package org.thingsboard.server.common.data.widget;
17 17
18 import com.fasterxml.jackson.databind.JsonNode; 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 import org.thingsboard.server.common.data.id.WidgetTypeId; 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 private transient JsonNode descriptor; 25 private transient JsonNode descriptor;
37 26
38 public WidgetType() { 27 public WidgetType() {
@@ -43,76 +32,13 @@ public class WidgetType extends BaseData<WidgetTypeId> implements HasTenantId { @@ -43,76 +32,13 @@ public class WidgetType extends BaseData<WidgetTypeId> implements HasTenantId {
43 super(id); 32 super(id);
44 } 33 }
45 34
  35 + public WidgetType(BaseWidgetType baseWidgetType) {
  36 + super(baseWidgetType);
  37 + }
  38 +
46 public WidgetType(WidgetType widgetType) { 39 public WidgetType(WidgetType widgetType) {
47 super(widgetType); 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 this.descriptor = widgetType.getDescriptor(); 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,11 +20,8 @@ import lombok.Data;
20 import lombok.EqualsAndHashCode; 20 import lombok.EqualsAndHashCode;
21 import org.hibernate.annotations.Type; 21 import org.hibernate.annotations.Type;
22 import org.hibernate.annotations.TypeDef; 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 import org.thingsboard.server.common.data.widget.WidgetType; 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 import org.thingsboard.server.dao.model.ModelConstants; 25 import org.thingsboard.server.dao.model.ModelConstants;
29 import org.thingsboard.server.dao.util.mapping.JsonStringType; 26 import org.thingsboard.server.dao.util.mapping.JsonStringType;
30 27
@@ -38,25 +35,7 @@ import java.util.UUID; @@ -38,25 +35,7 @@ import java.util.UUID;
38 @Entity 35 @Entity
39 @TypeDef(name = "json", typeClass = JsonStringType.class) 36 @TypeDef(name = "json", typeClass = JsonStringType.class)
40 @Table(name = ModelConstants.WIDGET_TYPE_COLUMN_FAMILY_NAME) 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 @Type(type="json") 40 @Type(type="json")
62 @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY) 41 @Column(name = ModelConstants.WIDGET_TYPE_DESCRIPTOR_PROPERTY)
@@ -66,34 +45,10 @@ public final class WidgetTypeEntity extends BaseSqlEntity<WidgetType> implement @@ -66,34 +45,10 @@ public final class WidgetTypeEntity extends BaseSqlEntity<WidgetType> implement
66 super(); 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 @Override 48 @Override
86 public WidgetType toData() { 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 widgetType.setDescriptor(descriptor); 52 widgetType.setDescriptor(descriptor);
98 return widgetType; 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,8 +18,12 @@ package org.thingsboard.server.dao.sql.widget;
18 import org.springframework.beans.factory.annotation.Autowired; 18 import org.springframework.beans.factory.annotation.Autowired;
19 import org.springframework.data.repository.CrudRepository; 19 import org.springframework.data.repository.CrudRepository;
20 import org.springframework.stereotype.Component; 20 import org.springframework.stereotype.Component;
  21 +import org.thingsboard.server.common.data.id.TenantId;
21 import org.thingsboard.server.common.data.widget.WidgetType; 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 import org.thingsboard.server.dao.DaoUtil; 25 import org.thingsboard.server.dao.DaoUtil;
  26 +import org.thingsboard.server.dao.model.sql.WidgetTypeDetailsEntity;
23 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity; 27 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
24 import org.thingsboard.server.dao.sql.JpaAbstractDao; 28 import org.thingsboard.server.dao.sql.JpaAbstractDao;
25 import org.thingsboard.server.dao.widget.WidgetTypeDao; 29 import org.thingsboard.server.dao.widget.WidgetTypeDao;
@@ -31,28 +35,43 @@ import java.util.UUID; @@ -31,28 +35,43 @@ import java.util.UUID;
31 * Created by Valerii Sosliuk on 4/29/2017. 35 * Created by Valerii Sosliuk on 4/29/2017.
32 */ 36 */
33 @Component 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 @Autowired 40 @Autowired
37 private WidgetTypeRepository widgetTypeRepository; 41 private WidgetTypeRepository widgetTypeRepository;
38 42
39 @Override 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 @Override 48 @Override
45 - protected CrudRepository<WidgetTypeEntity, UUID> getCrudRepository() { 49 + protected CrudRepository<WidgetTypeDetailsEntity, UUID> getCrudRepository() {
46 return widgetTypeRepository; 50 return widgetTypeRepository;
47 } 51 }
48 52
49 @Override 53 @Override
  54 + public WidgetType findWidgetTypeById(TenantId tenantId, UUID widgetTypeId) {
  55 + return DaoUtil.getData(widgetTypeRepository.findWidgetTypeById(widgetTypeId));
  56 + }
  57 +
  58 + @Override
50 public List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias) { 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 return DaoUtil.convertDataList(widgetTypeRepository.findByTenantIdAndBundleAlias(tenantId, bundleAlias)); 65 return DaoUtil.convertDataList(widgetTypeRepository.findByTenantIdAndBundleAlias(tenantId, bundleAlias));
52 } 66 }
53 67
54 @Override 68 @Override
  69 + public List<WidgetTypeInfo> findWidgetTypesInfosByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias) {
  70 + return DaoUtil.convertDataList(widgetTypeRepository.findWidgetTypesInfosByTenantIdAndBundleAlias(tenantId, bundleAlias));
  71 + }
  72 +
  73 + @Override
55 public WidgetType findByTenantIdBundleAliasAndAlias(UUID tenantId, String bundleAlias, String alias) { 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,18 +15,35 @@
15 */ 15 */
16 package org.thingsboard.server.dao.sql.widget; 16 package org.thingsboard.server.dao.sql.widget;
17 17
  18 +import org.springframework.data.jpa.repository.Query;
18 import org.springframework.data.repository.CrudRepository; 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 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity; 22 import org.thingsboard.server.dao.model.sql.WidgetTypeEntity;
  23 +import org.thingsboard.server.dao.model.sql.WidgetTypeInfoEntity;
20 24
21 import java.util.List; 25 import java.util.List;
22 import java.util.UUID; 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,6 +17,8 @@ package org.thingsboard.server.dao.widget;
17 17
18 import org.thingsboard.server.common.data.id.TenantId; 18 import org.thingsboard.server.common.data.id.TenantId;
19 import org.thingsboard.server.common.data.widget.WidgetType; 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 import org.thingsboard.server.dao.Dao; 22 import org.thingsboard.server.dao.Dao;
21 23
22 import java.util.List; 24 import java.util.List;
@@ -25,15 +27,24 @@ import java.util.UUID; @@ -25,15 +27,24 @@ import java.util.UUID;
25 /** 27 /**
26 * The Interface WidgetTypeDao. 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 * Save or update widget type object 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 * @return saved widget type object 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 * Find widget types by tenantId and bundleAlias. 50 * Find widget types by tenantId and bundleAlias.
@@ -45,6 +56,24 @@ public interface WidgetTypeDao extends Dao<WidgetType> { @@ -45,6 +56,24 @@ public interface WidgetTypeDao extends Dao<WidgetType> {
45 List<WidgetType> findWidgetTypesByTenantIdAndBundleAlias(UUID tenantId, String bundleAlias); 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 * Find widget type by tenantId, bundleAlias and alias. 77 * Find widget type by tenantId, bundleAlias and alias.
49 * 78 *
50 * @param tenantId the tenantId 79 * @param tenantId the tenantId
@@ -23,6 +23,8 @@ import org.thingsboard.server.common.data.Tenant; @@ -23,6 +23,8 @@ import org.thingsboard.server.common.data.Tenant;
23 import org.thingsboard.server.common.data.id.TenantId; 23 import org.thingsboard.server.common.data.id.TenantId;
24 import org.thingsboard.server.common.data.id.WidgetTypeId; 24 import org.thingsboard.server.common.data.id.WidgetTypeId;
25 import org.thingsboard.server.common.data.widget.WidgetType; 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 import org.thingsboard.server.common.data.widget.WidgetsBundle; 28 import org.thingsboard.server.common.data.widget.WidgetsBundle;
27 import org.thingsboard.server.dao.exception.DataValidationException; 29 import org.thingsboard.server.dao.exception.DataValidationException;
28 import org.thingsboard.server.dao.model.ModelConstants; 30 import org.thingsboard.server.dao.model.ModelConstants;
@@ -51,14 +53,21 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @@ -51,14 +53,21 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
51 public WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId) { 53 public WidgetType findWidgetTypeById(TenantId tenantId, WidgetTypeId widgetTypeId) {
52 log.trace("Executing findWidgetTypeById [{}]", widgetTypeId); 54 log.trace("Executing findWidgetTypeById [{}]", widgetTypeId);
53 Validator.validateId(widgetTypeId, "Incorrect widgetTypeId " + widgetTypeId); 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 return widgetTypeDao.findById(tenantId, widgetTypeId.getId()); 63 return widgetTypeDao.findById(tenantId, widgetTypeId.getId());
55 } 64 }
56 65
57 @Override 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 @Override 73 @Override
@@ -77,6 +86,22 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @@ -77,6 +86,22 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
77 } 86 }
78 87
79 @Override 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 public WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias) { 105 public WidgetType findWidgetTypeByTenantIdBundleAliasAndAlias(TenantId tenantId, String bundleAlias, String alias) {
81 log.trace("Executing findWidgetTypeByTenantIdBundleAliasAndAlias, tenantId [{}], bundleAlias [{}], alias [{}]", tenantId, bundleAlias, alias); 106 log.trace("Executing findWidgetTypeByTenantIdBundleAliasAndAlias, tenantId [{}], bundleAlias [{}], alias [{}]", tenantId, bundleAlias, alias);
82 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); 107 Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId);
@@ -96,24 +121,24 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @@ -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 @Override 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 throw new DataValidationException("Widgets type name should be specified!"); 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 throw new DataValidationException("Widgets type bundle alias should be specified!"); 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 throw new DataValidationException("Widgets type descriptor can't be empty!"); 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 if (tenant == null) { 142 if (tenant == null) {
118 throw new DataValidationException("Widget type is referencing to non-existent tenant!"); 143 throw new DataValidationException("Widget type is referencing to non-existent tenant!");
119 } 144 }
@@ -121,37 +146,37 @@ public class WidgetTypeServiceImpl implements WidgetTypeService { @@ -121,37 +146,37 @@ public class WidgetTypeServiceImpl implements WidgetTypeService {
121 } 146 }
122 147
123 @Override 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 if (widgetsBundle == null) { 151 if (widgetsBundle == null) {
127 throw new DataValidationException("Widget type is referencing to non-existent widgets bundle!"); 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 if (alias == null || alias.trim().isEmpty()) { 155 if (alias == null || alias.trim().isEmpty()) {
131 - alias = widgetType.getName().toLowerCase().replaceAll("\\W+", "_"); 156 + alias = widgetTypeDetails.getName().toLowerCase().replaceAll("\\W+", "_");
132 } 157 }
133 String originalAlias = alias; 158 String originalAlias = alias;
134 int c = 1; 159 int c = 1;
135 WidgetType withSameAlias; 160 WidgetType withSameAlias;
136 do { 161 do {
137 - withSameAlias = widgetTypeDao.findByTenantIdBundleAliasAndAlias(widgetType.getTenantId().getId(), widgetType.getBundleAlias(), alias); 162 + withSameAlias = widgetTypeDao.findByTenantIdBundleAliasAndAlias(widgetTypeDetails.getTenantId().getId(), widgetTypeDetails.getBundleAlias(), alias);
138 if (withSameAlias != null) { 163 if (withSameAlias != null) {
139 alias = originalAlias + (++c); 164 alias = originalAlias + (++c);
140 } 165 }
141 } while (withSameAlias != null); 166 } while (withSameAlias != null);
142 - widgetType.setAlias(alias); 167 + widgetTypeDetails.setAlias(alias);
143 } 168 }
144 169
145 @Override 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 throw new DataValidationException("Can't move existing widget type to different tenant!"); 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 throw new DataValidationException("Update of widget type bundle alias is prohibited!"); 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 throw new DataValidationException("Update of widget type alias is prohibited!"); 180 throw new DataValidationException("Update of widget type alias is prohibited!");
156 } 181 }
157 } 182 }
@@ -25,6 +25,7 @@ import org.junit.Test; @@ -25,6 +25,7 @@ import org.junit.Test;
25 import org.thingsboard.server.common.data.Tenant; 25 import org.thingsboard.server.common.data.Tenant;
26 import org.thingsboard.server.common.data.id.TenantId; 26 import org.thingsboard.server.common.data.id.TenantId;
27 import org.thingsboard.server.common.data.widget.WidgetType; 27 import org.thingsboard.server.common.data.widget.WidgetType;
  28 +import org.thingsboard.server.common.data.widget.WidgetTypeDetails;
28 import org.thingsboard.server.common.data.widget.WidgetsBundle; 29 import org.thingsboard.server.common.data.widget.WidgetsBundle;
29 import org.thingsboard.server.dao.exception.DataValidationException; 30 import org.thingsboard.server.dao.exception.DataValidationException;
30 import org.thingsboard.server.dao.model.ModelConstants; 31 import org.thingsboard.server.dao.model.ModelConstants;
@@ -62,12 +63,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -62,12 +63,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
62 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 63 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
63 64
64 65
65 - WidgetType widgetType = new WidgetType(); 66 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
66 widgetType.setTenantId(tenantId); 67 widgetType.setTenantId(tenantId);
67 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 68 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
68 widgetType.setName("Widget Type"); 69 widgetType.setName("Widget Type");
69 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 Assert.assertNotNull(savedWidgetType); 73 Assert.assertNotNull(savedWidgetType);
73 Assert.assertNotNull(savedWidgetType.getId()); 74 Assert.assertNotNull(savedWidgetType.getId());
@@ -94,7 +95,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -94,7 +95,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
94 widgetsBundle.setTitle("Widgets bundle"); 95 widgetsBundle.setTitle("Widgets bundle");
95 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 96 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
96 97
97 - WidgetType widgetType = new WidgetType(); 98 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
98 widgetType.setTenantId(tenantId); 99 widgetType.setTenantId(tenantId);
99 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 100 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
100 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 101 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
@@ -107,7 +108,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -107,7 +108,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
107 108
108 @Test(expected = DataValidationException.class) 109 @Test(expected = DataValidationException.class)
109 public void testSaveWidgetTypeWithEmptyBundleAlias() throws IOException { 110 public void testSaveWidgetTypeWithEmptyBundleAlias() throws IOException {
110 - WidgetType widgetType = new WidgetType(); 111 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
111 widgetType.setTenantId(tenantId); 112 widgetType.setTenantId(tenantId);
112 widgetType.setName("Widget Type"); 113 widgetType.setName("Widget Type");
113 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 114 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
@@ -121,7 +122,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -121,7 +122,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
121 widgetsBundle.setTitle("Widgets bundle"); 122 widgetsBundle.setTitle("Widgets bundle");
122 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 123 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
123 124
124 - WidgetType widgetType = new WidgetType(); 125 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
125 widgetType.setTenantId(tenantId); 126 widgetType.setTenantId(tenantId);
126 widgetType.setName("Widget Type"); 127 widgetType.setName("Widget Type");
127 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 128 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
@@ -140,7 +141,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -140,7 +141,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
140 widgetsBundle.setTitle("Widgets bundle"); 141 widgetsBundle.setTitle("Widgets bundle");
141 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 142 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
142 143
143 - WidgetType widgetType = new WidgetType(); 144 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
144 widgetType.setTenantId(new TenantId(Uuids.timeBased())); 145 widgetType.setTenantId(new TenantId(Uuids.timeBased()));
145 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 146 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
146 widgetType.setName("Widget Type"); 147 widgetType.setName("Widget Type");
@@ -154,7 +155,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -154,7 +155,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
154 155
155 @Test(expected = DataValidationException.class) 156 @Test(expected = DataValidationException.class)
156 public void testSaveWidgetTypeWithInvalidBundleAlias() throws IOException { 157 public void testSaveWidgetTypeWithInvalidBundleAlias() throws IOException {
157 - WidgetType widgetType = new WidgetType(); 158 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
158 widgetType.setTenantId(tenantId); 159 widgetType.setTenantId(tenantId);
159 widgetType.setBundleAlias("some_alias"); 160 widgetType.setBundleAlias("some_alias");
160 widgetType.setName("Widget Type"); 161 widgetType.setName("Widget Type");
@@ -169,12 +170,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -169,12 +170,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
169 widgetsBundle.setTitle("Widgets bundle"); 170 widgetsBundle.setTitle("Widgets bundle");
170 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 171 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
171 172
172 - WidgetType widgetType = new WidgetType(); 173 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
173 widgetType.setTenantId(tenantId); 174 widgetType.setTenantId(tenantId);
174 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 175 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
175 widgetType.setName("Widget Type"); 176 widgetType.setName("Widget Type");
176 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 177 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
177 - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType); 178 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
178 savedWidgetType.setTenantId(new TenantId(ModelConstants.NULL_UUID)); 179 savedWidgetType.setTenantId(new TenantId(ModelConstants.NULL_UUID));
179 try { 180 try {
180 widgetTypeService.saveWidgetType(savedWidgetType); 181 widgetTypeService.saveWidgetType(savedWidgetType);
@@ -190,12 +191,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -190,12 +191,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
190 widgetsBundle.setTitle("Widgets bundle"); 191 widgetsBundle.setTitle("Widgets bundle");
191 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 192 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
192 193
193 - WidgetType widgetType = new WidgetType(); 194 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
194 widgetType.setTenantId(tenantId); 195 widgetType.setTenantId(tenantId);
195 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 196 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
196 widgetType.setName("Widget Type"); 197 widgetType.setName("Widget Type");
197 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 198 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
198 - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType); 199 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
199 savedWidgetType.setBundleAlias("some_alias"); 200 savedWidgetType.setBundleAlias("some_alias");
200 try { 201 try {
201 widgetTypeService.saveWidgetType(savedWidgetType); 202 widgetTypeService.saveWidgetType(savedWidgetType);
@@ -211,12 +212,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -211,12 +212,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
211 widgetsBundle.setTitle("Widgets bundle"); 212 widgetsBundle.setTitle("Widgets bundle");
212 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 213 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
213 214
214 - WidgetType widgetType = new WidgetType(); 215 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
215 widgetType.setTenantId(tenantId); 216 widgetType.setTenantId(tenantId);
216 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 217 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
217 widgetType.setName("Widget Type"); 218 widgetType.setName("Widget Type");
218 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 219 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class));
219 - WidgetType savedWidgetType = widgetTypeService.saveWidgetType(widgetType); 220 + WidgetTypeDetails savedWidgetType = widgetTypeService.saveWidgetType(widgetType);
220 savedWidgetType.setAlias("some_alias"); 221 savedWidgetType.setAlias("some_alias");
221 try { 222 try {
222 widgetTypeService.saveWidgetType(savedWidgetType); 223 widgetTypeService.saveWidgetType(savedWidgetType);
@@ -232,13 +233,13 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -232,13 +233,13 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
232 widgetsBundle.setTitle("Widgets bundle"); 233 widgetsBundle.setTitle("Widgets bundle");
233 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 234 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
234 235
235 - WidgetType widgetType = new WidgetType(); 236 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
236 widgetType.setTenantId(tenantId); 237 widgetType.setTenantId(tenantId);
237 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 238 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
238 widgetType.setName("Widget Type"); 239 widgetType.setName("Widget Type");
239 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 Assert.assertNotNull(foundWidgetType); 243 Assert.assertNotNull(foundWidgetType);
243 Assert.assertEquals(savedWidgetType, foundWidgetType); 244 Assert.assertEquals(savedWidgetType, foundWidgetType);
244 245
@@ -252,12 +253,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -252,12 +253,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
252 widgetsBundle.setTitle("Widgets bundle"); 253 widgetsBundle.setTitle("Widgets bundle");
253 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 254 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
254 255
255 - WidgetType widgetType = new WidgetType(); 256 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
256 widgetType.setTenantId(tenantId); 257 widgetType.setTenantId(tenantId);
257 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 258 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
258 widgetType.setName("Widget Type"); 259 widgetType.setName("Widget Type");
259 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 WidgetType foundWidgetType = widgetTypeService.findWidgetTypeByTenantIdBundleAliasAndAlias(tenantId, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias()); 262 WidgetType foundWidgetType = widgetTypeService.findWidgetTypeByTenantIdBundleAliasAndAlias(tenantId, savedWidgetsBundle.getAlias(), savedWidgetType.getAlias());
262 Assert.assertNotNull(foundWidgetType); 263 Assert.assertNotNull(foundWidgetType);
263 Assert.assertEquals(savedWidgetType, foundWidgetType); 264 Assert.assertEquals(savedWidgetType, foundWidgetType);
@@ -272,7 +273,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -272,7 +273,7 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
272 widgetsBundle.setTitle("Widgets bundle"); 273 widgetsBundle.setTitle("Widgets bundle");
273 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle); 274 WidgetsBundle savedWidgetsBundle = widgetsBundleService.saveWidgetsBundle(widgetsBundle);
274 275
275 - WidgetType widgetType = new WidgetType(); 276 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
276 widgetType.setTenantId(tenantId); 277 widgetType.setTenantId(tenantId);
277 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 278 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
278 widgetType.setName("Widget Type"); 279 widgetType.setName("Widget Type");
@@ -296,12 +297,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest { @@ -296,12 +297,12 @@ public abstract class BaseWidgetTypeServiceTest extends AbstractServiceTest {
296 297
297 List<WidgetType> widgetTypes = new ArrayList<>(); 298 List<WidgetType> widgetTypes = new ArrayList<>();
298 for (int i=0;i<121;i++) { 299 for (int i=0;i<121;i++) {
299 - WidgetType widgetType = new WidgetType(); 300 + WidgetTypeDetails widgetType = new WidgetTypeDetails();
300 widgetType.setTenantId(tenantId); 301 widgetType.setTenantId(tenantId);
301 widgetType.setBundleAlias(savedWidgetsBundle.getAlias()); 302 widgetType.setBundleAlias(savedWidgetsBundle.getAlias());
302 widgetType.setName("Widget Type " + i); 303 widgetType.setName("Widget Type " + i);
303 widgetType.setDescriptor(new ObjectMapper().readValue("{ \"someKey\": \"someValue\" }", JsonNode.class)); 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 List<WidgetType> loadedWidgetTypes = widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(tenantId, savedWidgetsBundle.getAlias()); 308 List<WidgetType> loadedWidgetTypes = widgetTypeService.findWidgetTypesByTenantIdAndBundleAlias(tenantId, savedWidgetsBundle.getAlias());
@@ -21,11 +21,23 @@ import { HttpClient } from '@angular/common/http'; @@ -21,11 +21,23 @@ import { HttpClient } from '@angular/common/http';
21 import { PageLink } from '@shared/models/page/page-link'; 21 import { PageLink } from '@shared/models/page/page-link';
22 import { PageData } from '@shared/models/page/page-data'; 22 import { PageData } from '@shared/models/page/page-data';
23 import { WidgetsBundle } from '@shared/models/widgets-bundle.model'; 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 import { UtilsService } from '@core/services/utils.service'; 32 import { UtilsService } from '@core/services/utils.service';
26 import { TranslateService } from '@ngx-translate/core'; 33 import { TranslateService } from '@ngx-translate/core';
27 import { ResourcesService } from '../services/resources.service'; 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 import { filter, map, mergeMap, tap } from 'rxjs/operators'; 41 import { filter, map, mergeMap, tap } from 'rxjs/operators';
30 import { WidgetTypeId } from '@shared/models/id/widget-type-id'; 42 import { WidgetTypeId } from '@shared/models/id/widget-type-id';
31 import { NULL_UUID } from '@shared/models/id/has-uuid'; 43 import { NULL_UUID } from '@shared/models/id/has-uuid';
@@ -117,6 +129,18 @@ export class WidgetService { @@ -117,6 +129,18 @@ export class WidgetService {
117 defaultHttpOptionsFromConfig(config)); 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 public loadBundleLibraryWidgets(bundleAlias: string, isSystem: boolean, 144 public loadBundleLibraryWidgets(bundleAlias: string, isSystem: boolean,
121 config?: RequestConfig): Observable<Array<Widget>> { 145 config?: RequestConfig): Observable<Array<Widget>> {
122 return this.getBundleWidgetTypes(bundleAlias, isSystem, config).pipe( 146 return this.getBundleWidgetTypes(bundleAlias, isSystem, config).pipe(
@@ -144,8 +168,6 @@ export class WidgetService { @@ -144,8 +168,6 @@ export class WidgetService {
144 typeAlias: widgetTypeInfo.alias, 168 typeAlias: widgetTypeInfo.alias,
145 type: widgetTypeInfo.type, 169 type: widgetTypeInfo.type,
146 title: widgetTypeInfo.widgetName, 170 title: widgetTypeInfo.widgetName,
147 - image: widgetTypeInfo.image,  
148 - description: widgetTypeInfo.description,  
149 sizeX, 171 sizeX,
150 sizeY, 172 sizeY,
151 row: top, 173 row: top,
@@ -178,22 +200,22 @@ export class WidgetService { @@ -178,22 +200,22 @@ export class WidgetService {
178 defaultHttpOptionsFromConfig(config)); 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 defaultHttpOptionsFromConfig(config)).pipe( 210 defaultHttpOptionsFromConfig(config)).pipe(
189 tap((savedWidgetType) => { 211 tap((savedWidgetType) => {
190 this.widgetTypeUpdatedSubject.next(savedWidgetType); 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 defaultHttpOptionsFromConfig(config)).pipe( 219 defaultHttpOptionsFromConfig(config)).pipe(
198 tap((savedWidgetType) => { 220 tap((savedWidgetType) => {
199 this.widgetTypeUpdatedSubject.next(savedWidgetType); 221 this.widgetTypeUpdatedSubject.next(savedWidgetType);
@@ -215,8 +237,8 @@ export class WidgetService { @@ -215,8 +237,8 @@ export class WidgetService {
215 } 237 }
216 238
217 public getWidgetTypeById(widgetTypeId: string, 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 defaultHttpOptionsFromConfig(config)); 242 defaultHttpOptionsFromConfig(config));
221 } 243 }
222 244
@@ -470,8 +470,6 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI @@ -470,8 +470,6 @@ export class AttributeTableComponent extends PageComponent implements AfterViewI
470 typeAlias: widgetInfo.alias, 470 typeAlias: widgetInfo.alias,
471 type: widgetInfo.type, 471 type: widgetInfo.type,
472 title: widgetInfo.widgetName, 472 title: widgetInfo.widgetName,
473 - image: widgetInfo.image,  
474 - description: widgetInfo.description,  
475 sizeX, 473 sizeX,
476 sizeY, 474 sizeY,
477 row: 0, 475 row: 0,
@@ -97,17 +97,16 @@ export class DashboardWidgetSelectComponent implements OnInit { @@ -97,17 +97,16 @@ export class DashboardWidgetSelectComponent implements OnInit {
97 if (this.widgetsBundle !== null) { 97 if (this.widgetsBundle !== null) {
98 const bundleAlias = this.widgetsBundle.alias; 98 const bundleAlias = this.widgetsBundle.alias;
99 const isSystem = this.widgetsBundle.tenantId.id === NULL_UUID; 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 map(widgets => widgets.sort((a, b) => b.createdTime - a.createdTime)), 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 const widget: WidgetInfo = { 104 const widget: WidgetInfo = {
106 isSystemType: isSystem, 105 isSystemType: isSystem,
107 bundleAlias, 106 bundleAlias,
108 typeAlias: widgetTypeInfo.alias, 107 typeAlias: widgetTypeInfo.alias,
109 - type: widgetTypeInfo.type,  
110 - title: widgetTypeInfo.widgetName, 108 + type: widgetTypeInfo.widgetType,
  109 + title: widgetTypeInfo.name,
111 image: widgetTypeInfo.image, 110 image: widgetTypeInfo.image,
112 description: widgetTypeInfo.description 111 description: widgetTypeInfo.description
113 }; 112 };
@@ -14,7 +14,7 @@ @@ -14,7 +14,7 @@
14 /// limitations under the License. 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 import { DashboardLayoutId } from '@shared/models/dashboard.models'; 18 import { DashboardLayoutId } from '@shared/models/dashboard.models';
19 import { WidgetsBundle } from '@shared/models/widgets-bundle.model'; 19 import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
20 20
@@ -25,7 +25,7 @@ export interface ImportWidgetResult { @@ -25,7 +25,7 @@ export interface ImportWidgetResult {
25 25
26 export interface WidgetsBundleItem { 26 export interface WidgetsBundleItem {
27 widgetsBundle: WidgetsBundle; 27 widgetsBundle: WidgetsBundle;
28 - widgetTypes: WidgetType[]; 28 + widgetTypes: WidgetTypeDetails[];
29 } 29 }
30 30
31 export interface CsvToJsonConfig { 31 export interface CsvToJsonConfig {
@@ -38,7 +38,7 @@ import { forkJoin, Observable, of } from 'rxjs'; @@ -38,7 +38,7 @@ import { forkJoin, Observable, of } from 'rxjs';
38 import { catchError, map, mergeMap, tap } from 'rxjs/operators'; 38 import { catchError, map, mergeMap, tap } from 'rxjs/operators';
39 import { DashboardUtilsService } from '@core/services/dashboard-utils.service'; 39 import { DashboardUtilsService } from '@core/services/dashboard-utils.service';
40 import { EntityService } from '@core/http/entity.service'; 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 import { 42 import {
43 EntityAliasesDialogComponent, 43 EntityAliasesDialogComponent,
44 EntityAliasesDialogData 44 EntityAliasesDialogData
@@ -234,13 +234,13 @@ export class ImportExportService { @@ -234,13 +234,13 @@ export class ImportExportService {
234 234
235 public exportWidgetType(widgetTypeId: string) { 235 public exportWidgetType(widgetTypeId: string) {
236 this.widgetService.getWidgetTypeById(widgetTypeId).subscribe( 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 name = name.toLowerCase().replace(/\W/g, '_'); 242 name = name.toLowerCase().replace(/\W/g, '_');
243 - this.exportToPc(this.prepareExport(widgetType), name); 243 + this.exportToPc(this.prepareExport(widgetTypeDetails), name);
244 }, 244 },
245 (e) => { 245 (e) => {
246 this.handleExportError(e, 'widget-type.export-failed-error'); 246 this.handleExportError(e, 'widget-type.export-failed-error');
@@ -250,15 +250,15 @@ export class ImportExportService { @@ -250,15 +250,15 @@ export class ImportExportService {
250 250
251 public importWidgetType(bundleAlias: string): Observable<WidgetType> { 251 public importWidgetType(bundleAlias: string): Observable<WidgetType> {
252 return this.openImportDialog('widget-type.import', 'widget-type.widget-type-file').pipe( 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 this.store.dispatch(new ActionNotificationShow( 255 this.store.dispatch(new ActionNotificationShow(
256 {message: this.translate.instant('widget-type.invalid-widget-type-file-error'), 256 {message: this.translate.instant('widget-type.invalid-widget-type-file-error'),
257 type: 'error'})); 257 type: 'error'}));
258 throw new Error('Invalid widget type file'); 258 throw new Error('Invalid widget type file');
259 } else { 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 catchError((err) => { 264 catchError((err) => {
@@ -272,18 +272,18 @@ export class ImportExportService { @@ -272,18 +272,18 @@ export class ImportExportService {
272 (widgetsBundle) => { 272 (widgetsBundle) => {
273 const bundleAlias = widgetsBundle.alias; 273 const bundleAlias = widgetsBundle.alias;
274 const isSystem = widgetsBundle.tenantId.id === NULL_UUID; 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 const widgetsBundleItem: WidgetsBundleItem = { 278 const widgetsBundleItem: WidgetsBundleItem = {
279 widgetsBundle: this.prepareExport(widgetsBundle), 279 widgetsBundle: this.prepareExport(widgetsBundle),
280 widgetTypes: [] 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 let name = widgetsBundle.title; 288 let name = widgetsBundle.title;
289 name = name.toLowerCase().replace(/\W/g, '_'); 289 name = name.toLowerCase().replace(/\W/g, '_');
@@ -313,12 +313,12 @@ export class ImportExportService { @@ -313,12 +313,12 @@ export class ImportExportService {
313 return this.widgetService.saveWidgetsBundle(widgetsBundle).pipe( 313 return this.widgetService.saveWidgetsBundle(widgetsBundle).pipe(
314 mergeMap((savedWidgetsBundle) => { 314 mergeMap((savedWidgetsBundle) => {
315 const bundleAlias = savedWidgetsBundle.alias; 315 const bundleAlias = savedWidgetsBundle.alias;
316 - const widgetTypes = widgetsBundleItem.widgetTypes;  
317 - if (widgetTypes.length) { 316 + const widgetTypesDetails = widgetsBundleItem.widgetTypes;
  317 + if (widgetTypesDetails.length) {
318 const saveWidgetTypesObservables: Array<Observable<WidgetType>> = []; 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 return forkJoin(saveWidgetTypesObservables).pipe( 323 return forkJoin(saveWidgetTypesObservables).pipe(
324 map(() => savedWidgetsBundle) 324 map(() => savedWidgetsBundle)
@@ -508,9 +508,9 @@ export class ImportExportService { @@ -508,9 +508,9 @@ export class ImportExportService {
508 return true; 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 return false; 514 return false;
515 } 515 }
516 return true; 516 return true;
@@ -527,9 +527,9 @@ export class ImportExportService { @@ -527,9 +527,9 @@ export class ImportExportService {
527 if (isUndefined(widgetsBundle.title)) { 527 if (isUndefined(widgetsBundle.title)) {
528 return false; 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 return false; 533 return false;
534 } 534 }
535 } 535 }
@@ -104,8 +104,6 @@ export class WidgetComponentService { @@ -104,8 +104,6 @@ export class WidgetComponentService {
104 controllerScript: this.utils.editWidgetInfo.controllerScript, 104 controllerScript: this.utils.editWidgetInfo.controllerScript,
105 settingsSchema: this.utils.editWidgetInfo.settingsSchema, 105 settingsSchema: this.utils.editWidgetInfo.settingsSchema,
106 dataKeySettingsSchema: this.utils.editWidgetInfo.dataKeySettingsSchema, 106 dataKeySettingsSchema: this.utils.editWidgetInfo.dataKeySettingsSchema,
107 - image: this.utils.editWidgetInfo.image,  
108 - description: this.utils.editWidgetInfo.description,  
109 defaultConfig: this.utils.editWidgetInfo.defaultConfig 107 defaultConfig: this.utils.editWidgetInfo.defaultConfig
110 }, new WidgetTypeId('1'), new TenantId( NULL_UUID ), 'customWidgetBundle', undefined 108 }, new WidgetTypeId('1'), new TenantId( NULL_UUID ), 'customWidgetBundle', undefined
111 ); 109 );
@@ -27,7 +27,7 @@ import { @@ -27,7 +27,7 @@ import {
27 WidgetControllerDescriptor, 27 WidgetControllerDescriptor,
28 WidgetType, 28 WidgetType,
29 widgetType, 29 widgetType,
30 - WidgetTypeDescriptor, 30 + WidgetTypeDescriptor, WidgetTypeDetails,
31 WidgetTypeParameters 31 WidgetTypeParameters
32 } from '@shared/models/widget.models'; 32 } from '@shared/models/widget.models';
33 import { Timewindow, WidgetTimewindow } from '@shared/models/time/time.models'; 33 import { Timewindow, WidgetTimewindow } from '@shared/models/time/time.models';
@@ -347,8 +347,8 @@ export interface WidgetInfo extends WidgetTypeDescriptor, WidgetControllerDescri @@ -347,8 +347,8 @@ export interface WidgetInfo extends WidgetTypeDescriptor, WidgetControllerDescri
347 alias: string; 347 alias: string;
348 typeSettingsSchema?: string | any; 348 typeSettingsSchema?: string | any;
349 typeDataKeySettingsSchema?: string | any; 349 typeDataKeySettingsSchema?: string | any;
350 - image: string;  
351 - description: string; 350 + image?: string;
  351 + description?: string;
352 componentFactory?: ComponentFactory<IDynamicWidgetComponent>; 352 componentFactory?: ComponentFactory<IDynamicWidgetComponent>;
353 } 353 }
354 354
@@ -427,11 +427,16 @@ export interface WidgetTypeInstance { @@ -427,11 +427,16 @@ export interface WidgetTypeInstance {
427 onDestroy?: () => void; 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 export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo { 437 export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo {
431 return { 438 return {
432 widgetName: widgetTypeEntity.name, 439 widgetName: widgetTypeEntity.name,
433 - image: widgetTypeEntity.image,  
434 - description: widgetTypeEntity.description,  
435 alias: widgetTypeEntity.alias, 440 alias: widgetTypeEntity.alias,
436 type: widgetTypeEntity.descriptor.type, 441 type: widgetTypeEntity.descriptor.type,
437 sizeX: widgetTypeEntity.descriptor.sizeX, 442 sizeX: widgetTypeEntity.descriptor.sizeX,
@@ -446,6 +451,16 @@ export function toWidgetInfo(widgetTypeEntity: WidgetType): WidgetInfo { @@ -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 export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: TenantId, 464 export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: TenantId,
450 bundleAlias: string, createdTime: number): WidgetType { 465 bundleAlias: string, createdTime: number): WidgetType {
451 const descriptor: WidgetTypeDescriptor = { 466 const descriptor: WidgetTypeDescriptor = {
@@ -467,8 +482,6 @@ export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId: @@ -467,8 +482,6 @@ export function toWidgetType(widgetInfo: WidgetInfo, id: WidgetTypeId, tenantId:
467 bundleAlias, 482 bundleAlias,
468 alias: widgetInfo.alias, 483 alias: widgetInfo.alias,
469 name: widgetInfo.widgetName, 484 name: widgetInfo.widgetName,
470 - image: widgetInfo.image,  
471 - description: widgetInfo.description,  
472 descriptor 485 descriptor
473 }; 486 };
474 } 487 }
@@ -20,8 +20,15 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model'; @@ -20,8 +20,15 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
20 import { Store } from '@ngrx/store'; 20 import { Store } from '@ngrx/store';
21 import { AppState } from '@core/core.state'; 21 import { AppState } from '@core/core.state';
22 import { WidgetService } from '@core/http/widget.service'; 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 import { ActivatedRoute, Router } from '@angular/router'; 32 import { ActivatedRoute, Router } from '@angular/router';
26 import { deepClone } from '@core/utils'; 33 import { deepClone } from '@core/utils';
27 import { HasDirtyFlag } from '@core/guards/confirm-on-exit.guard'; 34 import { HasDirtyFlag } from '@core/guards/confirm-on-exit.guard';
@@ -108,7 +115,7 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe @@ -108,7 +115,7 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
108 isReadOnly: boolean; 115 isReadOnly: boolean;
109 116
110 widgetsBundle: WidgetsBundle; 117 widgetsBundle: WidgetsBundle;
111 - widgetType: WidgetType; 118 + widgetTypeDetails: WidgetTypeDetails;
112 widget: WidgetInfo; 119 widget: WidgetInfo;
113 origWidget: WidgetInfo; 120 origWidget: WidgetInfo;
114 121
@@ -175,14 +182,14 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe @@ -175,14 +182,14 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
175 } else { 182 } else {
176 this.isReadOnly = this.authUser.authority !== Authority.SYS_ADMIN; 183 this.isReadOnly = this.authUser.authority !== Authority.SYS_ADMIN;
177 } 184 }
178 - this.widgetType = data.widgetEditorData.widgetType; 185 + this.widgetTypeDetails = data.widgetEditorData.widgetTypeDetails;
179 this.widget = data.widgetEditorData.widget; 186 this.widget = data.widgetEditorData.widget;
180 - if (this.widgetType) { 187 + if (this.widgetTypeDetails) {
181 const config = JSON.parse(this.widget.defaultConfig); 188 const config = JSON.parse(this.widget.defaultConfig);
182 this.widget.defaultConfig = JSON.stringify(config); 189 this.widget.defaultConfig = JSON.stringify(config);
183 } 190 }
184 this.origWidget = deepClone(this.widget); 191 this.origWidget = deepClone(this.widget);
185 - if (!this.widgetType) { 192 + if (!this.widgetTypeDetails) {
186 this.isDirty = true; 193 this.isDirty = true;
187 } 194 }
188 } 195 }
@@ -515,11 +522,11 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe @@ -515,11 +522,11 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
515 } 522 }
516 523
517 private commitSaveWidget() { 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 this.saveWidgetPending = false; 530 this.saveWidgetPending = false;
524 this.store.dispatch(new ActionNotificationShow( 531 this.store.dispatch(new ActionNotificationShow(
525 {message: this.translate.instant('widget.widget-saved'), type: 'success', duration: 500})); 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,9 +551,9 @@ export class WidgetEditorComponent extends PageComponent implements OnInit, OnDe
544 config.title = this.widget.widgetName; 551 config.title = this.widget.widgetName;
545 this.widget.defaultConfig = JSON.stringify(config); 552 this.widget.defaultConfig = JSON.stringify(config);
546 this.isDirty = false; 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,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 const config = JSON.parse(this.widget.defaultConfig); 568 const config = JSON.parse(this.widget.defaultConfig);
562 this.widget.defaultConfig = JSON.stringify(config); 569 this.widget.defaultConfig = JSON.stringify(config);
563 this.origWidget = deepClone(this.widget); 570 this.origWidget = deepClone(this.widget);
@@ -27,14 +27,14 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model'; @@ -27,14 +27,14 @@ import { WidgetsBundle } from '@shared/models/widgets-bundle.model';
27 import { WidgetService } from '@core/http/widget.service'; 27 import { WidgetService } from '@core/http/widget.service';
28 import { WidgetEditorComponent } from '@home/pages/widget/widget-editor.component'; 28 import { WidgetEditorComponent } from '@home/pages/widget/widget-editor.component';
29 import { map } from 'rxjs/operators'; 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 import { ConfirmOnExitGuard } from '@core/guards/confirm-on-exit.guard'; 32 import { ConfirmOnExitGuard } from '@core/guards/confirm-on-exit.guard';
33 import { WidgetsData } from '@home/models/dashboard-component.models'; 33 import { WidgetsData } from '@home/models/dashboard-component.models';
34 import { NULL_UUID } from '@shared/models/id/has-uuid'; 34 import { NULL_UUID } from '@shared/models/id/has-uuid';
35 35
36 export interface WidgetEditorData { 36 export interface WidgetEditorData {
37 - widgetType: WidgetType; 37 + widgetTypeDetails: WidgetTypeDetails;
38 widget: WidgetInfo; 38 widget: WidgetInfo;
39 } 39 }
40 40
@@ -83,8 +83,8 @@ export class WidgetEditorDataResolver implements Resolve<WidgetEditorData> { @@ -83,8 +83,8 @@ export class WidgetEditorDataResolver implements Resolve<WidgetEditorData> {
83 return this.widgetsService.getWidgetTypeById(widgetTypeId).pipe( 83 return this.widgetsService.getWidgetTypeById(widgetTypeId).pipe(
84 map((result) => { 84 map((result) => {
85 return { 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,7 +106,7 @@ export class WidgetEditorAddDataResolver implements Resolve<WidgetEditorData> {
106 map((widget) => { 106 map((widget) => {
107 widget.widgetName = null; 107 widget.widgetName = null;
108 return { 108 return {
109 - widgetType: null, 109 + widgetTypeDetails: null,
110 widget 110 widget
111 }; 111 };
112 }) 112 })
@@ -165,14 +165,26 @@ export interface WidgetControllerDescriptor { @@ -165,14 +165,26 @@ export interface WidgetControllerDescriptor {
165 actionSources?: {[actionSourceId: string]: WidgetActionSource}; 165 actionSources?: {[actionSourceId: string]: WidgetActionSource};
166 } 166 }
167 167
168 -export interface WidgetType extends BaseData<WidgetTypeId> { 168 +export interface BaseWidgetType extends BaseData<WidgetTypeId> {
169 tenantId: TenantId; 169 tenantId: TenantId;
170 bundleAlias: string; 170 bundleAlias: string;
171 alias: string; 171 alias: string;
172 name: string; 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 image: string; 186 image: string;
174 description: string; 187 description: string;
175 - descriptor: WidgetTypeDescriptor;  
176 } 188 }
177 189
178 export enum LegendDirection { 190 export enum LegendDirection {
@@ -417,8 +429,8 @@ export interface WidgetInfo { @@ -417,8 +429,8 @@ export interface WidgetInfo {
417 typeAlias: string; 429 typeAlias: string;
418 type: widgetType; 430 type: widgetType;
419 title: string; 431 title: string;
420 - image: string;  
421 - description: string; 432 + image?: string;
  433 + description?: string;
422 } 434 }
423 435
424 export interface GroupInfo { 436 export interface GroupInfo {