Commit 0021f007f1de05bba8e202ebc7c3c3ed0ee4aaa7
1 parent
7645e6f2
Implement multiple customer assigned dashboards UI. Add Current Customer entity …
…type for dashboard aliases.
Showing
39 changed files
with
848 additions
and
497 deletions
@@ -434,7 +434,6 @@ public abstract class BaseController { | @@ -434,7 +434,6 @@ public abstract class BaseController { | ||
434 | try { | 434 | try { |
435 | validateId(dashboardId, "Incorrect dashboardId " + dashboardId); | 435 | validateId(dashboardId, "Incorrect dashboardId " + dashboardId); |
436 | DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(dashboardId); | 436 | DashboardInfo dashboardInfo = dashboardService.findDashboardInfoById(dashboardId); |
437 | - SecurityUser authUser = getCurrentUser(); | ||
438 | checkDashboard(dashboardInfo); | 437 | checkDashboard(dashboardInfo); |
439 | return dashboardInfo; | 438 | return dashboardInfo; |
440 | } catch (Exception e) { | 439 | } catch (Exception e) { |
@@ -447,7 +446,7 @@ public abstract class BaseController { | @@ -447,7 +446,7 @@ public abstract class BaseController { | ||
447 | checkTenantId(dashboard.getTenantId()); | 446 | checkTenantId(dashboard.getTenantId()); |
448 | SecurityUser authUser = getCurrentUser(); | 447 | SecurityUser authUser = getCurrentUser(); |
449 | if (authUser.getAuthority() == Authority.CUSTOMER_USER) { | 448 | if (authUser.getAuthority() == Authority.CUSTOMER_USER) { |
450 | - if (dashboard.getAssignedCustomers() == null || !dashboard.getAssignedCustomers().containsKey(authUser.getCustomerId().toString())) { | 449 | + if (!dashboard.isAssignedToCustomer(authUser.getCustomerId())) { |
451 | throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, | 450 | throw new ThingsboardException(YOU_DON_T_HAVE_PERMISSION_TO_PERFORM_THIS_OPERATION, |
452 | ThingsboardErrorCode.PERMISSION_DENIED); | 451 | ThingsboardErrorCode.PERMISSION_DENIED); |
453 | } | 452 | } |
@@ -18,10 +18,7 @@ package org.thingsboard.server.controller; | @@ -18,10 +18,7 @@ package org.thingsboard.server.controller; | ||
18 | import org.springframework.http.HttpStatus; | 18 | import org.springframework.http.HttpStatus; |
19 | import org.springframework.security.access.prepost.PreAuthorize; | 19 | import org.springframework.security.access.prepost.PreAuthorize; |
20 | import org.springframework.web.bind.annotation.*; | 20 | import org.springframework.web.bind.annotation.*; |
21 | -import org.thingsboard.server.common.data.Customer; | ||
22 | -import org.thingsboard.server.common.data.Dashboard; | ||
23 | -import org.thingsboard.server.common.data.DashboardInfo; | ||
24 | -import org.thingsboard.server.common.data.EntityType; | 21 | +import org.thingsboard.server.common.data.*; |
25 | import org.thingsboard.server.common.data.audit.ActionType; | 22 | import org.thingsboard.server.common.data.audit.ActionType; |
26 | import org.thingsboard.server.common.data.id.CustomerId; | 23 | import org.thingsboard.server.common.data.id.CustomerId; |
27 | import org.thingsboard.server.common.data.id.DashboardId; | 24 | import org.thingsboard.server.common.data.id.DashboardId; |
@@ -34,6 +31,9 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; | @@ -34,6 +31,9 @@ import org.thingsboard.server.dao.exception.IncorrectParameterException; | ||
34 | import org.thingsboard.server.dao.model.ModelConstants; | 31 | import org.thingsboard.server.dao.model.ModelConstants; |
35 | import org.thingsboard.server.exception.ThingsboardException; | 32 | import org.thingsboard.server.exception.ThingsboardException; |
36 | 33 | ||
34 | +import java.util.HashSet; | ||
35 | +import java.util.Set; | ||
36 | + | ||
37 | @RestController | 37 | @RestController |
38 | @RequestMapping("/api") | 38 | @RequestMapping("/api") |
39 | public class DashboardController extends BaseController { | 39 | public class DashboardController extends BaseController { |
@@ -182,6 +182,158 @@ public class DashboardController extends BaseController { | @@ -182,6 +182,158 @@ public class DashboardController extends BaseController { | ||
182 | } | 182 | } |
183 | 183 | ||
184 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") | 184 | @PreAuthorize("hasAuthority('TENANT_ADMIN')") |
185 | + @RequestMapping(value = "/dashboard/{dashboardId}/customers", method = RequestMethod.POST) | ||
186 | + @ResponseBody | ||
187 | + public Dashboard updateDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId, | ||
188 | + @RequestBody String[] strCustomerIds) throws ThingsboardException { | ||
189 | + checkParameter(DASHBOARD_ID, strDashboardId); | ||
190 | + try { | ||
191 | + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); | ||
192 | + Dashboard dashboard = checkDashboardId(dashboardId); | ||
193 | + | ||
194 | + Set<CustomerId> customerIds = new HashSet<>(); | ||
195 | + if (strCustomerIds != null) { | ||
196 | + for (String strCustomerId : strCustomerIds) { | ||
197 | + customerIds.add(new CustomerId(toUUID(strCustomerId))); | ||
198 | + } | ||
199 | + } | ||
200 | + | ||
201 | + Set<CustomerId> addedCustomerIds = new HashSet<>(); | ||
202 | + Set<CustomerId> removedCustomerIds = new HashSet<>(); | ||
203 | + for (CustomerId customerId : customerIds) { | ||
204 | + if (!dashboard.isAssignedToCustomer(customerId)) { | ||
205 | + addedCustomerIds.add(customerId); | ||
206 | + } | ||
207 | + } | ||
208 | + | ||
209 | + Set<ShortCustomerInfo> assignedCustomers = dashboard.getAssignedCustomers(); | ||
210 | + if (assignedCustomers != null) { | ||
211 | + for (ShortCustomerInfo customerInfo : assignedCustomers) { | ||
212 | + if (!customerIds.contains(customerInfo.getCustomerId())) { | ||
213 | + removedCustomerIds.add(customerInfo.getCustomerId()); | ||
214 | + } | ||
215 | + } | ||
216 | + } | ||
217 | + | ||
218 | + if (addedCustomerIds.isEmpty() && removedCustomerIds.isEmpty()) { | ||
219 | + return dashboard; | ||
220 | + } else { | ||
221 | + Dashboard savedDashboard = null; | ||
222 | + for (CustomerId customerId : addedCustomerIds) { | ||
223 | + savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, customerId)); | ||
224 | + ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); | ||
225 | + logEntityAction(dashboardId, savedDashboard, | ||
226 | + customerId, | ||
227 | + ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); | ||
228 | + } | ||
229 | + for (CustomerId customerId : removedCustomerIds) { | ||
230 | + ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); | ||
231 | + savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, customerId)); | ||
232 | + logEntityAction(dashboardId, dashboard, | ||
233 | + customerId, | ||
234 | + ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); | ||
235 | + | ||
236 | + } | ||
237 | + return savedDashboard; | ||
238 | + } | ||
239 | + } catch (Exception e) { | ||
240 | + | ||
241 | + logEntityAction(emptyId(EntityType.DASHBOARD), null, | ||
242 | + null, | ||
243 | + ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId); | ||
244 | + | ||
245 | + throw handleException(e); | ||
246 | + } | ||
247 | + } | ||
248 | + | ||
249 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
250 | + @RequestMapping(value = "/dashboard/{dashboardId}/customers/add", method = RequestMethod.POST) | ||
251 | + @ResponseBody | ||
252 | + public Dashboard addDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId, | ||
253 | + @RequestBody String[] strCustomerIds) throws ThingsboardException { | ||
254 | + checkParameter(DASHBOARD_ID, strDashboardId); | ||
255 | + try { | ||
256 | + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); | ||
257 | + Dashboard dashboard = checkDashboardId(dashboardId); | ||
258 | + | ||
259 | + Set<CustomerId> customerIds = new HashSet<>(); | ||
260 | + if (strCustomerIds != null) { | ||
261 | + for (String strCustomerId : strCustomerIds) { | ||
262 | + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); | ||
263 | + if (!dashboard.isAssignedToCustomer(customerId)) { | ||
264 | + customerIds.add(customerId); | ||
265 | + } | ||
266 | + } | ||
267 | + } | ||
268 | + | ||
269 | + if (customerIds.isEmpty()) { | ||
270 | + return dashboard; | ||
271 | + } else { | ||
272 | + Dashboard savedDashboard = null; | ||
273 | + for (CustomerId customerId : customerIds) { | ||
274 | + savedDashboard = checkNotNull(dashboardService.assignDashboardToCustomer(dashboardId, customerId)); | ||
275 | + ShortCustomerInfo customerInfo = savedDashboard.getAssignedCustomerInfo(customerId); | ||
276 | + logEntityAction(dashboardId, savedDashboard, | ||
277 | + customerId, | ||
278 | + ActionType.ASSIGNED_TO_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); | ||
279 | + } | ||
280 | + return savedDashboard; | ||
281 | + } | ||
282 | + } catch (Exception e) { | ||
283 | + | ||
284 | + logEntityAction(emptyId(EntityType.DASHBOARD), null, | ||
285 | + null, | ||
286 | + ActionType.ASSIGNED_TO_CUSTOMER, e, strDashboardId); | ||
287 | + | ||
288 | + throw handleException(e); | ||
289 | + } | ||
290 | + } | ||
291 | + | ||
292 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
293 | + @RequestMapping(value = "/dashboard/{dashboardId}/customers/remove", method = RequestMethod.POST) | ||
294 | + @ResponseBody | ||
295 | + public Dashboard removeDashboardCustomers(@PathVariable(DASHBOARD_ID) String strDashboardId, | ||
296 | + @RequestBody String[] strCustomerIds) throws ThingsboardException { | ||
297 | + checkParameter(DASHBOARD_ID, strDashboardId); | ||
298 | + try { | ||
299 | + DashboardId dashboardId = new DashboardId(toUUID(strDashboardId)); | ||
300 | + Dashboard dashboard = checkDashboardId(dashboardId); | ||
301 | + | ||
302 | + Set<CustomerId> customerIds = new HashSet<>(); | ||
303 | + if (strCustomerIds != null) { | ||
304 | + for (String strCustomerId : strCustomerIds) { | ||
305 | + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); | ||
306 | + if (dashboard.isAssignedToCustomer(customerId)) { | ||
307 | + customerIds.add(customerId); | ||
308 | + } | ||
309 | + } | ||
310 | + } | ||
311 | + | ||
312 | + if (customerIds.isEmpty()) { | ||
313 | + return dashboard; | ||
314 | + } else { | ||
315 | + Dashboard savedDashboard = null; | ||
316 | + for (CustomerId customerId : customerIds) { | ||
317 | + ShortCustomerInfo customerInfo = dashboard.getAssignedCustomerInfo(customerId); | ||
318 | + savedDashboard = checkNotNull(dashboardService.unassignDashboardFromCustomer(dashboardId, customerId)); | ||
319 | + logEntityAction(dashboardId, dashboard, | ||
320 | + customerId, | ||
321 | + ActionType.UNASSIGNED_FROM_CUSTOMER, null, strDashboardId, customerId.toString(), customerInfo.getTitle()); | ||
322 | + | ||
323 | + } | ||
324 | + return savedDashboard; | ||
325 | + } | ||
326 | + } catch (Exception e) { | ||
327 | + | ||
328 | + logEntityAction(emptyId(EntityType.DASHBOARD), null, | ||
329 | + null, | ||
330 | + ActionType.UNASSIGNED_FROM_CUSTOMER, e, strDashboardId); | ||
331 | + | ||
332 | + throw handleException(e); | ||
333 | + } | ||
334 | + } | ||
335 | + | ||
336 | + @PreAuthorize("hasAuthority('TENANT_ADMIN')") | ||
185 | @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) | 337 | @RequestMapping(value = "/customer/public/dashboard/{dashboardId}", method = RequestMethod.POST) |
186 | @ResponseBody | 338 | @ResponseBody |
187 | public Dashboard assignDashboardToPublicCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { | 339 | public Dashboard assignDashboardToPublicCustomer(@PathVariable(DASHBOARD_ID) String strDashboardId) throws ThingsboardException { |
@@ -15,12 +15,13 @@ | @@ -15,12 +15,13 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.service.install; | 16 | package org.thingsboard.server.service.install; |
17 | 17 | ||
18 | +import com.fasterxml.jackson.databind.JavaType; | ||
18 | import com.fasterxml.jackson.databind.ObjectMapper; | 19 | import com.fasterxml.jackson.databind.ObjectMapper; |
19 | import lombok.extern.slf4j.Slf4j; | 20 | import lombok.extern.slf4j.Slf4j; |
20 | import org.apache.commons.csv.CSVFormat; | 21 | import org.apache.commons.csv.CSVFormat; |
21 | import org.apache.commons.csv.CSVParser; | 22 | import org.apache.commons.csv.CSVParser; |
22 | import org.apache.commons.lang3.StringUtils; | 23 | import org.apache.commons.lang3.StringUtils; |
23 | -import com.fasterxml.jackson.databind.JsonNode; | 24 | +import org.thingsboard.server.common.data.ShortCustomerInfo; |
24 | import org.thingsboard.server.common.data.UUIDConverter; | 25 | import org.thingsboard.server.common.data.UUIDConverter; |
25 | import org.thingsboard.server.common.data.id.CustomerId; | 26 | import org.thingsboard.server.common.data.id.CustomerId; |
26 | import org.thingsboard.server.common.data.id.DashboardId; | 27 | import org.thingsboard.server.common.data.id.DashboardId; |
@@ -54,7 +55,8 @@ public class DatabaseHelper { | @@ -54,7 +55,8 @@ public class DatabaseHelper { | ||
54 | public static final ObjectMapper objectMapper = new ObjectMapper(); | 55 | public static final ObjectMapper objectMapper = new ObjectMapper(); |
55 | 56 | ||
56 | public static void upgradeTo40_assignDashboards(Path dashboardsDump, DashboardService dashboardService, boolean sql) throws Exception { | 57 | public static void upgradeTo40_assignDashboards(Path dashboardsDump, DashboardService dashboardService, boolean sql) throws Exception { |
57 | - String[] columns = new String[]{ID, TENANT_ID, CUSTOMER_ID, TITLE, SEARCH_TEXT, ASSIGNED_CUSTOMERS, CONFIGURATION}; | 58 | + JavaType assignedCustomersType = |
59 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | ||
58 | try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(dashboardsDump), CSV_DUMP_FORMAT.withFirstRecordAsHeader())) { | 60 | try (CSVParser csvParser = new CSVParser(Files.newBufferedReader(dashboardsDump), CSV_DUMP_FORMAT.withFirstRecordAsHeader())) { |
59 | csvParser.forEach(record -> { | 61 | csvParser.forEach(record -> { |
60 | String customerIdString = record.get(CUSTOMER_ID); | 62 | String customerIdString = record.get(CUSTOMER_ID); |
@@ -63,12 +65,11 @@ public class DatabaseHelper { | @@ -63,12 +65,11 @@ public class DatabaseHelper { | ||
63 | List<CustomerId> customerIds = new ArrayList<>(); | 65 | List<CustomerId> customerIds = new ArrayList<>(); |
64 | if (!StringUtils.isEmpty(assignedCustomersString)) { | 66 | if (!StringUtils.isEmpty(assignedCustomersString)) { |
65 | try { | 67 | try { |
66 | - JsonNode assignedCustomersJson = objectMapper.readTree(assignedCustomersString); | ||
67 | - Map<String,String> assignedCustomers = objectMapper.treeToValue(assignedCustomersJson, HashMap.class); | ||
68 | - assignedCustomers.forEach((strCustomerId, title) -> { | ||
69 | - CustomerId customerId = new CustomerId(UUID.fromString(strCustomerId)); | 68 | + Set<ShortCustomerInfo> assignedCustomers = objectMapper.readValue(assignedCustomersString, assignedCustomersType); |
69 | + assignedCustomers.forEach((customerInfo) -> { | ||
70 | + CustomerId customerId = customerInfo.getCustomerId(); | ||
70 | if (!customerId.isNullUid()) { | 71 | if (!customerId.isNullUid()) { |
71 | - customerIds.add(new CustomerId(UUID.fromString(strCustomerId))); | 72 | + customerIds.add(customerId); |
72 | } | 73 | } |
73 | }); | 74 | }); |
74 | } catch (IOException e) { | 75 | } catch (IOException e) { |
@@ -78,7 +79,7 @@ public class DatabaseHelper { | @@ -78,7 +79,7 @@ public class DatabaseHelper { | ||
78 | if (!StringUtils.isEmpty(customerIdString)) { | 79 | if (!StringUtils.isEmpty(customerIdString)) { |
79 | CustomerId customerId = new CustomerId(toUUID(customerIdString, sql)); | 80 | CustomerId customerId = new CustomerId(toUUID(customerIdString, sql)); |
80 | if (!customerId.isNullUid()) { | 81 | if (!customerId.isNullUid()) { |
81 | - customerIds.add(new CustomerId(toUUID(customerIdString, sql))); | 82 | + customerIds.add(customerId); |
82 | } | 83 | } |
83 | } | 84 | } |
84 | for (CustomerId customerId : customerIds) { | 85 | for (CustomerId customerId : customerIds) { |
@@ -138,10 +138,10 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest | @@ -138,10 +138,10 @@ public abstract class BaseDashboardControllerTest extends AbstractControllerTest | ||
138 | Dashboard assignedDashboard = doPost("/api/customer/" + savedCustomer.getId().getId().toString() | 138 | Dashboard assignedDashboard = doPost("/api/customer/" + savedCustomer.getId().getId().toString() |
139 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | 139 | + "/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); |
140 | 140 | ||
141 | - Assert.assertTrue(assignedDashboard.getAssignedCustomers().containsKey(savedCustomer.getId().toString())); | 141 | + Assert.assertTrue(assignedDashboard.getAssignedCustomers().contains(savedCustomer.toShortCustomerInfo())); |
142 | 142 | ||
143 | Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | 143 | Dashboard foundDashboard = doGet("/api/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); |
144 | - Assert.assertTrue(foundDashboard.getAssignedCustomers().containsKey(savedCustomer.getId().toString())); | 144 | + Assert.assertTrue(foundDashboard.getAssignedCustomers().contains(savedCustomer.toShortCustomerInfo())); |
145 | 145 | ||
146 | Dashboard unassignedDashboard = | 146 | Dashboard unassignedDashboard = |
147 | doDelete("/api/customer/"+savedCustomer.getId().getId().toString()+"/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); | 147 | doDelete("/api/customer/"+savedCustomer.getId().getId().toString()+"/dashboard/" + savedDashboard.getId().getId().toString(), Dashboard.class); |
@@ -69,6 +69,11 @@ public class Customer extends ContactBased<CustomerId> implements HasName { | @@ -69,6 +69,11 @@ public class Customer extends ContactBased<CustomerId> implements HasName { | ||
69 | return false; | 69 | return false; |
70 | } | 70 | } |
71 | 71 | ||
72 | + @JsonIgnore | ||
73 | + public ShortCustomerInfo toShortCustomerInfo() { | ||
74 | + return new ShortCustomerInfo(id, title, isPublic()); | ||
75 | + } | ||
76 | + | ||
72 | @Override | 77 | @Override |
73 | @JsonProperty(access = Access.READ_ONLY) | 78 | @JsonProperty(access = Access.READ_ONLY) |
74 | public String getName() { | 79 | public String getName() { |
@@ -20,16 +20,13 @@ import org.thingsboard.server.common.data.id.CustomerId; | @@ -20,16 +20,13 @@ import org.thingsboard.server.common.data.id.CustomerId; | ||
20 | import org.thingsboard.server.common.data.id.DashboardId; | 20 | import org.thingsboard.server.common.data.id.DashboardId; |
21 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
22 | 22 | ||
23 | -import java.util.HashMap; | ||
24 | -import java.util.List; | ||
25 | -import java.util.Map; | ||
26 | -import java.util.Set; | 23 | +import java.util.*; |
27 | 24 | ||
28 | public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName { | 25 | public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName { |
29 | 26 | ||
30 | private TenantId tenantId; | 27 | private TenantId tenantId; |
31 | private String title; | 28 | private String title; |
32 | - private Map<String, String> assignedCustomers; | 29 | + private Set<ShortCustomerInfo> assignedCustomers; |
33 | 30 | ||
34 | public DashboardInfo() { | 31 | public DashboardInfo() { |
35 | super(); | 32 | super(); |
@@ -62,38 +59,56 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa | @@ -62,38 +59,56 @@ public class DashboardInfo extends SearchTextBased<DashboardId> implements HasNa | ||
62 | this.title = title; | 59 | this.title = title; |
63 | } | 60 | } |
64 | 61 | ||
65 | - public Map<String, String> getAssignedCustomers() { | 62 | + public Set<ShortCustomerInfo> getAssignedCustomers() { |
66 | return assignedCustomers; | 63 | return assignedCustomers; |
67 | } | 64 | } |
68 | 65 | ||
69 | - public void setAssignedCustomers(Map<String, String> assignedCustomers) { | 66 | + public void setAssignedCustomers(Set<ShortCustomerInfo> assignedCustomers) { |
70 | this.assignedCustomers = assignedCustomers; | 67 | this.assignedCustomers = assignedCustomers; |
71 | } | 68 | } |
72 | 69 | ||
73 | - public boolean addAssignedCustomer(CustomerId customerId, String title) { | ||
74 | - if (this.assignedCustomers != null && this.assignedCustomers.containsKey(customerId.toString())) { | 70 | + public boolean isAssignedToCustomer(CustomerId customerId) { |
71 | + return this.assignedCustomers != null && this.assignedCustomers.contains(new ShortCustomerInfo(customerId, null, false)); | ||
72 | + } | ||
73 | + | ||
74 | + public ShortCustomerInfo getAssignedCustomerInfo(CustomerId customerId) { | ||
75 | + if (this.assignedCustomers != null) { | ||
76 | + for (ShortCustomerInfo customerInfo : this.assignedCustomers) { | ||
77 | + if (customerInfo.getCustomerId().equals(customerId)) { | ||
78 | + return customerInfo; | ||
79 | + } | ||
80 | + } | ||
81 | + } | ||
82 | + return null; | ||
83 | + } | ||
84 | + | ||
85 | + public boolean addAssignedCustomer(Customer customer) { | ||
86 | + ShortCustomerInfo customerInfo = customer.toShortCustomerInfo(); | ||
87 | + if (this.assignedCustomers != null && this.assignedCustomers.contains(customerInfo)) { | ||
75 | return false; | 88 | return false; |
76 | } else { | 89 | } else { |
77 | if (this.assignedCustomers == null) { | 90 | if (this.assignedCustomers == null) { |
78 | - this.assignedCustomers = new HashMap<>(); | 91 | + this.assignedCustomers = new HashSet<>(); |
79 | } | 92 | } |
80 | - this.assignedCustomers.put(customerId.toString(), title); | 93 | + this.assignedCustomers.add(customerInfo); |
81 | return true; | 94 | return true; |
82 | } | 95 | } |
83 | } | 96 | } |
84 | 97 | ||
85 | - public boolean updateAssignedCustomer(CustomerId customerId, String title) { | ||
86 | - if (this.assignedCustomers != null && this.assignedCustomers.containsKey(customerId.toString())) { | ||
87 | - this.assignedCustomers.put(customerId.toString(), title); | 98 | + public boolean updateAssignedCustomer(Customer customer) { |
99 | + ShortCustomerInfo customerInfo = customer.toShortCustomerInfo(); | ||
100 | + if (this.assignedCustomers != null && this.assignedCustomers.contains(customerInfo)) { | ||
101 | + this.assignedCustomers.add(customerInfo); | ||
88 | return true; | 102 | return true; |
89 | } else { | 103 | } else { |
90 | return false; | 104 | return false; |
91 | } | 105 | } |
92 | } | 106 | } |
93 | 107 | ||
94 | - public boolean removeAssignedCustomer(CustomerId customerId) { | ||
95 | - if (this.assignedCustomers != null && this.assignedCustomers.containsKey(customerId.toString())) { | ||
96 | - this.assignedCustomers.remove(customerId.toString()); | 108 | + public boolean removeAssignedCustomer(Customer customer) { |
109 | + ShortCustomerInfo customerInfo = customer.toShortCustomerInfo(); | ||
110 | + if (this.assignedCustomers != null && this.assignedCustomers.contains(customerInfo)) { | ||
111 | + this.assignedCustomers.remove(customerInfo); | ||
97 | return true; | 112 | return true; |
98 | } else { | 113 | } else { |
99 | return false; | 114 | return false; |
1 | +/** | ||
2 | + * Copyright © 2016-2017 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; | ||
17 | + | ||
18 | +import lombok.AllArgsConstructor; | ||
19 | +import lombok.Getter; | ||
20 | +import lombok.Setter; | ||
21 | +import org.thingsboard.server.common.data.id.CustomerId; | ||
22 | + | ||
23 | +/** | ||
24 | + * Created by igor on 2/27/18. | ||
25 | + */ | ||
26 | + | ||
27 | +@AllArgsConstructor | ||
28 | +public class ShortCustomerInfo { | ||
29 | + | ||
30 | + @Getter @Setter | ||
31 | + private CustomerId customerId; | ||
32 | + | ||
33 | + @Getter @Setter | ||
34 | + private String title; | ||
35 | + | ||
36 | + @Getter @Setter | ||
37 | + private boolean isPublic; | ||
38 | + | ||
39 | + @Override | ||
40 | + public boolean equals(Object o) { | ||
41 | + if (this == o) return true; | ||
42 | + if (o == null || getClass() != o.getClass()) return false; | ||
43 | + | ||
44 | + ShortCustomerInfo that = (ShortCustomerInfo) o; | ||
45 | + | ||
46 | + return customerId.equals(that.customerId); | ||
47 | + | ||
48 | + } | ||
49 | + | ||
50 | + @Override | ||
51 | + public int hashCode() { | ||
52 | + return customerId.hashCode(); | ||
53 | + } | ||
54 | +} |
@@ -98,7 +98,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -98,7 +98,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
98 | log.trace("Executing saveCustomer [{}]", customer); | 98 | log.trace("Executing saveCustomer [{}]", customer); |
99 | customerValidator.validate(customer); | 99 | customerValidator.validate(customer); |
100 | Customer savedCustomer = customerDao.save(customer); | 100 | Customer savedCustomer = customerDao.save(customer); |
101 | - dashboardService.updateCustomerDashboards(savedCustomer.getTenantId(), savedCustomer.getId(), savedCustomer.getTitle()); | 101 | + dashboardService.updateCustomerDashboards(savedCustomer.getId()); |
102 | return savedCustomer; | 102 | return savedCustomer; |
103 | } | 103 | } |
104 | 104 | ||
@@ -110,7 +110,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | @@ -110,7 +110,7 @@ public class CustomerServiceImpl extends AbstractEntityService implements Custom | ||
110 | if (customer == null) { | 110 | if (customer == null) { |
111 | throw new IncorrectParameterException("Unable to delete non-existent customer."); | 111 | throw new IncorrectParameterException("Unable to delete non-existent customer."); |
112 | } | 112 | } |
113 | - dashboardService.unassignCustomerDashboards(customer.getTenantId(), customerId); | 113 | + dashboardService.unassignCustomerDashboards(customerId); |
114 | assetService.unassignCustomerAssets(customer.getTenantId(), customerId); | 114 | assetService.unassignCustomerAssets(customer.getTenantId(), customerId); |
115 | deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); | 115 | deviceService.unassignCustomerDevices(customer.getTenantId(), customerId); |
116 | userService.deleteCustomerUsers(customer.getTenantId(), customerId); | 116 | userService.deleteCustomerUsers(customer.getTenantId(), customerId); |
@@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | @@ -26,7 +26,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | ||
26 | import org.thingsboard.server.common.data.page.TimePageData; | 26 | import org.thingsboard.server.common.data.page.TimePageData; |
27 | import org.thingsboard.server.common.data.page.TimePageLink; | 27 | import org.thingsboard.server.common.data.page.TimePageLink; |
28 | 28 | ||
29 | -import java.sql.Time; | 29 | +import java.util.Set; |
30 | 30 | ||
31 | public interface DashboardService { | 31 | public interface DashboardService { |
32 | 32 | ||
@@ -52,8 +52,8 @@ public interface DashboardService { | @@ -52,8 +52,8 @@ public interface DashboardService { | ||
52 | 52 | ||
53 | ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TimePageLink pageLink); | 53 | ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndCustomerId(TenantId tenantId, CustomerId customerId, TimePageLink pageLink); |
54 | 54 | ||
55 | - void unassignCustomerDashboards(TenantId tenantId, CustomerId customerId); | 55 | + void unassignCustomerDashboards(CustomerId customerId); |
56 | 56 | ||
57 | - void updateCustomerDashboards(TenantId tenantId, CustomerId customerId, String customerTitle); | 57 | + void updateCustomerDashboards(CustomerId customerId); |
58 | 58 | ||
59 | } | 59 | } |
@@ -117,7 +117,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -117,7 +117,7 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
117 | if (!customer.getTenantId().getId().equals(dashboard.getTenantId().getId())) { | 117 | if (!customer.getTenantId().getId().equals(dashboard.getTenantId().getId())) { |
118 | throw new DataValidationException("Can't assign dashboard to customer from different tenant!"); | 118 | throw new DataValidationException("Can't assign dashboard to customer from different tenant!"); |
119 | } | 119 | } |
120 | - if (dashboard.addAssignedCustomer(customerId, customer.getTitle())) { | 120 | + if (dashboard.addAssignedCustomer(customer)) { |
121 | try { | 121 | try { |
122 | createRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); | 122 | createRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); |
123 | } catch (ExecutionException | InterruptedException e) { | 123 | } catch (ExecutionException | InterruptedException e) { |
@@ -133,7 +133,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -133,7 +133,11 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
133 | @Override | 133 | @Override |
134 | public Dashboard unassignDashboardFromCustomer(DashboardId dashboardId, CustomerId customerId) { | 134 | public Dashboard unassignDashboardFromCustomer(DashboardId dashboardId, CustomerId customerId) { |
135 | Dashboard dashboard = findDashboardById(dashboardId); | 135 | Dashboard dashboard = findDashboardById(dashboardId); |
136 | - if (dashboard.removeAssignedCustomer(customerId)) { | 136 | + Customer customer = customerDao.findById(customerId.getId()); |
137 | + if (customer == null) { | ||
138 | + throw new DataValidationException("Can't unassign dashboard from non-existent customer!"); | ||
139 | + } | ||
140 | + if (dashboard.removeAssignedCustomer(customer)) { | ||
137 | try { | 141 | try { |
138 | deleteRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); | 142 | deleteRelation(new EntityRelation(customerId, dashboardId, EntityRelation.CONTAINS_TYPE, RelationTypeGroup.DASHBOARD)); |
139 | } catch (ExecutionException | InterruptedException e) { | 143 | } catch (ExecutionException | InterruptedException e) { |
@@ -146,9 +150,9 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -146,9 +150,9 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
146 | } | 150 | } |
147 | } | 151 | } |
148 | 152 | ||
149 | - private Dashboard updateAssignedCustomerTitle(DashboardId dashboardId, CustomerId customerId, String customerTitle) { | 153 | + private Dashboard updateAssignedCustomer(DashboardId dashboardId, Customer customer) { |
150 | Dashboard dashboard = findDashboardById(dashboardId); | 154 | Dashboard dashboard = findDashboardById(dashboardId); |
151 | - if (dashboard.updateAssignedCustomer(customerId, customerTitle)) { | 155 | + if (dashboard.updateAssignedCustomer(customer)) { |
152 | return saveDashboard(dashboard); | 156 | return saveDashboard(dashboard); |
153 | } else { | 157 | } else { |
154 | return dashboard; | 158 | return dashboard; |
@@ -207,20 +211,25 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -207,20 +211,25 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
207 | } | 211 | } |
208 | 212 | ||
209 | @Override | 213 | @Override |
210 | - public void unassignCustomerDashboards(TenantId tenantId, CustomerId customerId) { | ||
211 | - log.trace("Executing unassignCustomerDashboards, tenantId [{}], customerId [{}]", tenantId, customerId); | ||
212 | - Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 214 | + public void unassignCustomerDashboards(CustomerId customerId) { |
215 | + log.trace("Executing unassignCustomerDashboards, customerId [{}]", customerId); | ||
213 | Validator.validateId(customerId, "Incorrect customerId " + customerId); | 216 | Validator.validateId(customerId, "Incorrect customerId " + customerId); |
214 | - new CustomerDashboardsUnassigner(tenantId, customerId).removeEntities(customerId); | 217 | + Customer customer = customerDao.findById(customerId.getId()); |
218 | + if (customer == null) { | ||
219 | + throw new DataValidationException("Can't unassign dashboards from non-existent customer!"); | ||
220 | + } | ||
221 | + new CustomerDashboardsUnassigner(customer).removeEntities(customer); | ||
215 | } | 222 | } |
216 | 223 | ||
217 | @Override | 224 | @Override |
218 | - public void updateCustomerDashboards(TenantId tenantId, CustomerId customerId, String customerTitle) { | ||
219 | - log.trace("Executing updateCustomerDashboards, tenantId [{}], customerId [{}], customerTitle [{}]", tenantId, customerId, customerTitle); | ||
220 | - Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | 225 | + public void updateCustomerDashboards(CustomerId customerId) { |
226 | + log.trace("Executing updateCustomerDashboards, customerId [{}]", customerId); | ||
221 | Validator.validateId(customerId, "Incorrect customerId " + customerId); | 227 | Validator.validateId(customerId, "Incorrect customerId " + customerId); |
222 | - Validator.validateString(customerTitle, "Incorrect customerTitle " + customerTitle); | ||
223 | - new CustomerDashboardsUpdater(tenantId, customerId, customerTitle).removeEntities(customerId); | 228 | + Customer customer = customerDao.findById(customerId.getId()); |
229 | + if (customer == null) { | ||
230 | + throw new DataValidationException("Can't update dashboards for non-existent customer!"); | ||
231 | + } | ||
232 | + new CustomerDashboardsUpdater(customer).removeEntities(customer); | ||
224 | } | 233 | } |
225 | 234 | ||
226 | private DataValidator<Dashboard> dashboardValidator = | 235 | private DataValidator<Dashboard> dashboardValidator = |
@@ -255,58 +264,52 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -255,58 +264,52 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
255 | } | 264 | } |
256 | }; | 265 | }; |
257 | 266 | ||
258 | - private class CustomerDashboardsUnassigner extends TimePaginatedRemover<CustomerId, DashboardInfo> { | ||
259 | - | ||
260 | - private TenantId tenantId; | ||
261 | - private CustomerId customerId; | 267 | + private class CustomerDashboardsUnassigner extends TimePaginatedRemover<Customer, DashboardInfo> { |
262 | 268 | ||
263 | - CustomerDashboardsUnassigner(TenantId tenantId, CustomerId customerId) { | ||
264 | - this.tenantId = tenantId; | ||
265 | - this.customerId = customerId; | 269 | + private Customer customer; |
270 | + | ||
271 | + CustomerDashboardsUnassigner(Customer customer) { | ||
272 | + this.customer = customer; | ||
266 | } | 273 | } |
267 | 274 | ||
268 | @Override | 275 | @Override |
269 | - protected List<DashboardInfo> findEntities(CustomerId id, TimePageLink pageLink) { | 276 | + protected List<DashboardInfo> findEntities(Customer customer, TimePageLink pageLink) { |
270 | try { | 277 | try { |
271 | - return dashboardInfoDao.findDashboardsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink).get(); | 278 | + return dashboardInfoDao.findDashboardsByTenantIdAndCustomerId(customer.getTenantId().getId(), customer.getId().getId(), pageLink).get(); |
272 | } catch (InterruptedException | ExecutionException e) { | 279 | } catch (InterruptedException | ExecutionException e) { |
273 | - log.warn("Failed to get dashboards by tenantId [{}] and customerId [{}].", tenantId, id); | 280 | + log.warn("Failed to get dashboards by tenantId [{}] and customerId [{}].", customer.getTenantId().getId(), customer.getId().getId()); |
274 | throw new RuntimeException(e); | 281 | throw new RuntimeException(e); |
275 | } | 282 | } |
276 | } | 283 | } |
277 | 284 | ||
278 | @Override | 285 | @Override |
279 | protected void removeEntity(DashboardInfo entity) { | 286 | protected void removeEntity(DashboardInfo entity) { |
280 | - unassignDashboardFromCustomer(new DashboardId(entity.getUuidId()), this.customerId); | 287 | + unassignDashboardFromCustomer(new DashboardId(entity.getUuidId()), this.customer.getId()); |
281 | } | 288 | } |
282 | 289 | ||
283 | } | 290 | } |
284 | 291 | ||
285 | - private class CustomerDashboardsUpdater extends TimePaginatedRemover<CustomerId, DashboardInfo> { | 292 | + private class CustomerDashboardsUpdater extends TimePaginatedRemover<Customer, DashboardInfo> { |
286 | 293 | ||
287 | - private TenantId tenantId; | ||
288 | - private CustomerId customerId; | ||
289 | - private String customerTitle; | 294 | + private Customer customer; |
290 | 295 | ||
291 | - CustomerDashboardsUpdater(TenantId tenantId, CustomerId customerId, String customerTitle) { | ||
292 | - this.tenantId = tenantId; | ||
293 | - this.customerId = customerId; | ||
294 | - this.customerTitle = customerTitle; | 296 | + CustomerDashboardsUpdater(Customer customer) { |
297 | + this.customer = customer; | ||
295 | } | 298 | } |
296 | 299 | ||
297 | @Override | 300 | @Override |
298 | - protected List<DashboardInfo> findEntities(CustomerId id, TimePageLink pageLink) { | 301 | + protected List<DashboardInfo> findEntities(Customer customer, TimePageLink pageLink) { |
299 | try { | 302 | try { |
300 | - return dashboardInfoDao.findDashboardsByTenantIdAndCustomerId(tenantId.getId(), id.getId(), pageLink).get(); | 303 | + return dashboardInfoDao.findDashboardsByTenantIdAndCustomerId(customer.getTenantId().getId(), customer.getId().getId(), pageLink).get(); |
301 | } catch (InterruptedException | ExecutionException e) { | 304 | } catch (InterruptedException | ExecutionException e) { |
302 | - log.warn("Failed to get dashboards by tenantId [{}] and customerId [{}].", tenantId, id); | 305 | + log.warn("Failed to get dashboards by tenantId [{}] and customerId [{}].", customer.getTenantId().getId(), customer.getId().getId()); |
303 | throw new RuntimeException(e); | 306 | throw new RuntimeException(e); |
304 | } | 307 | } |
305 | } | 308 | } |
306 | 309 | ||
307 | @Override | 310 | @Override |
308 | protected void removeEntity(DashboardInfo entity) { | 311 | protected void removeEntity(DashboardInfo entity) { |
309 | - updateAssignedCustomerTitle(new DashboardId(entity.getUuidId()), this.customerId, this.customerTitle); | 312 | + updateAssignedCustomer(new DashboardId(entity.getUuidId()), this.customer); |
310 | } | 313 | } |
311 | 314 | ||
312 | } | 315 | } |
@@ -20,18 +20,22 @@ import com.datastax.driver.mapping.annotations.Column; | @@ -20,18 +20,22 @@ import com.datastax.driver.mapping.annotations.Column; | ||
20 | import com.datastax.driver.mapping.annotations.PartitionKey; | 20 | import com.datastax.driver.mapping.annotations.PartitionKey; |
21 | import com.datastax.driver.mapping.annotations.Table; | 21 | import com.datastax.driver.mapping.annotations.Table; |
22 | import com.fasterxml.jackson.core.JsonProcessingException; | 22 | import com.fasterxml.jackson.core.JsonProcessingException; |
23 | +import com.fasterxml.jackson.databind.JavaType; | ||
23 | import com.fasterxml.jackson.databind.JsonNode; | 24 | import com.fasterxml.jackson.databind.JsonNode; |
24 | import com.fasterxml.jackson.databind.ObjectMapper; | 25 | import com.fasterxml.jackson.databind.ObjectMapper; |
25 | import lombok.EqualsAndHashCode; | 26 | import lombok.EqualsAndHashCode; |
26 | import lombok.ToString; | 27 | import lombok.ToString; |
27 | import lombok.extern.slf4j.Slf4j; | 28 | import lombok.extern.slf4j.Slf4j; |
29 | +import org.springframework.util.StringUtils; | ||
28 | import org.thingsboard.server.common.data.Dashboard; | 30 | import org.thingsboard.server.common.data.Dashboard; |
31 | +import org.thingsboard.server.common.data.ShortCustomerInfo; | ||
29 | import org.thingsboard.server.common.data.id.DashboardId; | 32 | import org.thingsboard.server.common.data.id.DashboardId; |
30 | import org.thingsboard.server.common.data.id.TenantId; | 33 | import org.thingsboard.server.common.data.id.TenantId; |
31 | import org.thingsboard.server.dao.model.SearchTextEntity; | 34 | import org.thingsboard.server.dao.model.SearchTextEntity; |
32 | import org.thingsboard.server.dao.model.type.JsonCodec; | 35 | import org.thingsboard.server.dao.model.type.JsonCodec; |
33 | 36 | ||
34 | -import java.util.HashMap; | 37 | +import java.io.IOException; |
38 | +import java.util.HashSet; | ||
35 | import java.util.UUID; | 39 | import java.util.UUID; |
36 | 40 | ||
37 | import static org.thingsboard.server.dao.model.ModelConstants.*; | 41 | import static org.thingsboard.server.dao.model.ModelConstants.*; |
@@ -43,6 +47,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; | @@ -43,6 +47,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; | ||
43 | public final class DashboardEntity implements SearchTextEntity<Dashboard> { | 47 | public final class DashboardEntity implements SearchTextEntity<Dashboard> { |
44 | 48 | ||
45 | private static final ObjectMapper objectMapper = new ObjectMapper(); | 49 | private static final ObjectMapper objectMapper = new ObjectMapper(); |
50 | + private static final JavaType assignedCustomersType = | ||
51 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | ||
46 | 52 | ||
47 | @PartitionKey(value = 0) | 53 | @PartitionKey(value = 0) |
48 | @Column(name = ID_PROPERTY) | 54 | @Column(name = ID_PROPERTY) |
@@ -58,8 +64,8 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | @@ -58,8 +64,8 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | ||
58 | @Column(name = SEARCH_TEXT_PROPERTY) | 64 | @Column(name = SEARCH_TEXT_PROPERTY) |
59 | private String searchText; | 65 | private String searchText; |
60 | 66 | ||
61 | - @Column(name = DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY, codec = JsonCodec.class) | ||
62 | - private JsonNode assignedCustomers; | 67 | + @Column(name = DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) |
68 | + private String assignedCustomers; | ||
63 | 69 | ||
64 | @Column(name = DASHBOARD_CONFIGURATION_PROPERTY, codec = JsonCodec.class) | 70 | @Column(name = DASHBOARD_CONFIGURATION_PROPERTY, codec = JsonCodec.class) |
65 | private JsonNode configuration; | 71 | private JsonNode configuration; |
@@ -77,7 +83,11 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | @@ -77,7 +83,11 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | ||
77 | } | 83 | } |
78 | this.title = dashboard.getTitle(); | 84 | this.title = dashboard.getTitle(); |
79 | if (dashboard.getAssignedCustomers() != null) { | 85 | if (dashboard.getAssignedCustomers() != null) { |
80 | - this.assignedCustomers = objectMapper.valueToTree(dashboard.getAssignedCustomers()); | 86 | + try { |
87 | + this.assignedCustomers = objectMapper.writeValueAsString(dashboard.getAssignedCustomers()); | ||
88 | + } catch (JsonProcessingException e) { | ||
89 | + log.error("Unable to serialize assigned customers to string!", e); | ||
90 | + } | ||
81 | } | 91 | } |
82 | this.configuration = dashboard.getConfiguration(); | 92 | this.configuration = dashboard.getConfiguration(); |
83 | } | 93 | } |
@@ -106,11 +116,11 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | @@ -106,11 +116,11 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | ||
106 | this.title = title; | 116 | this.title = title; |
107 | } | 117 | } |
108 | 118 | ||
109 | - public JsonNode getAssignedCustomers() { | 119 | + public String getAssignedCustomers() { |
110 | return assignedCustomers; | 120 | return assignedCustomers; |
111 | } | 121 | } |
112 | 122 | ||
113 | - public void setAssignedCustomers(JsonNode assignedCustomers) { | 123 | + public void setAssignedCustomers(String assignedCustomers) { |
114 | this.assignedCustomers = assignedCustomers; | 124 | this.assignedCustomers = assignedCustomers; |
115 | } | 125 | } |
116 | 126 | ||
@@ -144,10 +154,10 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | @@ -144,10 +154,10 @@ public final class DashboardEntity implements SearchTextEntity<Dashboard> { | ||
144 | dashboard.setTenantId(new TenantId(tenantId)); | 154 | dashboard.setTenantId(new TenantId(tenantId)); |
145 | } | 155 | } |
146 | dashboard.setTitle(title); | 156 | dashboard.setTitle(title); |
147 | - if (assignedCustomers != null) { | 157 | + if (!StringUtils.isEmpty(assignedCustomers)) { |
148 | try { | 158 | try { |
149 | - dashboard.setAssignedCustomers(objectMapper.treeToValue(assignedCustomers, HashMap.class)); | ||
150 | - } catch (JsonProcessingException e) { | 159 | + dashboard.setAssignedCustomers(objectMapper.readValue(assignedCustomers, assignedCustomersType)); |
160 | + } catch (IOException e) { | ||
151 | log.warn("Unable to parse assigned customers!", e); | 161 | log.warn("Unable to parse assigned customers!", e); |
152 | } | 162 | } |
153 | } | 163 | } |
@@ -20,20 +20,20 @@ import com.datastax.driver.mapping.annotations.Column; | @@ -20,20 +20,20 @@ import com.datastax.driver.mapping.annotations.Column; | ||
20 | import com.datastax.driver.mapping.annotations.PartitionKey; | 20 | import com.datastax.driver.mapping.annotations.PartitionKey; |
21 | import com.datastax.driver.mapping.annotations.Table; | 21 | import com.datastax.driver.mapping.annotations.Table; |
22 | import com.fasterxml.jackson.core.JsonProcessingException; | 22 | import com.fasterxml.jackson.core.JsonProcessingException; |
23 | -import com.fasterxml.jackson.databind.JsonNode; | 23 | +import com.fasterxml.jackson.databind.JavaType; |
24 | import com.fasterxml.jackson.databind.ObjectMapper; | 24 | import com.fasterxml.jackson.databind.ObjectMapper; |
25 | import lombok.EqualsAndHashCode; | 25 | import lombok.EqualsAndHashCode; |
26 | import lombok.ToString; | 26 | import lombok.ToString; |
27 | import lombok.extern.slf4j.Slf4j; | 27 | import lombok.extern.slf4j.Slf4j; |
28 | +import org.springframework.util.StringUtils; | ||
28 | import org.thingsboard.server.common.data.DashboardInfo; | 29 | import org.thingsboard.server.common.data.DashboardInfo; |
29 | -import org.thingsboard.server.common.data.id.CustomerId; | 30 | +import org.thingsboard.server.common.data.ShortCustomerInfo; |
30 | import org.thingsboard.server.common.data.id.DashboardId; | 31 | import org.thingsboard.server.common.data.id.DashboardId; |
31 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
32 | import org.thingsboard.server.dao.model.SearchTextEntity; | 33 | import org.thingsboard.server.dao.model.SearchTextEntity; |
33 | -import org.thingsboard.server.dao.model.type.JsonCodec; | ||
34 | 34 | ||
35 | -import java.util.HashMap; | ||
36 | -import java.util.Set; | 35 | +import java.io.IOException; |
36 | +import java.util.HashSet; | ||
37 | import java.util.UUID; | 37 | import java.util.UUID; |
38 | 38 | ||
39 | import static org.thingsboard.server.dao.model.ModelConstants.*; | 39 | import static org.thingsboard.server.dao.model.ModelConstants.*; |
@@ -45,6 +45,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; | @@ -45,6 +45,8 @@ import static org.thingsboard.server.dao.model.ModelConstants.*; | ||
45 | public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | 45 | public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { |
46 | 46 | ||
47 | private static final ObjectMapper objectMapper = new ObjectMapper(); | 47 | private static final ObjectMapper objectMapper = new ObjectMapper(); |
48 | + private static final JavaType assignedCustomersType = | ||
49 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | ||
48 | 50 | ||
49 | @PartitionKey(value = 0) | 51 | @PartitionKey(value = 0) |
50 | @Column(name = ID_PROPERTY) | 52 | @Column(name = ID_PROPERTY) |
@@ -60,8 +62,8 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | @@ -60,8 +62,8 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | ||
60 | @Column(name = SEARCH_TEXT_PROPERTY) | 62 | @Column(name = SEARCH_TEXT_PROPERTY) |
61 | private String searchText; | 63 | private String searchText; |
62 | 64 | ||
63 | - @Column(name = DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY, codec = JsonCodec.class) | ||
64 | - private JsonNode assignedCustomers; | 65 | + @Column(name = DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) |
66 | + private String assignedCustomers; | ||
65 | 67 | ||
66 | public DashboardInfoEntity() { | 68 | public DashboardInfoEntity() { |
67 | super(); | 69 | super(); |
@@ -76,7 +78,11 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | @@ -76,7 +78,11 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | ||
76 | } | 78 | } |
77 | this.title = dashboardInfo.getTitle(); | 79 | this.title = dashboardInfo.getTitle(); |
78 | if (dashboardInfo.getAssignedCustomers() != null) { | 80 | if (dashboardInfo.getAssignedCustomers() != null) { |
79 | - this.assignedCustomers = objectMapper.valueToTree(dashboardInfo.getAssignedCustomers()); | 81 | + try { |
82 | + this.assignedCustomers = objectMapper.writeValueAsString(dashboardInfo.getAssignedCustomers()); | ||
83 | + } catch (JsonProcessingException e) { | ||
84 | + log.error("Unable to serialize assigned customers to string!", e); | ||
85 | + } | ||
80 | } | 86 | } |
81 | } | 87 | } |
82 | 88 | ||
@@ -104,11 +110,11 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | @@ -104,11 +110,11 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | ||
104 | this.title = title; | 110 | this.title = title; |
105 | } | 111 | } |
106 | 112 | ||
107 | - public JsonNode getAssignedCustomers() { | 113 | + public String getAssignedCustomers() { |
108 | return assignedCustomers; | 114 | return assignedCustomers; |
109 | } | 115 | } |
110 | 116 | ||
111 | - public void setAssignedCustomers(JsonNode assignedCustomers) { | 117 | + public void setAssignedCustomers(String assignedCustomers) { |
112 | this.assignedCustomers = assignedCustomers; | 118 | this.assignedCustomers = assignedCustomers; |
113 | } | 119 | } |
114 | 120 | ||
@@ -134,10 +140,10 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | @@ -134,10 +140,10 @@ public class DashboardInfoEntity implements SearchTextEntity<DashboardInfo> { | ||
134 | dashboardInfo.setTenantId(new TenantId(tenantId)); | 140 | dashboardInfo.setTenantId(new TenantId(tenantId)); |
135 | } | 141 | } |
136 | dashboardInfo.setTitle(title); | 142 | dashboardInfo.setTitle(title); |
137 | - if (assignedCustomers != null) { | 143 | + if (!StringUtils.isEmpty(assignedCustomers)) { |
138 | try { | 144 | try { |
139 | - dashboardInfo.setAssignedCustomers(objectMapper.treeToValue(assignedCustomers, HashMap.class)); | ||
140 | - } catch (JsonProcessingException e) { | 145 | + dashboardInfo.setAssignedCustomers(objectMapper.readValue(assignedCustomers, assignedCustomersType)); |
146 | + } catch (IOException e) { | ||
141 | log.warn("Unable to parse assigned customers!", e); | 147 | log.warn("Unable to parse assigned customers!", e); |
142 | } | 148 | } |
143 | } | 149 | } |
@@ -17,6 +17,7 @@ package org.thingsboard.server.dao.model.sql; | @@ -17,6 +17,7 @@ package org.thingsboard.server.dao.model.sql; | ||
17 | 17 | ||
18 | import com.datastax.driver.core.utils.UUIDs; | 18 | import com.datastax.driver.core.utils.UUIDs; |
19 | import com.fasterxml.jackson.core.JsonProcessingException; | 19 | import com.fasterxml.jackson.core.JsonProcessingException; |
20 | +import com.fasterxml.jackson.databind.JavaType; | ||
20 | import com.fasterxml.jackson.databind.JsonNode; | 21 | import com.fasterxml.jackson.databind.JsonNode; |
21 | import com.fasterxml.jackson.databind.ObjectMapper; | 22 | import com.fasterxml.jackson.databind.ObjectMapper; |
22 | import lombok.Data; | 23 | import lombok.Data; |
@@ -24,8 +25,9 @@ import lombok.EqualsAndHashCode; | @@ -24,8 +25,9 @@ import lombok.EqualsAndHashCode; | ||
24 | import lombok.extern.slf4j.Slf4j; | 25 | import lombok.extern.slf4j.Slf4j; |
25 | import org.hibernate.annotations.Type; | 26 | import org.hibernate.annotations.Type; |
26 | import org.hibernate.annotations.TypeDef; | 27 | import org.hibernate.annotations.TypeDef; |
28 | +import org.springframework.util.StringUtils; | ||
27 | import org.thingsboard.server.common.data.Dashboard; | 29 | import org.thingsboard.server.common.data.Dashboard; |
28 | -import org.thingsboard.server.common.data.id.CustomerId; | 30 | +import org.thingsboard.server.common.data.ShortCustomerInfo; |
29 | import org.thingsboard.server.common.data.id.DashboardId; | 31 | import org.thingsboard.server.common.data.id.DashboardId; |
30 | import org.thingsboard.server.common.data.id.TenantId; | 32 | import org.thingsboard.server.common.data.id.TenantId; |
31 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 33 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
@@ -36,9 +38,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | @@ -36,9 +38,8 @@ import org.thingsboard.server.dao.util.mapping.JsonStringType; | ||
36 | import javax.persistence.Column; | 38 | import javax.persistence.Column; |
37 | import javax.persistence.Entity; | 39 | import javax.persistence.Entity; |
38 | import javax.persistence.Table; | 40 | import javax.persistence.Table; |
39 | -import java.util.HashMap; | ||
40 | -import java.util.List; | ||
41 | -import java.util.Set; | 41 | +import java.io.IOException; |
42 | +import java.util.HashSet; | ||
42 | 43 | ||
43 | @Data | 44 | @Data |
44 | @Slf4j | 45 | @Slf4j |
@@ -49,6 +50,8 @@ import java.util.Set; | @@ -49,6 +50,8 @@ import java.util.Set; | ||
49 | public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements SearchTextEntity<Dashboard> { | 50 | public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements SearchTextEntity<Dashboard> { |
50 | 51 | ||
51 | private static final ObjectMapper objectMapper = new ObjectMapper(); | 52 | private static final ObjectMapper objectMapper = new ObjectMapper(); |
53 | + private static final JavaType assignedCustomersType = | ||
54 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | ||
52 | 55 | ||
53 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) | 56 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) |
54 | private String tenantId; | 57 | private String tenantId; |
@@ -59,9 +62,8 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | @@ -59,9 +62,8 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | ||
59 | @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | 62 | @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) |
60 | private String searchText; | 63 | private String searchText; |
61 | 64 | ||
62 | - @Type(type = "json") | ||
63 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) | 65 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) |
64 | - private JsonNode assignedCustomers; | 66 | + private String assignedCustomers; |
65 | 67 | ||
66 | @Type(type = "json") | 68 | @Type(type = "json") |
67 | @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY) | 69 | @Column(name = ModelConstants.DASHBOARD_CONFIGURATION_PROPERTY) |
@@ -80,7 +82,11 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | @@ -80,7 +82,11 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | ||
80 | } | 82 | } |
81 | this.title = dashboard.getTitle(); | 83 | this.title = dashboard.getTitle(); |
82 | if (dashboard.getAssignedCustomers() != null) { | 84 | if (dashboard.getAssignedCustomers() != null) { |
83 | - this.assignedCustomers = objectMapper.valueToTree(dashboard.getAssignedCustomers()); | 85 | + try { |
86 | + this.assignedCustomers = objectMapper.writeValueAsString(dashboard.getAssignedCustomers()); | ||
87 | + } catch (JsonProcessingException e) { | ||
88 | + log.error("Unable to serialize assigned customers to string!", e); | ||
89 | + } | ||
84 | } | 90 | } |
85 | this.configuration = dashboard.getConfiguration(); | 91 | this.configuration = dashboard.getConfiguration(); |
86 | } | 92 | } |
@@ -103,10 +109,10 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | @@ -103,10 +109,10 @@ public final class DashboardEntity extends BaseSqlEntity<Dashboard> implements S | ||
103 | dashboard.setTenantId(new TenantId(toUUID(tenantId))); | 109 | dashboard.setTenantId(new TenantId(toUUID(tenantId))); |
104 | } | 110 | } |
105 | dashboard.setTitle(title); | 111 | dashboard.setTitle(title); |
106 | - if (assignedCustomers != null) { | 112 | + if (!StringUtils.isEmpty(assignedCustomers)) { |
107 | try { | 113 | try { |
108 | - dashboard.setAssignedCustomers(objectMapper.treeToValue(assignedCustomers, HashMap.class)); | ||
109 | - } catch (JsonProcessingException e) { | 114 | + dashboard.setAssignedCustomers(objectMapper.readValue(assignedCustomers, assignedCustomersType)); |
115 | + } catch (IOException e) { | ||
110 | log.warn("Unable to parse assigned customers!", e); | 116 | log.warn("Unable to parse assigned customers!", e); |
111 | } | 117 | } |
112 | } | 118 | } |
@@ -17,14 +17,14 @@ package org.thingsboard.server.dao.model.sql; | @@ -17,14 +17,14 @@ package org.thingsboard.server.dao.model.sql; | ||
17 | 17 | ||
18 | import com.datastax.driver.core.utils.UUIDs; | 18 | import com.datastax.driver.core.utils.UUIDs; |
19 | import com.fasterxml.jackson.core.JsonProcessingException; | 19 | import com.fasterxml.jackson.core.JsonProcessingException; |
20 | -import com.fasterxml.jackson.databind.JsonNode; | 20 | +import com.fasterxml.jackson.databind.JavaType; |
21 | import com.fasterxml.jackson.databind.ObjectMapper; | 21 | import com.fasterxml.jackson.databind.ObjectMapper; |
22 | import lombok.Data; | 22 | import lombok.Data; |
23 | import lombok.EqualsAndHashCode; | 23 | import lombok.EqualsAndHashCode; |
24 | import lombok.extern.slf4j.Slf4j; | 24 | import lombok.extern.slf4j.Slf4j; |
25 | -import org.hibernate.annotations.Type; | 25 | +import org.springframework.util.StringUtils; |
26 | import org.thingsboard.server.common.data.DashboardInfo; | 26 | import org.thingsboard.server.common.data.DashboardInfo; |
27 | -import org.thingsboard.server.common.data.id.CustomerId; | 27 | +import org.thingsboard.server.common.data.ShortCustomerInfo; |
28 | import org.thingsboard.server.common.data.id.DashboardId; | 28 | import org.thingsboard.server.common.data.id.DashboardId; |
29 | import org.thingsboard.server.common.data.id.TenantId; | 29 | import org.thingsboard.server.common.data.id.TenantId; |
30 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 30 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
@@ -34,8 +34,8 @@ import org.thingsboard.server.dao.model.SearchTextEntity; | @@ -34,8 +34,8 @@ import org.thingsboard.server.dao.model.SearchTextEntity; | ||
34 | import javax.persistence.Column; | 34 | import javax.persistence.Column; |
35 | import javax.persistence.Entity; | 35 | import javax.persistence.Entity; |
36 | import javax.persistence.Table; | 36 | import javax.persistence.Table; |
37 | -import java.util.HashMap; | ||
38 | -import java.util.Set; | 37 | +import java.io.IOException; |
38 | +import java.util.HashSet; | ||
39 | 39 | ||
40 | @Data | 40 | @Data |
41 | @Slf4j | 41 | @Slf4j |
@@ -45,6 +45,8 @@ import java.util.Set; | @@ -45,6 +45,8 @@ import java.util.Set; | ||
45 | public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements SearchTextEntity<DashboardInfo> { | 45 | public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements SearchTextEntity<DashboardInfo> { |
46 | 46 | ||
47 | private static final ObjectMapper objectMapper = new ObjectMapper(); | 47 | private static final ObjectMapper objectMapper = new ObjectMapper(); |
48 | + private static final JavaType assignedCustomersType = | ||
49 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | ||
48 | 50 | ||
49 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) | 51 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) |
50 | private String tenantId; | 52 | private String tenantId; |
@@ -55,9 +57,8 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -55,9 +57,8 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
55 | @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) | 57 | @Column(name = ModelConstants.SEARCH_TEXT_PROPERTY) |
56 | private String searchText; | 58 | private String searchText; |
57 | 59 | ||
58 | - @Type(type = "json") | ||
59 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) | 60 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) |
60 | - private JsonNode assignedCustomers; | 61 | + private String assignedCustomers; |
61 | 62 | ||
62 | public DashboardInfoEntity() { | 63 | public DashboardInfoEntity() { |
63 | super(); | 64 | super(); |
@@ -72,7 +73,11 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -72,7 +73,11 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
72 | } | 73 | } |
73 | this.title = dashboardInfo.getTitle(); | 74 | this.title = dashboardInfo.getTitle(); |
74 | if (dashboardInfo.getAssignedCustomers() != null) { | 75 | if (dashboardInfo.getAssignedCustomers() != null) { |
75 | - this.assignedCustomers = objectMapper.valueToTree(dashboardInfo.getAssignedCustomers()); | 76 | + try { |
77 | + this.assignedCustomers = objectMapper.writeValueAsString(dashboardInfo.getAssignedCustomers()); | ||
78 | + } catch (JsonProcessingException e) { | ||
79 | + log.error("Unable to serialize assigned customers to string!", e); | ||
80 | + } | ||
76 | } | 81 | } |
77 | } | 82 | } |
78 | 83 | ||
@@ -98,10 +103,10 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -98,10 +103,10 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
98 | dashboardInfo.setTenantId(new TenantId(toUUID(tenantId))); | 103 | dashboardInfo.setTenantId(new TenantId(toUUID(tenantId))); |
99 | } | 104 | } |
100 | dashboardInfo.setTitle(title); | 105 | dashboardInfo.setTitle(title); |
101 | - if (assignedCustomers != null) { | 106 | + if (!StringUtils.isEmpty(assignedCustomers)) { |
102 | try { | 107 | try { |
103 | - dashboardInfo.setAssignedCustomers(objectMapper.treeToValue(assignedCustomers, HashMap.class)); | ||
104 | - } catch (JsonProcessingException e) { | 108 | + dashboardInfo.setAssignedCustomers(objectMapper.readValue(assignedCustomers, assignedCustomersType)); |
109 | + } catch (IOException e) { | ||
105 | log.warn("Unable to parse assigned customers!", e); | 110 | log.warn("Unable to parse assigned customers!", e); |
106 | } | 111 | } |
107 | } | 112 | } |
@@ -320,7 +320,7 @@ public abstract class BaseDashboardServiceTest extends AbstractServiceTest { | @@ -320,7 +320,7 @@ public abstract class BaseDashboardServiceTest extends AbstractServiceTest { | ||
320 | 320 | ||
321 | Assert.assertEquals(dashboards, loadedDashboards); | 321 | Assert.assertEquals(dashboards, loadedDashboards); |
322 | 322 | ||
323 | - dashboardService.unassignCustomerDashboards(tenantId, customerId); | 323 | + dashboardService.unassignCustomerDashboards(customerId); |
324 | 324 | ||
325 | pageLink = new TimePageLink(42); | 325 | pageLink = new TimePageLink(42); |
326 | pageData = dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink).get(); | 326 | pageData = dashboardService.findDashboardsByTenantIdAndCustomerId(tenantId, customerId, pageLink).get(); |
@@ -17,7 +17,7 @@ export default angular.module('thingsboard.api.dashboard', []) | @@ -17,7 +17,7 @@ export default angular.module('thingsboard.api.dashboard', []) | ||
17 | .factory('dashboardService', DashboardService).name; | 17 | .factory('dashboardService', DashboardService).name; |
18 | 18 | ||
19 | /*@ngInject*/ | 19 | /*@ngInject*/ |
20 | -function DashboardService($rootScope, $http, $q, $location, customerService) { | 20 | +function DashboardService($rootScope, $http, $q, $location, $filter) { |
21 | 21 | ||
22 | var stDiffPromise; | 22 | var stDiffPromise; |
23 | 23 | ||
@@ -37,7 +37,11 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -37,7 +37,11 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
37 | deleteDashboard: deleteDashboard, | 37 | deleteDashboard: deleteDashboard, |
38 | saveDashboard: saveDashboard, | 38 | saveDashboard: saveDashboard, |
39 | unassignDashboardFromCustomer: unassignDashboardFromCustomer, | 39 | unassignDashboardFromCustomer: unassignDashboardFromCustomer, |
40 | + updateDashboardCustomers: updateDashboardCustomers, | ||
41 | + addDashboardCustomers: addDashboardCustomers, | ||
42 | + removeDashboardCustomers: removeDashboardCustomers, | ||
40 | makeDashboardPublic: makeDashboardPublic, | 43 | makeDashboardPublic: makeDashboardPublic, |
44 | + makeDashboardPrivate: makeDashboardPrivate, | ||
41 | getPublicDashboardLink: getPublicDashboardLink | 45 | getPublicDashboardLink: getPublicDashboardLink |
42 | } | 46 | } |
43 | 47 | ||
@@ -56,14 +60,14 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -56,14 +60,14 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
56 | url += '&textOffset=' + pageLink.textOffset; | 60 | url += '&textOffset=' + pageLink.textOffset; |
57 | } | 61 | } |
58 | $http.get(url, config).then(function success(response) { | 62 | $http.get(url, config).then(function success(response) { |
59 | - deferred.resolve(response.data); | 63 | + deferred.resolve(prepareDashboards(response.data)); |
60 | }, function fail() { | 64 | }, function fail() { |
61 | deferred.reject(); | 65 | deferred.reject(); |
62 | }); | 66 | }); |
63 | return deferred.promise; | 67 | return deferred.promise; |
64 | } | 68 | } |
65 | 69 | ||
66 | - function getTenantDashboards(pageLink, applyCustomersInfo, config) { | 70 | + function getTenantDashboards(pageLink, config) { |
67 | var deferred = $q.defer(); | 71 | var deferred = $q.defer(); |
68 | var url = '/api/tenant/dashboards?limit=' + pageLink.limit; | 72 | var url = '/api/tenant/dashboards?limit=' + pageLink.limit; |
69 | if (angular.isDefined(pageLink.textSearch)) { | 73 | if (angular.isDefined(pageLink.textSearch)) { |
@@ -76,51 +80,25 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -76,51 +80,25 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
76 | url += '&textOffset=' + pageLink.textOffset; | 80 | url += '&textOffset=' + pageLink.textOffset; |
77 | } | 81 | } |
78 | $http.get(url, config).then(function success(response) { | 82 | $http.get(url, config).then(function success(response) { |
79 | - if (applyCustomersInfo) { | ||
80 | - customerService.applyAssignedCustomersInfo(response.data.data).then( | ||
81 | - function success(data) { | ||
82 | - response.data.data = data; | ||
83 | - deferred.resolve(response.data); | ||
84 | - }, | ||
85 | - function fail() { | ||
86 | - deferred.reject(); | ||
87 | - } | ||
88 | - ); | ||
89 | - } else { | ||
90 | - deferred.resolve(response.data); | ||
91 | - } | 83 | + deferred.resolve(prepareDashboards(response.data)); |
92 | }, function fail() { | 84 | }, function fail() { |
93 | deferred.reject(); | 85 | deferred.reject(); |
94 | }); | 86 | }); |
95 | return deferred.promise; | 87 | return deferred.promise; |
96 | } | 88 | } |
97 | 89 | ||
98 | - function getCustomerDashboards(customerId, pageLink, applyCustomersInfo, config) { | 90 | + function getCustomerDashboards(customerId, pageLink, config) { |
99 | var deferred = $q.defer(); | 91 | var deferred = $q.defer(); |
100 | var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; | 92 | var url = '/api/customer/' + customerId + '/dashboards?limit=' + pageLink.limit; |
101 | - if (angular.isDefined(pageLink.textSearch)) { | ||
102 | - url += '&textSearch=' + pageLink.textSearch; | ||
103 | - } | ||
104 | if (angular.isDefined(pageLink.idOffset)) { | 93 | if (angular.isDefined(pageLink.idOffset)) { |
105 | - url += '&idOffset=' + pageLink.idOffset; | ||
106 | - } | ||
107 | - if (angular.isDefined(pageLink.textOffset)) { | ||
108 | - url += '&textOffset=' + pageLink.textOffset; | 94 | + url += '&offset=' + pageLink.idOffset; |
109 | } | 95 | } |
110 | $http.get(url, config).then(function success(response) { | 96 | $http.get(url, config).then(function success(response) { |
111 | - if (applyCustomersInfo) { | ||
112 | - customerService.applyAssignedCustomerInfo(response.data.data, customerId).then( | ||
113 | - function success(data) { | ||
114 | - response.data.data = data; | ||
115 | - deferred.resolve(response.data); | ||
116 | - }, | ||
117 | - function fail() { | ||
118 | - deferred.reject(); | ||
119 | - } | ||
120 | - ); | ||
121 | - } else { | ||
122 | - deferred.resolve(response.data); | 97 | + response.data = prepareDashboards(response.data); |
98 | + if (pageLink.textSearch) { | ||
99 | + response.data.data = $filter('filter')(response.data.data, {title: pageLink.textSearch}); | ||
123 | } | 100 | } |
101 | + deferred.resolve(response.data); | ||
124 | }, function fail() { | 102 | }, function fail() { |
125 | deferred.reject(); | 103 | deferred.reject(); |
126 | }); | 104 | }); |
@@ -151,7 +129,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -151,7 +129,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
151 | var deferred = $q.defer(); | 129 | var deferred = $q.defer(); |
152 | var url = '/api/dashboard/' + dashboardId; | 130 | var url = '/api/dashboard/' + dashboardId; |
153 | $http.get(url, null).then(function success(response) { | 131 | $http.get(url, null).then(function success(response) { |
154 | - deferred.resolve(response.data); | 132 | + deferred.resolve(prepareDashboard(response.data)); |
155 | }, function fail() { | 133 | }, function fail() { |
156 | deferred.reject(); | 134 | deferred.reject(); |
157 | }); | 135 | }); |
@@ -162,7 +140,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -162,7 +140,7 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
162 | var deferred = $q.defer(); | 140 | var deferred = $q.defer(); |
163 | var url = '/api/dashboard/info/' + dashboardId; | 141 | var url = '/api/dashboard/info/' + dashboardId; |
164 | $http.get(url, config).then(function success(response) { | 142 | $http.get(url, config).then(function success(response) { |
165 | - deferred.resolve(response.data); | 143 | + deferred.resolve(prepareDashboard(response.data)); |
166 | }, function fail() { | 144 | }, function fail() { |
167 | deferred.reject(); | 145 | deferred.reject(); |
168 | }); | 146 | }); |
@@ -172,8 +150,8 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -172,8 +150,8 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
172 | function saveDashboard(dashboard) { | 150 | function saveDashboard(dashboard) { |
173 | var deferred = $q.defer(); | 151 | var deferred = $q.defer(); |
174 | var url = '/api/dashboard'; | 152 | var url = '/api/dashboard'; |
175 | - $http.post(url, dashboard).then(function success(response) { | ||
176 | - deferred.resolve(response.data); | 153 | + $http.post(url, cleanDashboard(dashboard)).then(function success(response) { |
154 | + deferred.resolve(prepareDashboard(response.data)); | ||
177 | }, function fail() { | 155 | }, function fail() { |
178 | deferred.reject(); | 156 | deferred.reject(); |
179 | }); | 157 | }); |
@@ -195,18 +173,51 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -195,18 +173,51 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
195 | var deferred = $q.defer(); | 173 | var deferred = $q.defer(); |
196 | var url = '/api/customer/' + customerId + '/dashboard/' + dashboardId; | 174 | var url = '/api/customer/' + customerId + '/dashboard/' + dashboardId; |
197 | $http.post(url, null).then(function success(response) { | 175 | $http.post(url, null).then(function success(response) { |
198 | - deferred.resolve(response.data); | 176 | + deferred.resolve(prepareDashboard(response.data)); |
199 | }, function fail() { | 177 | }, function fail() { |
200 | deferred.reject(); | 178 | deferred.reject(); |
201 | }); | 179 | }); |
202 | return deferred.promise; | 180 | return deferred.promise; |
203 | } | 181 | } |
204 | 182 | ||
205 | - function unassignDashboardFromCustomer(dashboardId) { | 183 | + function unassignDashboardFromCustomer(customerId, dashboardId) { |
206 | var deferred = $q.defer(); | 184 | var deferred = $q.defer(); |
207 | - var url = '/api/customer/dashboard/' + dashboardId; | 185 | + var url = '/api/customer/' + customerId + '/dashboard/' + dashboardId; |
208 | $http.delete(url).then(function success(response) { | 186 | $http.delete(url).then(function success(response) { |
209 | - deferred.resolve(response.data); | 187 | + deferred.resolve(prepareDashboard(response.data)); |
188 | + }, function fail() { | ||
189 | + deferred.reject(); | ||
190 | + }); | ||
191 | + return deferred.promise; | ||
192 | + } | ||
193 | + | ||
194 | + function updateDashboardCustomers(dashboardId, customerIds) { | ||
195 | + var deferred = $q.defer(); | ||
196 | + var url = '/api/dashboard/' + dashboardId + '/customers'; | ||
197 | + $http.post(url, customerIds).then(function success(response) { | ||
198 | + deferred.resolve(prepareDashboard(response.data)); | ||
199 | + }, function fail() { | ||
200 | + deferred.reject(); | ||
201 | + }); | ||
202 | + return deferred.promise; | ||
203 | + } | ||
204 | + | ||
205 | + function addDashboardCustomers(dashboardId, customerIds) { | ||
206 | + var deferred = $q.defer(); | ||
207 | + var url = '/api/dashboard/' + dashboardId + '/customers/add'; | ||
208 | + $http.post(url, customerIds).then(function success(response) { | ||
209 | + deferred.resolve(prepareDashboard(response.data)); | ||
210 | + }, function fail() { | ||
211 | + deferred.reject(); | ||
212 | + }); | ||
213 | + return deferred.promise; | ||
214 | + } | ||
215 | + | ||
216 | + function removeDashboardCustomers(dashboardId, customerIds) { | ||
217 | + var deferred = $q.defer(); | ||
218 | + var url = '/api/dashboard/' + dashboardId + '/customers/remove'; | ||
219 | + $http.post(url, customerIds).then(function success(response) { | ||
220 | + deferred.resolve(prepareDashboard(response.data)); | ||
210 | }, function fail() { | 221 | }, function fail() { |
211 | deferred.reject(); | 222 | deferred.reject(); |
212 | }); | 223 | }); |
@@ -217,7 +228,18 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -217,7 +228,18 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
217 | var deferred = $q.defer(); | 228 | var deferred = $q.defer(); |
218 | var url = '/api/customer/public/dashboard/' + dashboardId; | 229 | var url = '/api/customer/public/dashboard/' + dashboardId; |
219 | $http.post(url, null).then(function success(response) { | 230 | $http.post(url, null).then(function success(response) { |
220 | - deferred.resolve(response.data); | 231 | + deferred.resolve(prepareDashboard(response.data)); |
232 | + }, function fail() { | ||
233 | + deferred.reject(); | ||
234 | + }); | ||
235 | + return deferred.promise; | ||
236 | + } | ||
237 | + | ||
238 | + function makeDashboardPrivate(dashboardId) { | ||
239 | + var deferred = $q.defer(); | ||
240 | + var url = '/api/customer/public/dashboard/' + dashboardId; | ||
241 | + $http.delete(url).then(function success(response) { | ||
242 | + deferred.resolve(prepareDashboard(response.data)); | ||
221 | }, function fail() { | 243 | }, function fail() { |
222 | deferred.reject(); | 244 | deferred.reject(); |
223 | }); | 245 | }); |
@@ -230,8 +252,44 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | @@ -230,8 +252,44 @@ function DashboardService($rootScope, $http, $q, $location, customerService) { | ||
230 | if (port != 80 && port != 443) { | 252 | if (port != 80 && port != 443) { |
231 | url += ":" + port; | 253 | url += ":" + port; |
232 | } | 254 | } |
233 | - url += "/dashboards/" + dashboard.id.id + "?publicId=" + dashboard.customerId.id; | 255 | + url += "/dashboards/" + dashboard.id.id + "?publicId=" + dashboard.publicCustomerId; |
234 | return url; | 256 | return url; |
235 | } | 257 | } |
236 | 258 | ||
259 | + function prepareDashboards(dashboardsData) { | ||
260 | + if (dashboardsData.data) { | ||
261 | + for (var i = 0; i < dashboardsData.data.length; i++) { | ||
262 | + dashboardsData.data[i] = prepareDashboard(dashboardsData.data[i]); | ||
263 | + } | ||
264 | + } | ||
265 | + return dashboardsData; | ||
266 | + } | ||
267 | + | ||
268 | + function prepareDashboard(dashboard) { | ||
269 | + dashboard.publicCustomerId = null; | ||
270 | + dashboard.assignedCustomersText = ""; | ||
271 | + dashboard.assignedCustomersIds = []; | ||
272 | + if (dashboard.assignedCustomers && dashboard.assignedCustomers.length) { | ||
273 | + var assignedCustomersTitles = []; | ||
274 | + for (var i = 0; i < dashboard.assignedCustomers.length; i++) { | ||
275 | + var assignedCustomer = dashboard.assignedCustomers[i]; | ||
276 | + dashboard.assignedCustomersIds.push(assignedCustomer.customerId.id); | ||
277 | + if (assignedCustomer.public) { | ||
278 | + dashboard.publicCustomerId = assignedCustomer.customerId.id; | ||
279 | + } else { | ||
280 | + assignedCustomersTitles.push(assignedCustomer.title); | ||
281 | + } | ||
282 | + } | ||
283 | + dashboard.assignedCustomersText = assignedCustomersTitles.join(', '); | ||
284 | + } | ||
285 | + return dashboard; | ||
286 | + } | ||
287 | + | ||
288 | + function cleanDashboard(dashboard) { | ||
289 | + delete dashboard.publicCustomerId; | ||
290 | + delete dashboard.assignedCustomersText; | ||
291 | + delete dashboard.assignedCustomersIds; | ||
292 | + return dashboard; | ||
293 | + } | ||
294 | + | ||
237 | } | 295 | } |
@@ -273,9 +273,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -273,9 +273,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
273 | break; | 273 | break; |
274 | case types.entityType.dashboard: | 274 | case types.entityType.dashboard: |
275 | if (user.authority === 'CUSTOMER_USER') { | 275 | if (user.authority === 'CUSTOMER_USER') { |
276 | - promise = dashboardService.getCustomerDashboards(customerId, pageLink, false, config); | 276 | + promise = dashboardService.getCustomerDashboards(customerId, pageLink, config); |
277 | } else { | 277 | } else { |
278 | - promise = dashboardService.getTenantDashboards(pageLink, false, config); | 278 | + promise = dashboardService.getTenantDashboards(pageLink, config); |
279 | } | 279 | } |
280 | break; | 280 | break; |
281 | case types.entityType.user: | 281 | case types.entityType.user: |
@@ -403,6 +403,21 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -403,6 +403,21 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
403 | return deferred.promise; | 403 | return deferred.promise; |
404 | } | 404 | } |
405 | 405 | ||
406 | + function resolveAliasEntityId(entityType, id) { | ||
407 | + var entityId = { | ||
408 | + entityType: entityType, | ||
409 | + id: id | ||
410 | + }; | ||
411 | + if (entityType == types.aliasEntityType.current_customer) { | ||
412 | + var user = userService.getCurrentUser(); | ||
413 | + entityId.entityType = types.entityType.customer; | ||
414 | + if (user.authority === 'CUSTOMER_USER') { | ||
415 | + entityId.id = user.customerId; | ||
416 | + } | ||
417 | + } | ||
418 | + return entityId; | ||
419 | + } | ||
420 | + | ||
406 | function getStateEntityId(filter, stateParams) { | 421 | function getStateEntityId(filter, stateParams) { |
407 | var entityId = null; | 422 | var entityId = null; |
408 | if (stateParams) { | 423 | if (stateParams) { |
@@ -417,6 +432,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -417,6 +432,9 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
417 | if (!entityId) { | 432 | if (!entityId) { |
418 | entityId = filter.defaultStateEntity; | 433 | entityId = filter.defaultStateEntity; |
419 | } | 434 | } |
435 | + if (entityId) { | ||
436 | + entityId = resolveAliasEntityId(entityId.entityType, entityId.id); | ||
437 | + } | ||
420 | return entityId; | 438 | return entityId; |
421 | } | 439 | } |
422 | 440 | ||
@@ -432,7 +450,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -432,7 +450,8 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
432 | var stateEntityId = getStateEntityId(filter, stateParams); | 450 | var stateEntityId = getStateEntityId(filter, stateParams); |
433 | switch (filter.type) { | 451 | switch (filter.type) { |
434 | case types.aliasFilterType.singleEntity.value: | 452 | case types.aliasFilterType.singleEntity.value: |
435 | - getEntity(filter.singleEntity.entityType, filter.singleEntity.id, {ignoreLoading: true}).then( | 453 | + var aliasEntityId = resolveAliasEntityId(filter.singleEntity.entityType, filter.singleEntity.id); |
454 | + getEntity(aliasEntityId.entityType, aliasEntityId.id, {ignoreLoading: true}).then( | ||
436 | function success(entity) { | 455 | function success(entity) { |
437 | result.entities = entitiesToEntitiesInfo([entity]); | 456 | result.entities = entitiesToEntitiesInfo([entity]); |
438 | deferred.resolve(result); | 457 | deferred.resolve(result); |
@@ -530,10 +549,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -530,10 +549,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
530 | rootEntityId = filter.rootEntity.id; | 549 | rootEntityId = filter.rootEntity.id; |
531 | } | 550 | } |
532 | if (rootEntityType && rootEntityId) { | 551 | if (rootEntityType && rootEntityId) { |
552 | + var relationQueryRootEntityId = resolveAliasEntityId(rootEntityType, rootEntityId); | ||
533 | var searchQuery = { | 553 | var searchQuery = { |
534 | parameters: { | 554 | parameters: { |
535 | - rootId: rootEntityId, | ||
536 | - rootType: rootEntityType, | 555 | + rootId: relationQueryRootEntityId.id, |
556 | + rootType: relationQueryRootEntityId.entityType, | ||
537 | direction: filter.direction | 557 | direction: filter.direction |
538 | }, | 558 | }, |
539 | filters: filter.filters | 559 | filters: filter.filters |
@@ -571,10 +591,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -571,10 +591,11 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
571 | rootEntityId = filter.rootEntity.id; | 591 | rootEntityId = filter.rootEntity.id; |
572 | } | 592 | } |
573 | if (rootEntityType && rootEntityId) { | 593 | if (rootEntityType && rootEntityId) { |
594 | + var searchQueryRootEntityId = resolveAliasEntityId(rootEntityType, rootEntityId); | ||
574 | searchQuery = { | 595 | searchQuery = { |
575 | parameters: { | 596 | parameters: { |
576 | - rootId: rootEntityId, | ||
577 | - rootType: rootEntityType, | 597 | + rootId: searchQueryRootEntityId.id, |
598 | + rootType: searchQueryRootEntityId.entityType, | ||
578 | direction: filter.direction | 599 | direction: filter.direction |
579 | }, | 600 | }, |
580 | relationType: filter.relationType | 601 | relationType: filter.relationType |
@@ -709,7 +730,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -709,7 +730,7 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
709 | return result; | 730 | return result; |
710 | } | 731 | } |
711 | 732 | ||
712 | - function prepareAllowedEntityTypesList(allowedEntityTypes) { | 733 | + function prepareAllowedEntityTypesList(allowedEntityTypes, useAliasEntityTypes) { |
713 | var authority = userService.getAuthority(); | 734 | var authority = userService.getAuthority(); |
714 | var entityTypes = {}; | 735 | var entityTypes = {}; |
715 | switch(authority) { | 736 | switch(authority) { |
@@ -726,12 +747,18 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | @@ -726,12 +747,18 @@ function EntityService($http, $q, $filter, $translate, $log, userService, device | ||
726 | entityTypes.rule = types.entityType.rule; | 747 | entityTypes.rule = types.entityType.rule; |
727 | entityTypes.plugin = types.entityType.plugin; | 748 | entityTypes.plugin = types.entityType.plugin; |
728 | entityTypes.dashboard = types.entityType.dashboard; | 749 | entityTypes.dashboard = types.entityType.dashboard; |
750 | + if (useAliasEntityTypes) { | ||
751 | + entityTypes.current_customer = types.aliasEntityType.current_customer; | ||
752 | + } | ||
729 | break; | 753 | break; |
730 | case 'CUSTOMER_USER': | 754 | case 'CUSTOMER_USER': |
731 | entityTypes.device = types.entityType.device; | 755 | entityTypes.device = types.entityType.device; |
732 | entityTypes.asset = types.entityType.asset; | 756 | entityTypes.asset = types.entityType.asset; |
733 | entityTypes.customer = types.entityType.customer; | 757 | entityTypes.customer = types.entityType.customer; |
734 | entityTypes.dashboard = types.entityType.dashboard; | 758 | entityTypes.dashboard = types.entityType.dashboard; |
759 | + if (useAliasEntityTypes) { | ||
760 | + entityTypes.current_customer = types.aliasEntityType.current_customer; | ||
761 | + } | ||
735 | break; | 762 | break; |
736 | } | 763 | } |
737 | 764 |
@@ -266,9 +266,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi | @@ -266,9 +266,9 @@ function UserService($http, $q, $rootScope, adminService, dashboardService, logi | ||
266 | var pageLink = {limit: 100}; | 266 | var pageLink = {limit: 100}; |
267 | var fetchDashboardsPromise; | 267 | var fetchDashboardsPromise; |
268 | if (currentUser.authority === 'TENANT_ADMIN') { | 268 | if (currentUser.authority === 'TENANT_ADMIN') { |
269 | - fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink, false); | 269 | + fetchDashboardsPromise = dashboardService.getTenantDashboards(pageLink); |
270 | } else { | 270 | } else { |
271 | - fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink, false); | 271 | + fetchDashboardsPromise = dashboardService.getCustomerDashboards(currentUser.customerId, pageLink); |
272 | } | 272 | } |
273 | fetchDashboardsPromise.then( | 273 | fetchDashboardsPromise.then( |
274 | function success(result) { | 274 | function success(result) { |
@@ -296,6 +296,9 @@ export default angular.module('thingsboard.types', []) | @@ -296,6 +296,9 @@ export default angular.module('thingsboard.types', []) | ||
296 | dashboard: "DASHBOARD", | 296 | dashboard: "DASHBOARD", |
297 | alarm: "ALARM" | 297 | alarm: "ALARM" |
298 | }, | 298 | }, |
299 | + aliasEntityType: { | ||
300 | + current_customer: "CURRENT_CUSTOMER" | ||
301 | + }, | ||
299 | entityTypeTranslations: { | 302 | entityTypeTranslations: { |
300 | "DEVICE": { | 303 | "DEVICE": { |
301 | type: 'entity.type-device', | 304 | type: 'entity.type-device', |
@@ -350,6 +353,10 @@ export default angular.module('thingsboard.types', []) | @@ -350,6 +353,10 @@ export default angular.module('thingsboard.types', []) | ||
350 | typePlural: 'entity.type-alarms', | 353 | typePlural: 'entity.type-alarms', |
351 | list: 'entity.list-of-alarms', | 354 | list: 'entity.list-of-alarms', |
352 | nameStartsWith: 'entity.alarm-name-starts-with' | 355 | nameStartsWith: 'entity.alarm-name-starts-with' |
356 | + }, | ||
357 | + "CURRENT_CUSTOMER": { | ||
358 | + type: 'entity.type-current-customer', | ||
359 | + list: 'entity.type-current-customer' | ||
353 | } | 360 | } |
354 | }, | 361 | }, |
355 | entitySearchDirection: { | 362 | entitySearchDirection: { |
@@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | @@ -48,7 +48,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | ||
48 | var promise; | 48 | var promise; |
49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | if (scope.customerId) { | 50 | if (scope.customerId) { |
51 | - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); | 51 | + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, {ignoreLoading: true}); |
52 | } else { | 52 | } else { |
53 | promise = $q.when({data: []}); | 53 | promise = $q.when({data: []}); |
54 | } | 54 | } |
@@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | @@ -60,7 +60,7 @@ function DashboardAutocomplete($compile, $templateCache, $q, dashboardService, u | ||
60 | promise = $q.when({data: []}); | 60 | promise = $q.when({data: []}); |
61 | } | 61 | } |
62 | } else { | 62 | } else { |
63 | - promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); | 63 | + promise = dashboardService.getTenantDashboards(pageLink, {ignoreLoading: true}); |
64 | } | 64 | } |
65 | } | 65 | } |
66 | 66 |
@@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu | @@ -48,12 +48,12 @@ function DashboardSelect($compile, $templateCache, $q, $mdMedia, $mdPanel, $docu | ||
48 | var promise; | 48 | var promise; |
49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { | 49 | if (scope.dashboardsScope === 'customer' || userService.getAuthority() === 'CUSTOMER_USER') { |
50 | if (scope.customerId && scope.customerId != types.id.nullUid) { | 50 | if (scope.customerId && scope.customerId != types.id.nullUid) { |
51 | - promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, false, {ignoreLoading: true}); | 51 | + promise = dashboardService.getCustomerDashboards(scope.customerId, pageLink, {ignoreLoading: true}); |
52 | } else { | 52 | } else { |
53 | promise = $q.when({data: []}); | 53 | promise = $q.when({data: []}); |
54 | } | 54 | } |
55 | } else { | 55 | } else { |
56 | - promise = dashboardService.getTenantDashboards(pageLink, false, {ignoreLoading: true}); | 56 | + promise = dashboardService.getTenantDashboards(pageLink, {ignoreLoading: true}); |
57 | } | 57 | } |
58 | 58 | ||
59 | promise.then(function success(result) { | 59 | promise.then(function success(result) { |
@@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD | @@ -52,7 +52,7 @@ export default function AddDashboardsToCustomerController(dashboardService, $mdD | ||
52 | fetchMoreItems_: function () { | 52 | fetchMoreItems_: function () { |
53 | if (vm.dashboards.hasNext && !vm.dashboards.pending) { | 53 | if (vm.dashboards.hasNext && !vm.dashboards.pending) { |
54 | vm.dashboards.pending = true; | 54 | vm.dashboards.pending = true; |
55 | - dashboardService.getTenantDashboards(vm.dashboards.nextPageLink, false).then( | 55 | + dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then( |
56 | function success(dashboards) { | 56 | function success(dashboards) { |
57 | vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); | 57 | vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); |
58 | vm.dashboards.nextPageLink = dashboards.nextPageLink; | 58 | vm.dashboards.nextPageLink = dashboards.nextPageLink; |
ui/src/app/dashboard/assign-to-customer.controller.js
deleted
100644 → 0
1 | -/* | ||
2 | - * Copyright © 2016-2017 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 | -/*@ngInject*/ | ||
17 | -export default function AssignDashboardToCustomerController(customerService, dashboardService, $mdDialog, $q, dashboardIds, customers) { | ||
18 | - | ||
19 | - var vm = this; | ||
20 | - | ||
21 | - vm.customers = customers; | ||
22 | - vm.searchText = ''; | ||
23 | - | ||
24 | - vm.assign = assign; | ||
25 | - vm.cancel = cancel; | ||
26 | - vm.isCustomerSelected = isCustomerSelected; | ||
27 | - vm.hasData = hasData; | ||
28 | - vm.noData = noData; | ||
29 | - vm.searchCustomerTextUpdated = searchCustomerTextUpdated; | ||
30 | - vm.toggleCustomerSelection = toggleCustomerSelection; | ||
31 | - | ||
32 | - vm.theCustomers = { | ||
33 | - getItemAtIndex: function (index) { | ||
34 | - if (index > vm.customers.data.length) { | ||
35 | - vm.theCustomers.fetchMoreItems_(index); | ||
36 | - return null; | ||
37 | - } | ||
38 | - var item = vm.customers.data[index]; | ||
39 | - if (item) { | ||
40 | - item.indexNumber = index + 1; | ||
41 | - } | ||
42 | - return item; | ||
43 | - }, | ||
44 | - | ||
45 | - getLength: function () { | ||
46 | - if (vm.customers.hasNext) { | ||
47 | - return vm.customers.data.length + vm.customers.nextPageLink.limit; | ||
48 | - } else { | ||
49 | - return vm.customers.data.length; | ||
50 | - } | ||
51 | - }, | ||
52 | - | ||
53 | - fetchMoreItems_: function () { | ||
54 | - if (vm.customers.hasNext && !vm.customers.pending) { | ||
55 | - vm.customers.pending = true; | ||
56 | - customerService.getCustomers(vm.customers.nextPageLink).then( | ||
57 | - function success(customers) { | ||
58 | - vm.customers.data = vm.customers.data.concat(customers.data); | ||
59 | - vm.customers.nextPageLink = customers.nextPageLink; | ||
60 | - vm.customers.hasNext = customers.hasNext; | ||
61 | - if (vm.customers.hasNext) { | ||
62 | - vm.customers.nextPageLink.limit = vm.customers.pageSize; | ||
63 | - } | ||
64 | - vm.customers.pending = false; | ||
65 | - }, | ||
66 | - function fail() { | ||
67 | - vm.customers.hasNext = false; | ||
68 | - vm.customers.pending = false; | ||
69 | - }); | ||
70 | - } | ||
71 | - } | ||
72 | - }; | ||
73 | - | ||
74 | - function cancel () { | ||
75 | - $mdDialog.cancel(); | ||
76 | - } | ||
77 | - | ||
78 | - function assign () { | ||
79 | - var tasks = []; | ||
80 | - for (var dashboardId in dashboardIds) { | ||
81 | - tasks.push(dashboardService.assignDashboardToCustomer(vm.customers.selection.id.id, dashboardIds[dashboardId])); | ||
82 | - } | ||
83 | - $q.all(tasks).then(function () { | ||
84 | - $mdDialog.hide(); | ||
85 | - }); | ||
86 | - } | ||
87 | - | ||
88 | - function noData () { | ||
89 | - return vm.customers.data.length == 0 && !vm.customers.hasNext; | ||
90 | - } | ||
91 | - | ||
92 | - function hasData () { | ||
93 | - return vm.customers.data.length > 0; | ||
94 | - } | ||
95 | - | ||
96 | - function toggleCustomerSelection ($event, customer) { | ||
97 | - $event.stopPropagation(); | ||
98 | - if (vm.isCustomerSelected(customer)) { | ||
99 | - vm.customers.selection = null; | ||
100 | - } else { | ||
101 | - vm.customers.selection = customer; | ||
102 | - } | ||
103 | - } | ||
104 | - | ||
105 | - function isCustomerSelected (customer) { | ||
106 | - return vm.customers.selection != null && customer && | ||
107 | - customer.id.id === vm.customers.selection.id.id; | ||
108 | - } | ||
109 | - | ||
110 | - function searchCustomerTextUpdated () { | ||
111 | - vm.customers = { | ||
112 | - pageSize: vm.customers.pageSize, | ||
113 | - data: [], | ||
114 | - nextPageLink: { | ||
115 | - limit: vm.customers.pageSize, | ||
116 | - textSearch: vm.searchText | ||
117 | - }, | ||
118 | - selection: null, | ||
119 | - hasNext: true, | ||
120 | - pending: false | ||
121 | - }; | ||
122 | - } | ||
123 | -} |
ui/src/app/dashboard/dashboard-card.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 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 | + | ||
17 | +.tb-dashboard-assigned-customers { | ||
18 | + display: block; | ||
19 | + display: -webkit-box; | ||
20 | + height: 34px; | ||
21 | + overflow: hidden; | ||
22 | + text-overflow: ellipsis; | ||
23 | + -webkit-line-clamp: 2; | ||
24 | + -webkit-box-orient: vertical; | ||
25 | + margin-bottom: 4px; | ||
26 | +} | ||
27 | + |
@@ -15,6 +15,6 @@ | @@ -15,6 +15,6 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<div class="tb-small" ng-show="vm.isAssignedToCustomer()">{{'dashboard.assignedToCustomer' | translate}} '{{vm.item.assignedCustomer.title}}'</div> | ||
19 | -<div class="tb-small" ng-show="vm.isPublic()">{{'dashboard.public' | translate}}</div> | 18 | +<div class="tb-small tb-dashboard-assigned-customers" ng-show="vm.parentCtl.dashboardsScope === 'tenant' && vm.item.assignedCustomersText">{{'dashboard.assignedToCustomers' | translate}}: '{{vm.item.assignedCustomersText}}'</div> |
19 | +<div class="tb-small" ng-show="vm.parentCtl.dashboardsScope === 'tenant' && vm.item.publicCustomerId">{{'dashboard.public' | translate}}</div> | ||
20 | 20 |
@@ -19,24 +19,29 @@ | @@ -19,24 +19,29 @@ | ||
19 | ng-show="!isEdit && dashboardScope === 'tenant'" | 19 | ng-show="!isEdit && dashboardScope === 'tenant'" |
20 | class="md-raised md-primary">{{ 'dashboard.export' | translate }}</md-button> | 20 | class="md-raised md-primary">{{ 'dashboard.export' | translate }}</md-button> |
21 | <md-button ng-click="onMakePublic({event: $event})" | 21 | <md-button ng-click="onMakePublic({event: $event})" |
22 | - ng-show="!isEdit && dashboardScope === 'tenant' && !isAssignedToCustomer && !isPublic" | 22 | + ng-show="!isEdit && dashboardScope === 'tenant' && !dashboard.publicCustomerId" |
23 | class="md-raised md-primary">{{ 'dashboard.make-public' | translate }}</md-button> | 23 | class="md-raised md-primary">{{ 'dashboard.make-public' | translate }}</md-button> |
24 | -<md-button ng-click="onAssignToCustomer({event: $event})" | ||
25 | - ng-show="!isEdit && dashboardScope === 'tenant' && !isAssignedToCustomer" | ||
26 | - class="md-raised md-primary">{{ 'dashboard.assign-to-customer' | translate }}</md-button> | ||
27 | -<md-button ng-click="onUnassignFromCustomer({event: $event, isPublic: isPublic})" | ||
28 | - ng-show="!isEdit && (dashboardScope === 'customer' || dashboardScope === 'tenant') && isAssignedToCustomer" | ||
29 | - class="md-raised md-primary">{{ isPublic ? 'dashboard.make-private' : 'dashboard.unassign-from-customer' | translate }}</md-button> | 24 | +<md-button ng-click="onMakePrivate({event: $event})" |
25 | + ng-show="!isEdit && ((dashboardScope === 'tenant' && dashboard.publicCustomerId || | ||
26 | + dashboardScope === 'customer' && customerId == dashboard.publicCustomerId))" | ||
27 | + class="md-raised md-primary">{{ 'dashboard.make-private' | translate }}</md-button> | ||
28 | +<md-button ng-click="onManageAssignedCustomers({event: $event})" | ||
29 | + ng-show="!isEdit && dashboardScope === 'tenant'" | ||
30 | + class="md-raised md-primary">{{ 'dashboard.manage-assigned-customers' | translate }}</md-button> | ||
31 | +<md-button ng-click="onUnassignFromCustomer({event: $event})" | ||
32 | + ng-show="!isEdit && dashboardScope === 'customer' && customerId != dashboard.publicCustomerId" | ||
33 | + class="md-raised md-primary">{{ 'dashboard.unassign-from-customer' | translate }}</md-button> | ||
30 | <md-button ng-click="onDeleteDashboard({event: $event})" | 34 | <md-button ng-click="onDeleteDashboard({event: $event})" |
31 | ng-show="!isEdit && dashboardScope === 'tenant'" | 35 | ng-show="!isEdit && dashboardScope === 'tenant'" |
32 | class="md-raised md-primary">{{ 'dashboard.delete' | translate }}</md-button> | 36 | class="md-raised md-primary">{{ 'dashboard.delete' | translate }}</md-button> |
33 | <md-content class="md-padding" layout="column"> | 37 | <md-content class="md-padding" layout="column"> |
34 | <md-input-container class="md-block" | 38 | <md-input-container class="md-block" |
35 | - ng-show="!isEdit && isAssignedToCustomer && !isPublic && dashboardScope === 'tenant'"> | ||
36 | - <label translate>dashboard.assignedToCustomer</label> | ||
37 | - <input ng-model="assignedCustomer.title" disabled> | 39 | + ng-show="!isEdit && dashboard.assignedCustomersText && dashboardScope === 'tenant'"> |
40 | + <label translate>dashboard.assignedToCustomers</label> | ||
41 | + <input ng-model="dashboard.assignedCustomersText" disabled> | ||
38 | </md-input-container> | 42 | </md-input-container> |
39 | - <div layout="column" ng-show="!isEdit && isPublic && (dashboardScope === 'customer' || dashboardScope === 'tenant')"> | 43 | + <div layout="column" ng-show="!isEdit && ((dashboardScope === 'tenant' && dashboard.publicCustomerId || |
44 | + dashboardScope === 'customer' && customerId == dashboard.publicCustomerId))"> | ||
40 | <tb-social-share-panel style="padding-bottom: 10px;" | 45 | <tb-social-share-panel style="padding-bottom: 10px;" |
41 | share-title="{{ 'dashboard.socialshare-title' | translate:{dashboardTitle: dashboard.title} }}" | 46 | share-title="{{ 'dashboard.socialshare-title' | translate:{dashboardTitle: dashboard.title} }}" |
42 | share-text="{{ 'dashboard.socialshare-text' | translate:{dashboardTitle: dashboard.title} }}" | 47 | share-text="{{ 'dashboard.socialshare-text' | translate:{dashboardTitle: dashboard.title} }}" |
@@ -20,36 +20,17 @@ import dashboardFieldsetTemplate from './dashboard-fieldset.tpl.html'; | @@ -20,36 +20,17 @@ import dashboardFieldsetTemplate from './dashboard-fieldset.tpl.html'; | ||
20 | /* eslint-enable import/no-unresolved, import/default */ | 20 | /* eslint-enable import/no-unresolved, import/default */ |
21 | 21 | ||
22 | /*@ngInject*/ | 22 | /*@ngInject*/ |
23 | -export default function DashboardDirective($compile, $templateCache, $translate, types, toast, customerService, dashboardService) { | 23 | +export default function DashboardDirective($compile, $templateCache, $translate, types, toast, dashboardService) { |
24 | var linker = function (scope, element) { | 24 | var linker = function (scope, element) { |
25 | var template = $templateCache.get(dashboardFieldsetTemplate); | 25 | var template = $templateCache.get(dashboardFieldsetTemplate); |
26 | element.html(template); | 26 | element.html(template); |
27 | - | ||
28 | - scope.isAssignedToCustomer = false; | ||
29 | - scope.isPublic = false; | ||
30 | - scope.assignedCustomer = null; | ||
31 | scope.publicLink = null; | 27 | scope.publicLink = null; |
32 | - | ||
33 | scope.$watch('dashboard', function(newVal) { | 28 | scope.$watch('dashboard', function(newVal) { |
34 | if (newVal) { | 29 | if (newVal) { |
35 | - if (scope.dashboard.customerId && scope.dashboard.customerId.id !== types.id.nullUid) { | ||
36 | - scope.isAssignedToCustomer = true; | ||
37 | - customerService.getShortCustomerInfo(scope.dashboard.customerId.id).then( | ||
38 | - function success(customer) { | ||
39 | - scope.assignedCustomer = customer; | ||
40 | - scope.isPublic = customer.isPublic; | ||
41 | - if (scope.isPublic) { | ||
42 | - scope.publicLink = dashboardService.getPublicDashboardLink(scope.dashboard); | ||
43 | - } else { | ||
44 | - scope.publicLink = null; | ||
45 | - } | ||
46 | - } | ||
47 | - ); | 30 | + if (scope.dashboard.publicCustomerId) { |
31 | + scope.publicLink = dashboardService.getPublicDashboardLink(scope.dashboard); | ||
48 | } else { | 32 | } else { |
49 | - scope.isAssignedToCustomer = false; | ||
50 | - scope.isPublic = false; | ||
51 | scope.publicLink = null; | 33 | scope.publicLink = null; |
52 | - scope.assignedCustomer = null; | ||
53 | } | 34 | } |
54 | } | 35 | } |
55 | }); | 36 | }); |
@@ -66,10 +47,12 @@ export default function DashboardDirective($compile, $templateCache, $translate, | @@ -66,10 +47,12 @@ export default function DashboardDirective($compile, $templateCache, $translate, | ||
66 | scope: { | 47 | scope: { |
67 | dashboard: '=', | 48 | dashboard: '=', |
68 | isEdit: '=', | 49 | isEdit: '=', |
50 | + customerId: '=', | ||
69 | dashboardScope: '=', | 51 | dashboardScope: '=', |
70 | theForm: '=', | 52 | theForm: '=', |
71 | - onAssignToCustomer: '&', | ||
72 | onMakePublic: '&', | 53 | onMakePublic: '&', |
54 | + onMakePrivate: '&', | ||
55 | + onManageAssignedCustomers: '&', | ||
73 | onUnassignFromCustomer: '&', | 56 | onUnassignFromCustomer: '&', |
74 | onExportDashboard: '&', | 57 | onExportDashboard: '&', |
75 | onDeleteDashboard: '&' | 58 | onDeleteDashboard: '&' |
@@ -17,12 +17,14 @@ | @@ -17,12 +17,14 @@ | ||
17 | 17 | ||
18 | import addDashboardTemplate from './add-dashboard.tpl.html'; | 18 | import addDashboardTemplate from './add-dashboard.tpl.html'; |
19 | import dashboardCard from './dashboard-card.tpl.html'; | 19 | import dashboardCard from './dashboard-card.tpl.html'; |
20 | -import assignToCustomerTemplate from './assign-to-customer.tpl.html'; | ||
21 | import addDashboardsToCustomerTemplate from './add-dashboards-to-customer.tpl.html'; | 20 | import addDashboardsToCustomerTemplate from './add-dashboards-to-customer.tpl.html'; |
22 | import makeDashboardPublicDialogTemplate from './make-dashboard-public-dialog.tpl.html'; | 21 | import makeDashboardPublicDialogTemplate from './make-dashboard-public-dialog.tpl.html'; |
22 | +import manageAssignedCustomersTemplate from './manage-assigned-customers.tpl.html'; | ||
23 | 23 | ||
24 | /* eslint-enable import/no-unresolved, import/default */ | 24 | /* eslint-enable import/no-unresolved, import/default */ |
25 | 25 | ||
26 | +import './dashboard-card.scss'; | ||
27 | + | ||
26 | /*@ngInject*/ | 28 | /*@ngInject*/ |
27 | export function MakeDashboardPublicDialogController($mdDialog, $translate, toast, dashboardService, dashboard) { | 29 | export function MakeDashboardPublicDialogController($mdDialog, $translate, toast, dashboardService, dashboard) { |
28 | 30 | ||
@@ -48,23 +50,8 @@ export function MakeDashboardPublicDialogController($mdDialog, $translate, toast | @@ -48,23 +50,8 @@ export function MakeDashboardPublicDialogController($mdDialog, $translate, toast | ||
48 | export function DashboardCardController(types) { | 50 | export function DashboardCardController(types) { |
49 | 51 | ||
50 | var vm = this; | 52 | var vm = this; |
51 | - | ||
52 | vm.types = types; | 53 | vm.types = types; |
53 | 54 | ||
54 | - vm.isAssignedToCustomer = function() { | ||
55 | - if (vm.item && vm.item.customerId && vm.parentCtl.dashboardsScope === 'tenant' && | ||
56 | - vm.item.customerId.id != vm.types.id.nullUid && !vm.item.assignedCustomer.isPublic) { | ||
57 | - return true; | ||
58 | - } | ||
59 | - return false; | ||
60 | - } | ||
61 | - | ||
62 | - vm.isPublic = function() { | ||
63 | - if (vm.item && vm.item.assignedCustomer && vm.parentCtl.dashboardsScope === 'tenant' && vm.item.assignedCustomer.isPublic) { | ||
64 | - return true; | ||
65 | - } | ||
66 | - return false; | ||
67 | - } | ||
68 | } | 55 | } |
69 | 56 | ||
70 | /*@ngInject*/ | 57 | /*@ngInject*/ |
@@ -135,8 +122,9 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -135,8 +122,9 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
135 | 122 | ||
136 | vm.dashboardsScope = $state.$current.data.dashboardsType; | 123 | vm.dashboardsScope = $state.$current.data.dashboardsType; |
137 | 124 | ||
138 | - vm.assignToCustomer = assignToCustomer; | ||
139 | vm.makePublic = makePublic; | 125 | vm.makePublic = makePublic; |
126 | + vm.makePrivate = makePrivate; | ||
127 | + vm.manageAssignedCustomers = manageAssignedCustomers; | ||
140 | vm.unassignFromCustomer = unassignFromCustomer; | 128 | vm.unassignFromCustomer = unassignFromCustomer; |
141 | vm.exportDashboard = exportDashboard; | 129 | vm.exportDashboard = exportDashboard; |
142 | 130 | ||
@@ -155,6 +143,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -155,6 +143,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
155 | } | 143 | } |
156 | 144 | ||
157 | if (customerId) { | 145 | if (customerId) { |
146 | + vm.customerId = customerId; | ||
158 | vm.customerDashboardsTitle = $translate.instant('customer.dashboards'); | 147 | vm.customerDashboardsTitle = $translate.instant('customer.dashboards'); |
159 | customerService.getShortCustomerInfo(customerId).then( | 148 | customerService.getShortCustomerInfo(customerId).then( |
160 | function success(info) { | 149 | function success(info) { |
@@ -167,7 +156,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -167,7 +156,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
167 | 156 | ||
168 | if (vm.dashboardsScope === 'tenant') { | 157 | if (vm.dashboardsScope === 'tenant') { |
169 | fetchDashboardsFunction = function (pageLink) { | 158 | fetchDashboardsFunction = function (pageLink) { |
170 | - return dashboardService.getTenantDashboards(pageLink, true); | 159 | + return dashboardService.getTenantDashboards(pageLink); |
171 | }; | 160 | }; |
172 | deleteDashboardFunction = function (dashboardId) { | 161 | deleteDashboardFunction = function (dashboardId) { |
173 | return dashboardService.deleteDashboard(dashboardId); | 162 | return dashboardService.deleteDashboard(dashboardId); |
@@ -194,11 +183,33 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -194,11 +183,33 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
194 | details: function() { return $translate.instant('dashboard.make-public') }, | 183 | details: function() { return $translate.instant('dashboard.make-public') }, |
195 | icon: "share", | 184 | icon: "share", |
196 | isEnabled: function(dashboard) { | 185 | isEnabled: function(dashboard) { |
197 | - return dashboard && (!dashboard.customerId || dashboard.customerId.id === types.id.nullUid); | 186 | + return dashboard && !dashboard.publicCustomerId; |
198 | } | 187 | } |
199 | }); | 188 | }); |
200 | - | ||
201 | dashboardActionsList.push({ | 189 | dashboardActionsList.push({ |
190 | + onAction: function ($event, item) { | ||
191 | + makePrivate($event, item); | ||
192 | + }, | ||
193 | + name: function() { return $translate.instant('action.make-private') }, | ||
194 | + details: function() { return $translate.instant('dashboard.make-private') }, | ||
195 | + icon: "reply", | ||
196 | + isEnabled: function(dashboard) { | ||
197 | + return dashboard && dashboard.publicCustomerId; | ||
198 | + } | ||
199 | + }); | ||
200 | + dashboardActionsList.push({ | ||
201 | + onAction: function ($event, item) { | ||
202 | + manageAssignedCustomers($event, item); | ||
203 | + }, | ||
204 | + name: function() { return $translate.instant('action.assign') }, | ||
205 | + details: function() { return $translate.instant('dashboard.manage-assigned-customers') }, | ||
206 | + icon: "assignment_ind", | ||
207 | + isEnabled: function(dashboard) { | ||
208 | + return dashboard; | ||
209 | + } | ||
210 | + }); | ||
211 | + | ||
212 | + /*dashboardActionsList.push({ | ||
202 | onAction: function ($event, item) { | 213 | onAction: function ($event, item) { |
203 | assignToCustomer($event, [ item.id.id ]); | 214 | assignToCustomer($event, [ item.id.id ]); |
204 | }, | 215 | }, |
@@ -208,8 +219,8 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -208,8 +219,8 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
208 | isEnabled: function(dashboard) { | 219 | isEnabled: function(dashboard) { |
209 | return dashboard && (!dashboard.customerId || dashboard.customerId.id === types.id.nullUid); | 220 | return dashboard && (!dashboard.customerId || dashboard.customerId.id === types.id.nullUid); |
210 | } | 221 | } |
211 | - }); | ||
212 | - dashboardActionsList.push({ | 222 | + });*/ |
223 | + /*dashboardActionsList.push({ | ||
213 | onAction: function ($event, item) { | 224 | onAction: function ($event, item) { |
214 | unassignFromCustomer($event, item, false); | 225 | unassignFromCustomer($event, item, false); |
215 | }, | 226 | }, |
@@ -219,18 +230,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -219,18 +230,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
219 | isEnabled: function(dashboard) { | 230 | isEnabled: function(dashboard) { |
220 | return dashboard && dashboard.customerId && dashboard.customerId.id !== types.id.nullUid && !dashboard.assignedCustomer.isPublic; | 231 | return dashboard && dashboard.customerId && dashboard.customerId.id !== types.id.nullUid && !dashboard.assignedCustomer.isPublic; |
221 | } | 232 | } |
222 | - }); | ||
223 | - dashboardActionsList.push({ | ||
224 | - onAction: function ($event, item) { | ||
225 | - unassignFromCustomer($event, item, true); | ||
226 | - }, | ||
227 | - name: function() { return $translate.instant('action.make-private') }, | ||
228 | - details: function() { return $translate.instant('dashboard.make-private') }, | ||
229 | - icon: "reply", | ||
230 | - isEnabled: function(dashboard) { | ||
231 | - return dashboard && dashboard.customerId && dashboard.customerId.id !== types.id.nullUid && dashboard.assignedCustomer.isPublic; | ||
232 | - } | ||
233 | - }); | 233 | + });*/ |
234 | 234 | ||
235 | dashboardActionsList.push( | 235 | dashboardActionsList.push( |
236 | { | 236 | { |
@@ -246,7 +246,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -246,7 +246,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
246 | dashboardGroupActionsList.push( | 246 | dashboardGroupActionsList.push( |
247 | { | 247 | { |
248 | onAction: function ($event, items) { | 248 | onAction: function ($event, items) { |
249 | - assignDashboardsToCustomer($event, items); | 249 | + assignDashboardsToCustomers($event, items); |
250 | }, | 250 | }, |
251 | name: function() { return $translate.instant('dashboard.assign-dashboards') }, | 251 | name: function() { return $translate.instant('dashboard.assign-dashboards') }, |
252 | details: function(selectedCount) { | 252 | details: function(selectedCount) { |
@@ -255,6 +255,17 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -255,6 +255,17 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
255 | icon: "assignment_ind" | 255 | icon: "assignment_ind" |
256 | } | 256 | } |
257 | ); | 257 | ); |
258 | + dashboardGroupActionsList.push( | ||
259 | + { | ||
260 | + onAction: function ($event, items) { | ||
261 | + unassignDashboardsFromCustomers($event, items); | ||
262 | + }, | ||
263 | + name: function() { return $translate.instant('dashboard.unassign-dashboards') }, | ||
264 | + details: function(selectedCount) { | ||
265 | + return $translate.instant('dashboard.unassign-dashboards-action-text', {count: selectedCount}, "messageformat"); | ||
266 | + }, | ||
267 | + icon: "assignment_return" } | ||
268 | + ); | ||
258 | 269 | ||
259 | dashboardGroupActionsList.push( | 270 | dashboardGroupActionsList.push( |
260 | { | 271 | { |
@@ -290,10 +301,10 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -290,10 +301,10 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
290 | }); | 301 | }); |
291 | } else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') { | 302 | } else if (vm.dashboardsScope === 'customer' || vm.dashboardsScope === 'customer_user') { |
292 | fetchDashboardsFunction = function (pageLink) { | 303 | fetchDashboardsFunction = function (pageLink) { |
293 | - return dashboardService.getCustomerDashboards(customerId, pageLink, true); | 304 | + return dashboardService.getCustomerDashboards(customerId, pageLink); |
294 | }; | 305 | }; |
295 | deleteDashboardFunction = function (dashboardId) { | 306 | deleteDashboardFunction = function (dashboardId) { |
296 | - return dashboardService.unassignDashboardFromCustomer(dashboardId); | 307 | + return dashboardService.unassignDashboardFromCustomer(customerId, dashboardId); |
297 | }; | 308 | }; |
298 | refreshDashboardsParamsFunction = function () { | 309 | refreshDashboardsParamsFunction = function () { |
299 | return {"customerId": customerId, "topIndex": vm.topIndex}; | 310 | return {"customerId": customerId, "topIndex": vm.topIndex}; |
@@ -314,26 +325,27 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -314,26 +325,27 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
314 | dashboardActionsList.push( | 325 | dashboardActionsList.push( |
315 | { | 326 | { |
316 | onAction: function ($event, item) { | 327 | onAction: function ($event, item) { |
317 | - unassignFromCustomer($event, item, false); | 328 | + makePrivate($event, item); |
318 | }, | 329 | }, |
319 | - name: function() { return $translate.instant('action.unassign') }, | ||
320 | - details: function() { return $translate.instant('dashboard.unassign-from-customer') }, | ||
321 | - icon: "assignment_return", | 330 | + name: function() { return $translate.instant('action.make-private') }, |
331 | + details: function() { return $translate.instant('dashboard.make-private') }, | ||
332 | + icon: "reply", | ||
322 | isEnabled: function(dashboard) { | 333 | isEnabled: function(dashboard) { |
323 | - return dashboard && !dashboard.assignedCustomer.isPublic; | 334 | + return dashboard && customerId == dashboard.publicCustomerId; |
324 | } | 335 | } |
325 | } | 336 | } |
326 | ); | 337 | ); |
338 | + | ||
327 | dashboardActionsList.push( | 339 | dashboardActionsList.push( |
328 | { | 340 | { |
329 | onAction: function ($event, item) { | 341 | onAction: function ($event, item) { |
330 | - unassignFromCustomer($event, item, true); | 342 | + unassignFromCustomer($event, item, customerId); |
331 | }, | 343 | }, |
332 | - name: function() { return $translate.instant('action.make-private') }, | ||
333 | - details: function() { return $translate.instant('dashboard.make-private') }, | ||
334 | - icon: "reply", | 344 | + name: function() { return $translate.instant('action.unassign') }, |
345 | + details: function() { return $translate.instant('dashboard.unassign-from-customer') }, | ||
346 | + icon: "assignment_return", | ||
335 | isEnabled: function(dashboard) { | 347 | isEnabled: function(dashboard) { |
336 | - return dashboard && dashboard.assignedCustomer.isPublic; | 348 | + return dashboard && customerId != dashboard.publicCustomerId; |
337 | } | 349 | } |
338 | } | 350 | } |
339 | ); | 351 | ); |
@@ -341,7 +353,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -341,7 +353,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
341 | dashboardGroupActionsList.push( | 353 | dashboardGroupActionsList.push( |
342 | { | 354 | { |
343 | onAction: function ($event, items) { | 355 | onAction: function ($event, items) { |
344 | - unassignDashboardsFromCustomer($event, items); | 356 | + unassignDashboardsFromCustomer($event, items, customerId); |
345 | }, | 357 | }, |
346 | name: function() { return $translate.instant('dashboard.unassign-dashboards') }, | 358 | name: function() { return $translate.instant('dashboard.unassign-dashboards') }, |
347 | details: function(selectedCount) { | 359 | details: function(selectedCount) { |
@@ -351,7 +363,6 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -351,7 +363,6 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
351 | } | 363 | } |
352 | ); | 364 | ); |
353 | 365 | ||
354 | - | ||
355 | vm.dashboardGridConfig.addItemAction = { | 366 | vm.dashboardGridConfig.addItemAction = { |
356 | onAction: function ($event) { | 367 | onAction: function ($event) { |
357 | addDashboardsToCustomer($event); | 368 | addDashboardsToCustomer($event); |
@@ -428,39 +439,42 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -428,39 +439,42 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
428 | return deferred.promise; | 439 | return deferred.promise; |
429 | } | 440 | } |
430 | 441 | ||
431 | - function assignToCustomer($event, dashboardIds) { | 442 | + function manageAssignedCustomers($event, dashboard) { |
443 | + showManageAssignedCustomersDialog($event, [dashboard.id.id], 'manage', dashboard.assignedCustomersIds); | ||
444 | + } | ||
445 | + | ||
446 | + function assignDashboardsToCustomers($event, items) { | ||
447 | + var dashboardIds = []; | ||
448 | + for (var id in items.selections) { | ||
449 | + dashboardIds.push(id); | ||
450 | + } | ||
451 | + showManageAssignedCustomersDialog($event, dashboardIds, 'assign'); | ||
452 | + } | ||
453 | + | ||
454 | + function unassignDashboardsFromCustomers($event, items) { | ||
455 | + var dashboardIds = []; | ||
456 | + for (var id in items.selections) { | ||
457 | + dashboardIds.push(id); | ||
458 | + } | ||
459 | + showManageAssignedCustomersDialog($event, dashboardIds, 'unassign'); | ||
460 | + } | ||
461 | + | ||
462 | + function showManageAssignedCustomersDialog($event, dashboardIds, actionType, assignedCustomers) { | ||
432 | if ($event) { | 463 | if ($event) { |
433 | $event.stopPropagation(); | 464 | $event.stopPropagation(); |
434 | } | 465 | } |
435 | - var pageSize = 10; | ||
436 | - customerService.getCustomers({limit: pageSize, textSearch: ''}).then( | ||
437 | - function success(_customers) { | ||
438 | - var customers = { | ||
439 | - pageSize: pageSize, | ||
440 | - data: _customers.data, | ||
441 | - nextPageLink: _customers.nextPageLink, | ||
442 | - selection: null, | ||
443 | - hasNext: _customers.hasNext, | ||
444 | - pending: false | ||
445 | - }; | ||
446 | - if (customers.hasNext) { | ||
447 | - customers.nextPageLink.limit = pageSize; | ||
448 | - } | ||
449 | - $mdDialog.show({ | ||
450 | - controller: 'AssignDashboardToCustomerController', | ||
451 | - controllerAs: 'vm', | ||
452 | - templateUrl: assignToCustomerTemplate, | ||
453 | - locals: {dashboardIds: dashboardIds, customers: customers}, | ||
454 | - parent: angular.element($document[0].body), | ||
455 | - fullscreen: true, | ||
456 | - targetEvent: $event | ||
457 | - }).then(function () { | ||
458 | - vm.grid.refreshList(); | ||
459 | - }, function () { | ||
460 | - }); | ||
461 | - }, | ||
462 | - function fail() { | ||
463 | - }); | 466 | + $mdDialog.show({ |
467 | + controller: 'ManageAssignedCustomersController', | ||
468 | + controllerAs: 'vm', | ||
469 | + templateUrl: manageAssignedCustomersTemplate, | ||
470 | + locals: {actionType: actionType, dashboardIds: dashboardIds, assignedCustomers: assignedCustomers}, | ||
471 | + parent: angular.element($document[0].body), | ||
472 | + fullscreen: true, | ||
473 | + targetEvent: $event | ||
474 | + }).then(function () { | ||
475 | + vm.grid.refreshList(); | ||
476 | + }, function () { | ||
477 | + }); | ||
464 | } | 478 | } |
465 | 479 | ||
466 | function addDashboardsToCustomer($event) { | 480 | function addDashboardsToCustomer($event) { |
@@ -468,7 +482,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -468,7 +482,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
468 | $event.stopPropagation(); | 482 | $event.stopPropagation(); |
469 | } | 483 | } |
470 | var pageSize = 10; | 484 | var pageSize = 10; |
471 | - dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}, false).then( | 485 | + dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}).then( |
472 | function success(_dashboards) { | 486 | function success(_dashboards) { |
473 | var dashboards = { | 487 | var dashboards = { |
474 | pageSize: pageSize, | 488 | pageSize: pageSize, |
@@ -499,30 +513,13 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -499,30 +513,13 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
499 | }); | 513 | }); |
500 | } | 514 | } |
501 | 515 | ||
502 | - function assignDashboardsToCustomer($event, items) { | ||
503 | - var dashboardIds = []; | ||
504 | - for (var id in items.selections) { | ||
505 | - dashboardIds.push(id); | ||
506 | - } | ||
507 | - assignToCustomer($event, dashboardIds); | ||
508 | - } | ||
509 | - | ||
510 | - function unassignFromCustomer($event, dashboard, isPublic) { | 516 | + function unassignFromCustomer($event, dashboard, customerId) { |
511 | if ($event) { | 517 | if ($event) { |
512 | $event.stopPropagation(); | 518 | $event.stopPropagation(); |
513 | } | 519 | } |
514 | - var title; | ||
515 | - var content; | ||
516 | - var label; | ||
517 | - if (isPublic) { | ||
518 | - title = $translate.instant('dashboard.make-private-dashboard-title', {dashboardTitle: dashboard.title}); | ||
519 | - content = $translate.instant('dashboard.make-private-dashboard-text'); | ||
520 | - label = $translate.instant('dashboard.make-private-dashboard'); | ||
521 | - } else { | ||
522 | - title = $translate.instant('dashboard.unassign-dashboard-title', {dashboardTitle: dashboard.title}); | ||
523 | - content = $translate.instant('dashboard.unassign-dashboard-text'); | ||
524 | - label = $translate.instant('dashboard.unassign-dashboard'); | ||
525 | - } | 520 | + var title = $translate.instant('dashboard.unassign-dashboard-title', {dashboardTitle: dashboard.title}); |
521 | + var content = $translate.instant('dashboard.unassign-dashboard-text'); | ||
522 | + var label = $translate.instant('dashboard.unassign-dashboard'); | ||
526 | var confirm = $mdDialog.confirm() | 523 | var confirm = $mdDialog.confirm() |
527 | .targetEvent($event) | 524 | .targetEvent($event) |
528 | .title(title) | 525 | .title(title) |
@@ -531,7 +528,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -531,7 +528,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
531 | .cancel($translate.instant('action.no')) | 528 | .cancel($translate.instant('action.no')) |
532 | .ok($translate.instant('action.yes')); | 529 | .ok($translate.instant('action.yes')); |
533 | $mdDialog.show(confirm).then(function () { | 530 | $mdDialog.show(confirm).then(function () { |
534 | - dashboardService.unassignDashboardFromCustomer(dashboard.id.id).then(function success() { | 531 | + dashboardService.unassignDashboardFromCustomer(customerId, dashboard.id.id).then(function success() { |
535 | vm.grid.refreshList(); | 532 | vm.grid.refreshList(); |
536 | }); | 533 | }); |
537 | }); | 534 | }); |
@@ -556,12 +553,33 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -556,12 +553,33 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
556 | }); | 553 | }); |
557 | } | 554 | } |
558 | 555 | ||
556 | + function makePrivate($event, dashboard) { | ||
557 | + if ($event) { | ||
558 | + $event.stopPropagation(); | ||
559 | + } | ||
560 | + var title = $translate.instant('dashboard.make-private-dashboard-title', {dashboardTitle: dashboard.title}); | ||
561 | + var content = $translate.instant('dashboard.make-private-dashboard-text'); | ||
562 | + var label = $translate.instant('dashboard.make-private-dashboard'); | ||
563 | + var confirm = $mdDialog.confirm() | ||
564 | + .targetEvent($event) | ||
565 | + .title(title) | ||
566 | + .htmlContent(content) | ||
567 | + .ariaLabel(label) | ||
568 | + .cancel($translate.instant('action.no')) | ||
569 | + .ok($translate.instant('action.yes')); | ||
570 | + $mdDialog.show(confirm).then(function () { | ||
571 | + dashboardService.makeDashboardPrivate(dashboard.id.id).then(function success() { | ||
572 | + vm.grid.refreshList(); | ||
573 | + }); | ||
574 | + }); | ||
575 | + } | ||
576 | + | ||
559 | function exportDashboard($event, dashboard) { | 577 | function exportDashboard($event, dashboard) { |
560 | $event.stopPropagation(); | 578 | $event.stopPropagation(); |
561 | importExport.exportDashboard(dashboard.id.id); | 579 | importExport.exportDashboard(dashboard.id.id); |
562 | } | 580 | } |
563 | 581 | ||
564 | - function unassignDashboardsFromCustomer($event, items) { | 582 | + function unassignDashboardsFromCustomer($event, items, customerId) { |
565 | var confirm = $mdDialog.confirm() | 583 | var confirm = $mdDialog.confirm() |
566 | .targetEvent($event) | 584 | .targetEvent($event) |
567 | .title($translate.instant('dashboard.unassign-dashboards-title', {count: items.selectedCount}, 'messageformat')) | 585 | .title($translate.instant('dashboard.unassign-dashboards-title', {count: items.selectedCount}, 'messageformat')) |
@@ -572,7 +590,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -572,7 +590,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
572 | $mdDialog.show(confirm).then(function () { | 590 | $mdDialog.show(confirm).then(function () { |
573 | var tasks = []; | 591 | var tasks = []; |
574 | for (var id in items.selections) { | 592 | for (var id in items.selections) { |
575 | - tasks.push(dashboardService.unassignDashboardFromCustomer(id)); | 593 | + tasks.push(dashboardService.unassignDashboardFromCustomer(customerId, id)); |
576 | } | 594 | } |
577 | $q.all(tasks).then(function () { | 595 | $q.all(tasks).then(function () { |
578 | vm.grid.refreshList(); | 596 | vm.grid.refreshList(); |
@@ -25,10 +25,12 @@ | @@ -25,10 +25,12 @@ | ||
25 | <tb-dashboard-details dashboard="vm.grid.operatingItem()" | 25 | <tb-dashboard-details dashboard="vm.grid.operatingItem()" |
26 | is-edit="vm.grid.detailsConfig.isDetailsEditMode" | 26 | is-edit="vm.grid.detailsConfig.isDetailsEditMode" |
27 | dashboard-scope="vm.dashboardsScope" | 27 | dashboard-scope="vm.dashboardsScope" |
28 | + customer-id="vm.customerId" | ||
28 | the-form="vm.grid.detailsForm" | 29 | the-form="vm.grid.detailsForm" |
29 | - on-assign-to-customer="vm.assignToCustomer(event, [ vm.grid.detailsConfig.currentItem.id.id ])" | ||
30 | on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)" | 30 | on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)" |
31 | - on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)" | 31 | + on-make-private="vm.makePrivate(event, vm.grid.detailsConfig.currentItem)" |
32 | + on-manage-assigned-customers="vm.manageAssignedCustomers(event, vm.grid.detailsConfig.currentItem)" | ||
33 | + on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, vm.customerId)" | ||
32 | on-export-dashboard="vm.exportDashboard(event, vm.grid.detailsConfig.currentItem)" | 34 | on-export-dashboard="vm.exportDashboard(event, vm.grid.detailsConfig.currentItem)" |
33 | on-delete-dashboard="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-dashboard-details> | 35 | on-delete-dashboard="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-dashboard-details> |
34 | </md-tab> | 36 | </md-tab> |
@@ -40,8 +40,8 @@ import DashboardRoutes from './dashboard.routes'; | @@ -40,8 +40,8 @@ import DashboardRoutes from './dashboard.routes'; | ||
40 | import {DashboardsController, DashboardCardController, MakeDashboardPublicDialogController} from './dashboards.controller'; | 40 | import {DashboardsController, DashboardCardController, MakeDashboardPublicDialogController} from './dashboards.controller'; |
41 | import DashboardController from './dashboard.controller'; | 41 | import DashboardController from './dashboard.controller'; |
42 | import DashboardSettingsController from './dashboard-settings.controller'; | 42 | import DashboardSettingsController from './dashboard-settings.controller'; |
43 | -import AssignDashboardToCustomerController from './assign-to-customer.controller'; | ||
44 | import AddDashboardsToCustomerController from './add-dashboards-to-customer.controller'; | 43 | import AddDashboardsToCustomerController from './add-dashboards-to-customer.controller'; |
44 | +import ManageAssignedCustomersController from './manage-assigned-customers.controller'; | ||
45 | import AddWidgetController from './add-widget.controller'; | 45 | import AddWidgetController from './add-widget.controller'; |
46 | import DashboardDirective from './dashboard.directive'; | 46 | import DashboardDirective from './dashboard.directive'; |
47 | import EditWidgetDirective from './edit-widget.directive'; | 47 | import EditWidgetDirective from './edit-widget.directive'; |
@@ -74,8 +74,8 @@ export default angular.module('thingsboard.dashboard', [ | @@ -74,8 +74,8 @@ export default angular.module('thingsboard.dashboard', [ | ||
74 | .controller('MakeDashboardPublicDialogController', MakeDashboardPublicDialogController) | 74 | .controller('MakeDashboardPublicDialogController', MakeDashboardPublicDialogController) |
75 | .controller('DashboardController', DashboardController) | 75 | .controller('DashboardController', DashboardController) |
76 | .controller('DashboardSettingsController', DashboardSettingsController) | 76 | .controller('DashboardSettingsController', DashboardSettingsController) |
77 | - .controller('AssignDashboardToCustomerController', AssignDashboardToCustomerController) | ||
78 | .controller('AddDashboardsToCustomerController', AddDashboardsToCustomerController) | 77 | .controller('AddDashboardsToCustomerController', AddDashboardsToCustomerController) |
78 | + .controller('ManageAssignedCustomersController', ManageAssignedCustomersController) | ||
79 | .controller('AddWidgetController', AddWidgetController) | 79 | .controller('AddWidgetController', AddWidgetController) |
80 | .directive('tbDashboardDetails', DashboardDirective) | 80 | .directive('tbDashboardDetails', DashboardDirective) |
81 | .directive('tbEditWidget', EditWidgetDirective) | 81 | .directive('tbEditWidget', EditWidgetDirective) |
1 | +/* | ||
2 | + * Copyright © 2016-2017 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 | +/*@ngInject*/ | ||
17 | +export default function ManageAssignedCustomersController($mdDialog, $q, types, dashboardService, actionType, dashboardIds, assignedCustomers) { | ||
18 | + | ||
19 | + var vm = this; | ||
20 | + | ||
21 | + vm.types = types; | ||
22 | + vm.actionType = actionType; | ||
23 | + vm.dashboardIds = dashboardIds; | ||
24 | + vm.assignedCustomers = assignedCustomers; | ||
25 | + if (actionType != 'manage') { | ||
26 | + vm.assignedCustomers = []; | ||
27 | + } | ||
28 | + | ||
29 | + if (actionType == 'manage') { | ||
30 | + vm.titleText = 'dashboard.manage-assigned-customers'; | ||
31 | + vm.labelText = 'dashboard.assigned-customers'; | ||
32 | + vm.actionName = 'action.update'; | ||
33 | + } else if (actionType == 'assign') { | ||
34 | + vm.titleText = 'dashboard.assign-to-customers'; | ||
35 | + vm.labelText = 'dashboard.assign-to-customers-text'; | ||
36 | + vm.actionName = 'action.assign'; | ||
37 | + } else if (actionType == 'unassign') { | ||
38 | + vm.titleText = 'dashboard.unassign-from-customers'; | ||
39 | + vm.labelText = 'dashboard.unassign-from-customers-text'; | ||
40 | + vm.actionName = 'action.unassign'; | ||
41 | + } | ||
42 | + | ||
43 | + vm.submit = submit; | ||
44 | + vm.cancel = cancel; | ||
45 | + | ||
46 | + function cancel () { | ||
47 | + $mdDialog.cancel(); | ||
48 | + } | ||
49 | + | ||
50 | + function submit () { | ||
51 | + var tasks = []; | ||
52 | + for (var i=0;i<vm.dashboardIds.length;i++) { | ||
53 | + var dashboardId = vm.dashboardIds[i]; | ||
54 | + var promise; | ||
55 | + if (vm.actionType == 'manage') { | ||
56 | + promise = dashboardService.updateDashboardCustomers(dashboardId, vm.assignedCustomers); | ||
57 | + } else if (vm.actionType == 'assign') { | ||
58 | + promise = dashboardService.addDashboardCustomers(dashboardId, vm.assignedCustomers); | ||
59 | + } else if (vm.actionType == 'unassign') { | ||
60 | + promise = dashboardService.removeDashboardCustomers(dashboardId, vm.assignedCustomers); | ||
61 | + } | ||
62 | + tasks.push(promise); | ||
63 | + } | ||
64 | + $q.all(tasks).then(function () { | ||
65 | + $mdDialog.hide(); | ||
66 | + }); | ||
67 | + } | ||
68 | + | ||
69 | +} |
ui/src/app/dashboard/manage-assigned-customers.tpl.html
renamed from
ui/src/app/dashboard/assign-to-customer.tpl.html
@@ -15,11 +15,11 @@ | @@ -15,11 +15,11 @@ | ||
15 | limitations under the License. | 15 | limitations under the License. |
16 | 16 | ||
17 | --> | 17 | --> |
18 | -<md-dialog aria-label="{{ 'dashboard.assign-dashboard-to-customer' | translate }}"> | ||
19 | - <form name="theForm" ng-submit="vm.assign()"> | 18 | +<md-dialog aria-label="{{ vm.titleText | translate }}" style="width: 600px;"> |
19 | + <form name="theForm" ng-submit="vm.submit()"> | ||
20 | <md-toolbar> | 20 | <md-toolbar> |
21 | <div class="md-toolbar-tools"> | 21 | <div class="md-toolbar-tools"> |
22 | - <h2 translate>dashboard.assign-dashboard-to-customer</h2> | 22 | + <h2 translate>{{vm.titleText}}</h2> |
23 | <span flex></span> | 23 | <span flex></span> |
24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> | 24 | <md-button class="md-icon-button" ng-click="vm.cancel()"> |
25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> | 25 | <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> |
@@ -31,42 +31,17 @@ | @@ -31,42 +31,17 @@ | ||
31 | <md-dialog-content> | 31 | <md-dialog-content> |
32 | <div class="md-dialog-content"> | 32 | <div class="md-dialog-content"> |
33 | <fieldset> | 33 | <fieldset> |
34 | - <span translate>dashboard.assign-to-customer-text</span> | ||
35 | - <md-input-container class="md-block" style='margin-bottom: 0px;'> | ||
36 | - <label> </label> | ||
37 | - <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons"> | ||
38 | - search | ||
39 | - </md-icon> | ||
40 | - <input id="customer-search" autofocus ng-model="vm.searchText" | ||
41 | - ng-change="vm.searchCustomerTextUpdated()" | ||
42 | - placeholder="{{ 'common.enter-search' | translate }}"/> | ||
43 | - </md-input-container> | ||
44 | - <div style='min-height: 150px;'> | ||
45 | - <span translate layout-align="center center" | ||
46 | - style="text-transform: uppercase; display: flex; height: 150px;" | ||
47 | - class="md-subhead" | ||
48 | - ng-show="vm.noData()">customer.no-customers-text</span> | ||
49 | - <md-virtual-repeat-container ng-show="vm.hasData()" | ||
50 | - tb-scope-element="repeatContainer" md-top-index="vm.topIndex" flex | ||
51 | - style='min-height: 150px; width: 100%;'> | ||
52 | - <md-list> | ||
53 | - <md-list-item md-virtual-repeat="customer in vm.theCustomers" md-on-demand | ||
54 | - class="repeated-item" flex> | ||
55 | - <md-checkbox ng-click="vm.toggleCustomerSelection($event, customer)" | ||
56 | - aria-label="{{ 'item.selected' | translate }}" | ||
57 | - ng-checked="vm.isCustomerSelected(customer)"></md-checkbox> | ||
58 | - <span> {{ customer.title }} </span> | ||
59 | - </md-list-item> | ||
60 | - </md-list> | ||
61 | - </md-virtual-repeat-container> | ||
62 | - </div> | 34 | + <span translate>{{vm.labelText}}</span> |
35 | + <tb-entity-list ng-disabled="$root.loading" | ||
36 | + ng-model="vm.assignedCustomers" | ||
37 | + entity-type="vm.types.entityType.customer"></tb-entity-list> | ||
63 | </fieldset> | 38 | </fieldset> |
64 | </div> | 39 | </div> |
65 | </md-dialog-content> | 40 | </md-dialog-content> |
66 | <md-dialog-actions layout="row"> | 41 | <md-dialog-actions layout="row"> |
67 | <span flex></span> | 42 | <span flex></span> |
68 | - <md-button ng-disabled="$root.loading || vm.customers.selection==null" type="submit" class="md-raised md-primary"> | ||
69 | - {{ 'action.assign' | translate }} | 43 | + <md-button ng-disabled="$root.loading || !theForm.$dirty || !theForm.$valid" type="submit" class="md-raised md-primary"> |
44 | + {{ vm.actionName | translate }} | ||
70 | </md-button> | 45 | </md-button> |
71 | <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | 46 | <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | |
72 | translate }} | 47 | translate }} |
@@ -38,7 +38,12 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | @@ -38,7 +38,12 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | ||
38 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { | 38 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { |
39 | limit += scope.excludeEntityIds.length; | 39 | limit += scope.excludeEntityIds.length; |
40 | } | 40 | } |
41 | - entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit, {ignoreLoading: true}, scope.entitySubtype).then(function success(result) { | 41 | + var targetType = scope.entityType; |
42 | + if (targetType == types.aliasEntityType.current_customer) { | ||
43 | + targetType = types.entityType.customer; | ||
44 | + } | ||
45 | + | ||
46 | + entityService.getEntitiesByNameFilter(targetType, searchText, limit, {ignoreLoading: true}, scope.entitySubtype).then(function success(result) { | ||
42 | if (result) { | 47 | if (result) { |
43 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { | 48 | if (scope.excludeEntityIds && scope.excludeEntityIds.length) { |
44 | var entities = []; | 49 | var entities = []; |
@@ -71,7 +76,11 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | @@ -71,7 +76,11 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | ||
71 | 76 | ||
72 | ngModelCtrl.$render = function () { | 77 | ngModelCtrl.$render = function () { |
73 | if (ngModelCtrl.$viewValue) { | 78 | if (ngModelCtrl.$viewValue) { |
74 | - entityService.getEntity(scope.entityType, ngModelCtrl.$viewValue).then( | 79 | + var targetType = scope.entityType; |
80 | + if (targetType == types.aliasEntityType.current_customer) { | ||
81 | + targetType = types.entityType.customer; | ||
82 | + } | ||
83 | + entityService.getEntity(targetType, ngModelCtrl.$viewValue).then( | ||
75 | function success(entity) { | 84 | function success(entity) { |
76 | scope.entity = entity; | 85 | scope.entity = entity; |
77 | }, | 86 | }, |
@@ -114,55 +123,61 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | @@ -114,55 +123,61 @@ export default function EntityAutocomplete($compile, $templateCache, $q, $filter | ||
114 | scope.selectEntityText = 'asset.select-asset'; | 123 | scope.selectEntityText = 'asset.select-asset'; |
115 | scope.entityText = 'asset.asset'; | 124 | scope.entityText = 'asset.asset'; |
116 | scope.noEntitiesMatchingText = 'asset.no-assets-matching'; | 125 | scope.noEntitiesMatchingText = 'asset.no-assets-matching'; |
117 | - scope.entityRequiredText = 'asset.asset-required' | 126 | + scope.entityRequiredText = 'asset.asset-required'; |
118 | break; | 127 | break; |
119 | case types.entityType.device: | 128 | case types.entityType.device: |
120 | scope.selectEntityText = 'device.select-device'; | 129 | scope.selectEntityText = 'device.select-device'; |
121 | scope.entityText = 'device.device'; | 130 | scope.entityText = 'device.device'; |
122 | scope.noEntitiesMatchingText = 'device.no-devices-matching'; | 131 | scope.noEntitiesMatchingText = 'device.no-devices-matching'; |
123 | - scope.entityRequiredText = 'device.device-required' | 132 | + scope.entityRequiredText = 'device.device-required'; |
124 | break; | 133 | break; |
125 | case types.entityType.rule: | 134 | case types.entityType.rule: |
126 | scope.selectEntityText = 'rule.select-rule'; | 135 | scope.selectEntityText = 'rule.select-rule'; |
127 | scope.entityText = 'rule.rule'; | 136 | scope.entityText = 'rule.rule'; |
128 | scope.noEntitiesMatchingText = 'rule.no-rules-matching'; | 137 | scope.noEntitiesMatchingText = 'rule.no-rules-matching'; |
129 | - scope.entityRequiredText = 'rule.rule-required' | 138 | + scope.entityRequiredText = 'rule.rule-required'; |
130 | break; | 139 | break; |
131 | case types.entityType.plugin: | 140 | case types.entityType.plugin: |
132 | scope.selectEntityText = 'plugin.select-plugin'; | 141 | scope.selectEntityText = 'plugin.select-plugin'; |
133 | scope.entityText = 'plugin.plugin'; | 142 | scope.entityText = 'plugin.plugin'; |
134 | scope.noEntitiesMatchingText = 'plugin.no-plugins-matching'; | 143 | scope.noEntitiesMatchingText = 'plugin.no-plugins-matching'; |
135 | - scope.entityRequiredText = 'plugin.plugin-required' | 144 | + scope.entityRequiredText = 'plugin.plugin-required'; |
136 | break; | 145 | break; |
137 | case types.entityType.tenant: | 146 | case types.entityType.tenant: |
138 | scope.selectEntityText = 'tenant.select-tenant'; | 147 | scope.selectEntityText = 'tenant.select-tenant'; |
139 | scope.entityText = 'tenant.tenant'; | 148 | scope.entityText = 'tenant.tenant'; |
140 | scope.noEntitiesMatchingText = 'tenant.no-tenants-matching'; | 149 | scope.noEntitiesMatchingText = 'tenant.no-tenants-matching'; |
141 | - scope.entityRequiredText = 'tenant.tenant-required' | 150 | + scope.entityRequiredText = 'tenant.tenant-required'; |
142 | break; | 151 | break; |
143 | case types.entityType.customer: | 152 | case types.entityType.customer: |
144 | scope.selectEntityText = 'customer.select-customer'; | 153 | scope.selectEntityText = 'customer.select-customer'; |
145 | scope.entityText = 'customer.customer'; | 154 | scope.entityText = 'customer.customer'; |
146 | scope.noEntitiesMatchingText = 'customer.no-customers-matching'; | 155 | scope.noEntitiesMatchingText = 'customer.no-customers-matching'; |
147 | - scope.entityRequiredText = 'customer.customer-required' | 156 | + scope.entityRequiredText = 'customer.customer-required'; |
148 | break; | 157 | break; |
149 | case types.entityType.user: | 158 | case types.entityType.user: |
150 | scope.selectEntityText = 'user.select-user'; | 159 | scope.selectEntityText = 'user.select-user'; |
151 | scope.entityText = 'user.user'; | 160 | scope.entityText = 'user.user'; |
152 | scope.noEntitiesMatchingText = 'user.no-users-matching'; | 161 | scope.noEntitiesMatchingText = 'user.no-users-matching'; |
153 | - scope.entityRequiredText = 'user.user-required' | 162 | + scope.entityRequiredText = 'user.user-required'; |
154 | break; | 163 | break; |
155 | case types.entityType.dashboard: | 164 | case types.entityType.dashboard: |
156 | scope.selectEntityText = 'dashboard.select-dashboard'; | 165 | scope.selectEntityText = 'dashboard.select-dashboard'; |
157 | scope.entityText = 'dashboard.dashboard'; | 166 | scope.entityText = 'dashboard.dashboard'; |
158 | scope.noEntitiesMatchingText = 'dashboard.no-dashboards-matching'; | 167 | scope.noEntitiesMatchingText = 'dashboard.no-dashboards-matching'; |
159 | - scope.entityRequiredText = 'dashboard.dashboard-required' | 168 | + scope.entityRequiredText = 'dashboard.dashboard-required'; |
160 | break; | 169 | break; |
161 | case types.entityType.alarm: | 170 | case types.entityType.alarm: |
162 | scope.selectEntityText = 'alarm.select-alarm'; | 171 | scope.selectEntityText = 'alarm.select-alarm'; |
163 | scope.entityText = 'alarm.alarm'; | 172 | scope.entityText = 'alarm.alarm'; |
164 | scope.noEntitiesMatchingText = 'alarm.no-alarms-matching'; | 173 | scope.noEntitiesMatchingText = 'alarm.no-alarms-matching'; |
165 | - scope.entityRequiredText = 'alarm.alarm-required' | 174 | + scope.entityRequiredText = 'alarm.alarm-required'; |
175 | + break; | ||
176 | + case types.aliasEntityType.current_customer: | ||
177 | + scope.selectEntityText = 'customer.select-default-customer'; | ||
178 | + scope.entityText = 'customer.default-customer'; | ||
179 | + scope.noEntitiesMatchingText = 'customer.no-customers-matching'; | ||
180 | + scope.entityRequiredText = 'customer.default-customer-required'; | ||
166 | break; | 181 | break; |
167 | } | 182 | } |
168 | if (scope.entity && scope.entity.id.entityType != scope.entityType) { | 183 | if (scope.entity && scope.entity.id.entityType != scope.entityType) { |
@@ -32,6 +32,7 @@ | @@ -32,6 +32,7 @@ | ||
32 | <tb-entity-select flex | 32 | <tb-entity-select flex |
33 | the-form="theForm" | 33 | the-form="theForm" |
34 | tb-required="true" | 34 | tb-required="true" |
35 | + use-alias-entity-types="true" | ||
35 | ng-model="filter.singleEntity"> | 36 | ng-model="filter.singleEntity"> |
36 | </tb-entity-select> | 37 | </tb-entity-select> |
37 | </section> | 38 | </section> |
@@ -78,6 +79,7 @@ | @@ -78,6 +79,7 @@ | ||
78 | <tb-entity-select flex | 79 | <tb-entity-select flex |
79 | the-form="theForm" | 80 | the-form="theForm" |
80 | tb-required="false" | 81 | tb-required="false" |
82 | + use-alias-entity-types="true" | ||
81 | ng-model="filter.defaultStateEntity"> | 83 | ng-model="filter.defaultStateEntity"> |
82 | </tb-entity-select> | 84 | </tb-entity-select> |
83 | </div> | 85 | </div> |
@@ -123,6 +125,7 @@ | @@ -123,6 +125,7 @@ | ||
123 | the-form="theForm" | 125 | the-form="theForm" |
124 | tb-required="!filter.rootStateEntity" | 126 | tb-required="!filter.rootStateEntity" |
125 | ng-disabled="filter.rootStateEntity" | 127 | ng-disabled="filter.rootStateEntity" |
128 | + use-alias-entity-types="true" | ||
126 | ng-model="filter.rootEntity"> | 129 | ng-model="filter.rootEntity"> |
127 | </tb-entity-select> | 130 | </tb-entity-select> |
128 | </div> | 131 | </div> |
@@ -139,6 +142,7 @@ | @@ -139,6 +142,7 @@ | ||
139 | <tb-entity-select flex | 142 | <tb-entity-select flex |
140 | the-form="theForm" | 143 | the-form="theForm" |
141 | tb-required="false" | 144 | tb-required="false" |
145 | + use-alias-entity-types="true" | ||
142 | ng-model="filter.defaultStateEntity"> | 146 | ng-model="filter.defaultStateEntity"> |
143 | </tb-entity-select> | 147 | </tb-entity-select> |
144 | </div> | 148 | </div> |
@@ -182,6 +186,7 @@ | @@ -182,6 +186,7 @@ | ||
182 | the-form="theForm" | 186 | the-form="theForm" |
183 | tb-required="!filter.rootStateEntity" | 187 | tb-required="!filter.rootStateEntity" |
184 | ng-disabled="filter.rootStateEntity" | 188 | ng-disabled="filter.rootStateEntity" |
189 | + use-alias-entity-types="true" | ||
185 | ng-model="filter.rootEntity"> | 190 | ng-model="filter.rootEntity"> |
186 | </tb-entity-select> | 191 | </tb-entity-select> |
187 | </div> | 192 | </div> |
@@ -198,6 +203,7 @@ | @@ -198,6 +203,7 @@ | ||
198 | <tb-entity-select flex | 203 | <tb-entity-select flex |
199 | the-form="theForm" | 204 | the-form="theForm" |
200 | tb-required="false" | 205 | tb-required="false" |
206 | + use-alias-entity-types="true" | ||
201 | ng-model="filter.defaultStateEntity"> | 207 | ng-model="filter.defaultStateEntity"> |
202 | </tb-entity-select> | 208 | </tb-entity-select> |
203 | </div> | 209 | </div> |
@@ -249,6 +255,7 @@ | @@ -249,6 +255,7 @@ | ||
249 | the-form="theForm" | 255 | the-form="theForm" |
250 | tb-required="!filter.rootStateEntity" | 256 | tb-required="!filter.rootStateEntity" |
251 | ng-disabled="filter.rootStateEntity" | 257 | ng-disabled="filter.rootStateEntity" |
258 | + use-alias-entity-types="true" | ||
252 | ng-model="filter.rootEntity"> | 259 | ng-model="filter.rootEntity"> |
253 | </tb-entity-select> | 260 | </tb-entity-select> |
254 | </div> | 261 | </div> |
@@ -265,6 +272,7 @@ | @@ -265,6 +272,7 @@ | ||
265 | <tb-entity-select flex | 272 | <tb-entity-select flex |
266 | the-form="theForm" | 273 | the-form="theForm" |
267 | tb-required="false" | 274 | tb-required="false" |
275 | + use-alias-entity-types="true" | ||
268 | ng-model="filter.defaultStateEntity"> | 276 | ng-model="filter.defaultStateEntity"> |
269 | </tb-entity-select> | 277 | </tb-entity-select> |
270 | </div> | 278 | </div> |
@@ -105,7 +105,8 @@ export default function EntitySelect($compile, $templateCache) { | @@ -105,7 +105,8 @@ export default function EntitySelect($compile, $templateCache) { | ||
105 | scope: { | 105 | scope: { |
106 | theForm: '=?', | 106 | theForm: '=?', |
107 | tbRequired: '=?', | 107 | tbRequired: '=?', |
108 | - disabled:'=ngDisabled' | 108 | + disabled:'=ngDisabled', |
109 | + useAliasEntityTypes: "=?" | ||
109 | } | 110 | } |
110 | }; | 111 | }; |
111 | } | 112 | } |
@@ -20,6 +20,7 @@ | @@ -20,6 +20,7 @@ | ||
20 | the-form="theForm" | 20 | the-form="theForm" |
21 | ng-disabled="disabled" | 21 | ng-disabled="disabled" |
22 | tb-required="tbRequired" | 22 | tb-required="tbRequired" |
23 | + use-alias-entity-types="useAliasEntityTypes" | ||
23 | ng-model="model.entityType"> | 24 | ng-model="model.entityType"> |
24 | </tb-entity-type-select> | 25 | </tb-entity-type-select> |
25 | <tb-entity-autocomplete flex ng-if="model.entityType" | 26 | <tb-entity-autocomplete flex ng-if="model.entityType" |
@@ -39,7 +39,7 @@ export default function EntityTypeSelect($compile, $templateCache, utils, entity | @@ -39,7 +39,7 @@ export default function EntityTypeSelect($compile, $templateCache, utils, entity | ||
39 | 39 | ||
40 | scope.ngModelCtrl = ngModelCtrl; | 40 | scope.ngModelCtrl = ngModelCtrl; |
41 | 41 | ||
42 | - scope.entityTypes = entityService.prepareAllowedEntityTypesList(scope.allowedEntityTypes); | 42 | + scope.entityTypes = entityService.prepareAllowedEntityTypesList(scope.allowedEntityTypes, scope.useAliasEntityTypes); |
43 | 43 | ||
44 | scope.typeName = function(type) { | 44 | scope.typeName = function(type) { |
45 | return type ? types.entityTypeTranslations[type].type : ''; | 45 | return type ? types.entityTypeTranslations[type].type : ''; |
@@ -79,7 +79,8 @@ export default function EntityTypeSelect($compile, $templateCache, utils, entity | @@ -79,7 +79,8 @@ export default function EntityTypeSelect($compile, $templateCache, utils, entity | ||
79 | theForm: '=?', | 79 | theForm: '=?', |
80 | tbRequired: '=?', | 80 | tbRequired: '=?', |
81 | disabled:'=ngDisabled', | 81 | disabled:'=ngDisabled', |
82 | - allowedEntityTypes: "=?" | 82 | + allowedEntityTypes: "=?", |
83 | + useAliasEntityTypes: "=?" | ||
83 | } | 84 | } |
84 | }; | 85 | }; |
85 | } | 86 | } |
@@ -540,7 +540,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -540,7 +540,7 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
540 | function success(dashboard) { | 540 | function success(dashboard) { |
541 | var name = dashboard.title; | 541 | var name = dashboard.title; |
542 | name = name.toLowerCase().replace(/\W/g,"_"); | 542 | name = name.toLowerCase().replace(/\W/g,"_"); |
543 | - exportToPc(prepareExport(dashboard), name + '.json'); | 543 | + exportToPc(prepareDashboardExport(dashboard), name + '.json'); |
544 | }, | 544 | }, |
545 | function fail(rejection) { | 545 | function fail(rejection) { |
546 | var message = rejection; | 546 | var message = rejection; |
@@ -552,6 +552,15 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | @@ -552,6 +552,15 @@ export default function ImportExport($log, $translate, $q, $mdDialog, $document, | ||
552 | ); | 552 | ); |
553 | } | 553 | } |
554 | 554 | ||
555 | + function prepareDashboardExport(dashboard) { | ||
556 | + dashboard = prepareExport(dashboard); | ||
557 | + delete dashboard.assignedCustomers; | ||
558 | + delete dashboard.publicCustomerId; | ||
559 | + delete dashboard.assignedCustomersText; | ||
560 | + delete dashboard.assignedCustomersIds; | ||
561 | + return dashboard; | ||
562 | + } | ||
563 | + | ||
555 | function importDashboard($event) { | 564 | function importDashboard($event) { |
556 | var deferred = $q.defer(); | 565 | var deferred = $q.defer(); |
557 | openImportDialog($event, 'dashboard.import', 'dashboard.dashboard-file').then( | 566 | openImportDialog($event, 'dashboard.import', 'dashboard.dashboard-file').then( |
@@ -383,7 +383,10 @@ export default angular.module('thingsboard.locale', []) | @@ -383,7 +383,10 @@ export default angular.module('thingsboard.locale', []) | ||
383 | "idCopiedMessage": "Customer Id has been copied to clipboard", | 383 | "idCopiedMessage": "Customer Id has been copied to clipboard", |
384 | "select-customer": "Select customer", | 384 | "select-customer": "Select customer", |
385 | "no-customers-matching": "No customers matching '{{entity}}' were found.", | 385 | "no-customers-matching": "No customers matching '{{entity}}' were found.", |
386 | - "customer-required": "Customer is required" | 386 | + "customer-required": "Customer is required", |
387 | + "select-default-customer": "Select default customer", | ||
388 | + "default-customer": "Default customer", | ||
389 | + "default-customer-required": "Default customer is required in order to debug dashboard on Tenant level" | ||
387 | }, | 390 | }, |
388 | "datetime": { | 391 | "datetime": { |
389 | "date-from": "Date from", | 392 | "date-from": "Date from", |
@@ -404,6 +407,12 @@ export default angular.module('thingsboard.locale', []) | @@ -404,6 +407,12 @@ export default angular.module('thingsboard.locale', []) | ||
404 | "unassign-from-customer": "Unassign from customer", | 407 | "unassign-from-customer": "Unassign from customer", |
405 | "make-public": "Make dashboard public", | 408 | "make-public": "Make dashboard public", |
406 | "make-private": "Make dashboard private", | 409 | "make-private": "Make dashboard private", |
410 | + "manage-assigned-customers": "Manage assigned customers", | ||
411 | + "assigned-customers": "Assigned customers", | ||
412 | + "assign-to-customers": "Assign Dashboard(s) To Customers", | ||
413 | + "assign-to-customers-text": "Please select the customers to assign the dashboard(s)", | ||
414 | + "unassign-from-customers": "Unassign Dashboard(s) From Customers", | ||
415 | + "unassign-from-customers-text": "Please select the customers to unassign from the dashboard(s)", | ||
407 | "no-dashboards-text": "No dashboards found", | 416 | "no-dashboards-text": "No dashboards found", |
408 | "no-widgets": "No widgets configured", | 417 | "no-widgets": "No widgets configured", |
409 | "add-widget": "Add new widget", | 418 | "add-widget": "Add new widget", |
@@ -418,7 +427,8 @@ export default angular.module('thingsboard.locale', []) | @@ -418,7 +427,8 @@ export default angular.module('thingsboard.locale', []) | ||
418 | "add-dashboard-text": "Add new dashboard", | 427 | "add-dashboard-text": "Add new dashboard", |
419 | "assign-dashboards": "Assign dashboards", | 428 | "assign-dashboards": "Assign dashboards", |
420 | "assign-new-dashboard": "Assign new dashboard", | 429 | "assign-new-dashboard": "Assign new dashboard", |
421 | - "assign-dashboards-text": "Assign { count, select, 1 {1 dashboard} other {# dashboards} } to customer", | 430 | + "assign-dashboards-text": "Assign { count, select, 1 {1 dashboard} other {# dashboards} } to customers", |
431 | + "unassign-dashboards-action-text": "Unassign { count, select, 1 {1 dashboard} other {# dashboards} } from customers", | ||
422 | "delete-dashboards": "Delete dashboards", | 432 | "delete-dashboards": "Delete dashboards", |
423 | "unassign-dashboards": "Unassign dashboards", | 433 | "unassign-dashboards": "Unassign dashboards", |
424 | "unassign-dashboards-action-title": "Unassign { count, select, 1 {1 dashboard} other {# dashboards} } from customer", | 434 | "unassign-dashboards-action-title": "Unassign { count, select, 1 {1 dashboard} other {# dashboards} } from customer", |
@@ -500,6 +510,7 @@ export default angular.module('thingsboard.locale', []) | @@ -500,6 +510,7 @@ export default angular.module('thingsboard.locale', []) | ||
500 | "Please contact your administrator in order to resolve this issue.", | 510 | "Please contact your administrator in order to resolve this issue.", |
501 | "select-devices": "Select devices", | 511 | "select-devices": "Select devices", |
502 | "assignedToCustomer": "Assigned to customer", | 512 | "assignedToCustomer": "Assigned to customer", |
513 | + "assignedToCustomers": "Assigned to customers", | ||
503 | "public": "Public", | 514 | "public": "Public", |
504 | "public-link": "Public link", | 515 | "public-link": "Public link", |
505 | "copy-public-link": "Copy public link", | 516 | "copy-public-link": "Copy public link", |
@@ -735,6 +746,7 @@ export default angular.module('thingsboard.locale', []) | @@ -735,6 +746,7 @@ export default angular.module('thingsboard.locale', []) | ||
735 | "type-alarms": "Alarms", | 746 | "type-alarms": "Alarms", |
736 | "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", | 747 | "list-of-alarms": "{ count, select, 1 {One alarms} other {List of # alarms} }", |
737 | "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", | 748 | "alarm-name-starts-with": "Alarms whose names start with '{{prefix}}'", |
749 | + "type-current-customer": "Current Customer", | ||
738 | "search": "Search entities", | 750 | "search": "Search entities", |
739 | "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", | 751 | "selected-entities": "{ count, select, 1 {1 entity} other {# entities} } selected", |
740 | "entity-name": "Entity name", | 752 | "entity-name": "Entity name", |