Commit 6be5f9aa4d315facb772f681c95f05ff3546c698
1 parent
f35c1156
Manage edge dashboards functionality
Showing
15 changed files
with
603 additions
and
28 deletions
@@ -689,4 +689,26 @@ public class DashboardController extends BaseController { | @@ -689,4 +689,26 @@ public class DashboardController extends BaseController { | ||
689 | throw handleException(e); | 689 | throw handleException(e); |
690 | } | 690 | } |
691 | } | 691 | } |
692 | + | ||
693 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
694 | + @RequestMapping(value = "/edge/{edgeId}/dashboards", params = { "limit" }, method = RequestMethod.GET) | ||
695 | + @ResponseBody | ||
696 | + public TimePageData<DashboardInfo> getEdgeDashboards( | ||
697 | + @PathVariable("edgeId") String strEdgeId, | ||
698 | + @RequestParam int limit, | ||
699 | + @RequestParam(required = false) Long startTime, | ||
700 | + @RequestParam(required = false) Long endTime, | ||
701 | + @RequestParam(required = false, defaultValue = "false") boolean ascOrder, | ||
702 | + @RequestParam(required = false) String offset) throws ThingsboardException { | ||
703 | + checkParameter("edgeId", strEdgeId); | ||
704 | + try { | ||
705 | + TenantId tenantId = getCurrentUser().getTenantId(); | ||
706 | + EdgeId edgeId = new EdgeId(toUUID(strEdgeId)); | ||
707 | + checkEdgeId(edgeId, Operation.READ); | ||
708 | + TimePageLink pageLink = createPageLink(limit, startTime, endTime, ascOrder, offset); | ||
709 | + return checkNotNull(dashboardService.findDashboardsByTenantIdAndEdgeId(tenantId, edgeId, pageLink).get()); | ||
710 | + } catch (Exception e) { | ||
711 | + throw handleException(e); | ||
712 | + } | ||
713 | + } | ||
692 | } | 714 | } |
@@ -62,4 +62,6 @@ public interface DashboardService { | @@ -62,4 +62,6 @@ public interface DashboardService { | ||
62 | void unassignEdgeDashboards(TenantId tenantId, EdgeId edgeId); | 62 | void unassignEdgeDashboards(TenantId tenantId, EdgeId edgeId); |
63 | 63 | ||
64 | void updateEdgeDashboards(TenantId tenantId, EdgeId edgeId); | 64 | void updateEdgeDashboards(TenantId tenantId, EdgeId edgeId); |
65 | + | ||
66 | + ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink); | ||
65 | } | 67 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2019 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 | + */ | ||
1 | package org.thingsboard.server.common.data; | 16 | package org.thingsboard.server.common.data; |
2 | 17 | ||
3 | import lombok.AllArgsConstructor; | 18 | import lombok.AllArgsConstructor; |
4 | -import lombok.Data; | ||
5 | -import lombok.NoArgsConstructor; | 19 | +import lombok.Getter; |
20 | +import lombok.Setter; | ||
6 | import org.thingsboard.server.common.data.id.EdgeId; | 21 | import org.thingsboard.server.common.data.id.EdgeId; |
7 | 22 | ||
8 | -@Data | ||
9 | -@NoArgsConstructor | ||
10 | @AllArgsConstructor | 23 | @AllArgsConstructor |
11 | public class ShortEdgeInfo { | 24 | public class ShortEdgeInfo { |
12 | 25 | ||
26 | + @Getter @Setter | ||
13 | private EdgeId edgeId; | 27 | private EdgeId edgeId; |
28 | + | ||
29 | + @Getter @Setter | ||
14 | private String title; | 30 | private String title; |
31 | + | ||
32 | + @Override | ||
33 | + public boolean equals(Object o) { | ||
34 | + if (this == o) return true; | ||
35 | + if (o == null || getClass() != o.getClass()) return false; | ||
36 | + | ||
37 | + ShortEdgeInfo that = (ShortEdgeInfo) o; | ||
38 | + | ||
39 | + return edgeId.equals(that.edgeId); | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public int hashCode() { | ||
44 | + return edgeId.hashCode(); | ||
45 | + } | ||
15 | } | 46 | } |
@@ -299,6 +299,23 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | @@ -299,6 +299,23 @@ public class DashboardServiceImpl extends AbstractEntityService implements Dashb | ||
299 | new EdgeDashboardsUpdater(edge).removeEntities(tenantId, edge); | 299 | new EdgeDashboardsUpdater(edge).removeEntities(tenantId, edge); |
300 | } | 300 | } |
301 | 301 | ||
302 | + @Override | ||
303 | + public ListenableFuture<TimePageData<DashboardInfo>> findDashboardsByTenantIdAndEdgeId(TenantId tenantId, EdgeId edgeId, TimePageLink pageLink) { | ||
304 | + log.trace("Executing findDashboardsByTenantIdAndEdgeId, tenantId [{}], edgeId [{}], pageLink [{}]", tenantId, edgeId, pageLink); | ||
305 | + Validator.validateId(tenantId, INCORRECT_TENANT_ID + tenantId); | ||
306 | + Validator.validateId(edgeId, "Incorrect customerId " + edgeId); | ||
307 | + Validator.validatePageLink(pageLink, "Incorrect page link " + pageLink); | ||
308 | + ListenableFuture<List<DashboardInfo>> dashboards = dashboardInfoDao.findDashboardsByTenantIdAndEdgeId(tenantId.getId(), edgeId.getId(), pageLink); | ||
309 | + | ||
310 | + return Futures.transform(dashboards, new Function<List<DashboardInfo>, TimePageData<DashboardInfo>>() { | ||
311 | + @Nullable | ||
312 | + @Override | ||
313 | + public TimePageData<DashboardInfo> apply(@Nullable List<DashboardInfo> dashboards) { | ||
314 | + return new TimePageData<>(dashboards, pageLink); | ||
315 | + } | ||
316 | + }); | ||
317 | + } | ||
318 | + | ||
302 | private Dashboard updateAssignedEdge(TenantId tenantId, DashboardId dashboardId, Edge edge) { | 319 | private Dashboard updateAssignedEdge(TenantId tenantId, DashboardId dashboardId, Edge edge) { |
303 | Dashboard dashboard = findDashboardById(tenantId, dashboardId); | 320 | Dashboard dashboard = findDashboardById(tenantId, dashboardId); |
304 | if (dashboard.updateAssignedEdge(edge)) { | 321 | if (dashboard.updateAssignedEdge(edge)) { |
@@ -25,6 +25,7 @@ import lombok.extern.slf4j.Slf4j; | @@ -25,6 +25,7 @@ import lombok.extern.slf4j.Slf4j; | ||
25 | import org.springframework.util.StringUtils; | 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.ShortCustomerInfo; | 27 | import org.thingsboard.server.common.data.ShortCustomerInfo; |
28 | +import org.thingsboard.server.common.data.ShortEdgeInfo; | ||
28 | import org.thingsboard.server.common.data.id.DashboardId; | 29 | import org.thingsboard.server.common.data.id.DashboardId; |
29 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
30 | import org.thingsboard.server.dao.model.BaseSqlEntity; | 31 | import org.thingsboard.server.dao.model.BaseSqlEntity; |
@@ -47,6 +48,8 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -47,6 +48,8 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
47 | private static final ObjectMapper objectMapper = new ObjectMapper(); | 48 | private static final ObjectMapper objectMapper = new ObjectMapper(); |
48 | private static final JavaType assignedCustomersType = | 49 | private static final JavaType assignedCustomersType = |
49 | objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); | 50 | objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortCustomerInfo.class); |
51 | + private static final JavaType assignedEdgesType = | ||
52 | + objectMapper.getTypeFactory().constructCollectionType(HashSet.class, ShortEdgeInfo.class); | ||
50 | 53 | ||
51 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) | 54 | @Column(name = ModelConstants.DASHBOARD_TENANT_ID_PROPERTY) |
52 | private String tenantId; | 55 | private String tenantId; |
@@ -60,6 +63,9 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -60,6 +63,9 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
60 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) | 63 | @Column(name = ModelConstants.DASHBOARD_ASSIGNED_CUSTOMERS_PROPERTY) |
61 | private String assignedCustomers; | 64 | private String assignedCustomers; |
62 | 65 | ||
66 | + @Column(name = ModelConstants.DASHBOARD_ASSIGNED_EDGES_PROPERTY) | ||
67 | + private String assignedEdges; | ||
68 | + | ||
63 | public DashboardInfoEntity() { | 69 | public DashboardInfoEntity() { |
64 | super(); | 70 | super(); |
65 | } | 71 | } |
@@ -79,6 +85,13 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -79,6 +85,13 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
79 | log.error("Unable to serialize assigned customers to string!", e); | 85 | log.error("Unable to serialize assigned customers to string!", e); |
80 | } | 86 | } |
81 | } | 87 | } |
88 | + if (dashboardInfo.getAssignedEdges() != null) { | ||
89 | + try { | ||
90 | + this.assignedEdges = objectMapper.writeValueAsString(dashboardInfo.getAssignedEdges()); | ||
91 | + } catch (JsonProcessingException e) { | ||
92 | + log.error("Unable to serialize assigned edges to string!", e); | ||
93 | + } | ||
94 | + } | ||
82 | } | 95 | } |
83 | 96 | ||
84 | @Override | 97 | @Override |
@@ -110,6 +123,13 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | @@ -110,6 +123,13 @@ public class DashboardInfoEntity extends BaseSqlEntity<DashboardInfo> implements | ||
110 | log.warn("Unable to parse assigned customers!", e); | 123 | log.warn("Unable to parse assigned customers!", e); |
111 | } | 124 | } |
112 | } | 125 | } |
126 | + if (!StringUtils.isEmpty(assignedEdges)) { | ||
127 | + try { | ||
128 | + dashboardInfo.setAssignedEdges(objectMapper.readValue(assignedEdges, assignedEdgesType)); | ||
129 | + } catch (IOException e) { | ||
130 | + log.warn("Unable to parse assigned edges!", e); | ||
131 | + } | ||
132 | + } | ||
113 | return dashboardInfo; | 133 | return dashboardInfo; |
114 | } | 134 | } |
115 | 135 |
@@ -45,7 +45,10 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | @@ -45,7 +45,10 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | ||
45 | getPublicDashboardLink: getPublicDashboardLink, | 45 | getPublicDashboardLink: getPublicDashboardLink, |
46 | updateDashboardEdges: updateDashboardEdges, | 46 | updateDashboardEdges: updateDashboardEdges, |
47 | addDashboardEdges: addDashboardEdges, | 47 | addDashboardEdges: addDashboardEdges, |
48 | - removeDashboardEdges: removeDashboardEdges | 48 | + removeDashboardEdges: removeDashboardEdges, |
49 | + getEdgeDashboards: getEdgeDashboards, | ||
50 | + assignDashboardToEdge: assignDashboardToEdge, | ||
51 | + unassignDashboardFromEdge: unassignDashboardFromEdge | ||
49 | } | 52 | } |
50 | 53 | ||
51 | return service; | 54 | return service; |
@@ -285,6 +288,20 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | @@ -285,6 +288,20 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | ||
285 | } | 288 | } |
286 | dashboard.assignedCustomersText = assignedCustomersTitles.join(', '); | 289 | dashboard.assignedCustomersText = assignedCustomersTitles.join(', '); |
287 | } | 290 | } |
291 | + dashboard.assignedEdgesIds = []; | ||
292 | + if (dashboard.assignedEdges && dashboard.assignedEdges.length) { | ||
293 | + // var assignedEdgesTitles = []; | ||
294 | + for (var j = 0; j < dashboard.assignedEdges.length; j++) { | ||
295 | + var assignedEdge = dashboard.assignedEdges[j]; | ||
296 | + dashboard.assignedEdgesIds.push(assignedEdge.edgeId.id); | ||
297 | + // if (assignedCustomer.public) { | ||
298 | + // dashboard.publicCustomerId = assignedCustomer.customerId.id; | ||
299 | + // } else { | ||
300 | + // assignedCustomersTitles.push(assignedCustomer.title); | ||
301 | + // } | ||
302 | + } | ||
303 | + // dashboard.assignedCustomersText = assignedCustomersTitles.join(', '); | ||
304 | + } | ||
288 | return dashboard; | 305 | return dashboard; |
289 | } | 306 | } |
290 | 307 | ||
@@ -292,6 +309,7 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | @@ -292,6 +309,7 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | ||
292 | delete dashboard.publicCustomerId; | 309 | delete dashboard.publicCustomerId; |
293 | delete dashboard.assignedCustomersText; | 310 | delete dashboard.assignedCustomersText; |
294 | delete dashboard.assignedCustomersIds; | 311 | delete dashboard.assignedCustomersIds; |
312 | + delete dashboard.assignedEdgeIds; | ||
295 | return dashboard; | 313 | return dashboard; |
296 | } | 314 | } |
297 | 315 | ||
@@ -327,4 +345,44 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | @@ -327,4 +345,44 @@ function DashboardService($rootScope, $http, $q, $location, $filter) { | ||
327 | }); | 345 | }); |
328 | return deferred.promise; | 346 | return deferred.promise; |
329 | } | 347 | } |
348 | + | ||
349 | + function getEdgeDashboards(edgeId, pageLink, config) { | ||
350 | + var deferred = $q.defer(); | ||
351 | + var url = '/api/edge/' + edgeId + '/dashboards?limit=' + pageLink.limit; | ||
352 | + if (angular.isDefined(pageLink.idOffset)) { | ||
353 | + url += '&offset=' + pageLink.idOffset; | ||
354 | + } | ||
355 | + $http.get(url, config).then(function success(response) { | ||
356 | + response.data = prepareDashboards(response.data); | ||
357 | + if (pageLink.textSearch) { | ||
358 | + response.data.data = $filter('filter')(response.data.data, {title: pageLink.textSearch}); | ||
359 | + } | ||
360 | + deferred.resolve(response.data); | ||
361 | + }, function fail() { | ||
362 | + deferred.reject(); | ||
363 | + }); | ||
364 | + return deferred.promise; | ||
365 | + } | ||
366 | + | ||
367 | + function assignDashboardToEdge(edgeId, dashboardId) { | ||
368 | + var deferred = $q.defer(); | ||
369 | + var url = '/api/edge/' + edgeId + '/dashboard/' + dashboardId; | ||
370 | + $http.post(url, null).then(function success(response) { | ||
371 | + deferred.resolve(prepareDashboard(response.data)); | ||
372 | + }, function fail() { | ||
373 | + deferred.reject(); | ||
374 | + }); | ||
375 | + return deferred.promise; | ||
376 | + } | ||
377 | + | ||
378 | + function unassignDashboardFromEdge(edgeId, dashboardId) { | ||
379 | + var deferred = $q.defer(); | ||
380 | + var url = '/api/edge/' + edgeId + '/dashboard/' + dashboardId; | ||
381 | + $http.delete(url).then(function success(response) { | ||
382 | + deferred.resolve(prepareDashboard(response.data)); | ||
383 | + }, function fail() { | ||
384 | + deferred.reject(); | ||
385 | + }); | ||
386 | + return deferred.promise; | ||
387 | + } | ||
330 | } | 388 | } |
@@ -89,7 +89,7 @@ export default function CustomerController(customerService, $state, $stateParams | @@ -89,7 +89,7 @@ export default function CustomerController(customerService, $state, $stateParams | ||
89 | return $translate.instant('customer.manage-customer-edges') | 89 | return $translate.instant('customer.manage-customer-edges') |
90 | } | 90 | } |
91 | }, | 91 | }, |
92 | - icon: "toys" | 92 | + icon: "wifi_tethering" |
93 | }, | 93 | }, |
94 | { | 94 | { |
95 | onAction: function ($event, item) { | 95 | onAction: function ($event, item) { |
1 | +/* | ||
2 | + * Copyright © 2016-2019 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 AddDashboardsToEdgeController(dashboardService, $mdDialog, $q, edgeId, dashboards) { | ||
18 | + | ||
19 | + var vm = this; | ||
20 | + | ||
21 | + vm.dashboards = dashboards; | ||
22 | + vm.searchText = ''; | ||
23 | + | ||
24 | + vm.assign = assign; | ||
25 | + vm.cancel = cancel; | ||
26 | + vm.hasData = hasData; | ||
27 | + vm.noData = noData; | ||
28 | + vm.searchDashboardTextUpdated = searchDashboardTextUpdated; | ||
29 | + vm.toggleDashboardSelection = toggleDashboardSelection; | ||
30 | + | ||
31 | + vm.theDashboards = { | ||
32 | + getItemAtIndex: function (index) { | ||
33 | + if (index > vm.dashboards.data.length) { | ||
34 | + vm.theDashboards.fetchMoreItems_(index); | ||
35 | + return null; | ||
36 | + } | ||
37 | + var item = vm.dashboards.data[index]; | ||
38 | + if (item) { | ||
39 | + item.indexNumber = index + 1; | ||
40 | + } | ||
41 | + return item; | ||
42 | + }, | ||
43 | + | ||
44 | + getLength: function () { | ||
45 | + if (vm.dashboards.hasNext) { | ||
46 | + return vm.dashboards.data.length + vm.dashboards.nextPageLink.limit; | ||
47 | + } else { | ||
48 | + return vm.dashboards.data.length; | ||
49 | + } | ||
50 | + }, | ||
51 | + | ||
52 | + fetchMoreItems_: function () { | ||
53 | + if (vm.dashboards.hasNext && !vm.dashboards.pending) { | ||
54 | + vm.dashboards.pending = true; | ||
55 | + dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then( | ||
56 | + function success(dashboards) { | ||
57 | + vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); | ||
58 | + vm.dashboards.nextPageLink = dashboards.nextPageLink; | ||
59 | + vm.dashboards.hasNext = dashboards.hasNext; | ||
60 | + if (vm.dashboards.hasNext) { | ||
61 | + vm.dashboards.nextPageLink.limit = vm.dashboards.pageSize; | ||
62 | + } | ||
63 | + vm.dashboards.pending = false; | ||
64 | + }, | ||
65 | + function fail() { | ||
66 | + vm.dashboards.hasNext = false; | ||
67 | + vm.dashboards.pending = false; | ||
68 | + }); | ||
69 | + } | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + function cancel () { | ||
74 | + $mdDialog.cancel(); | ||
75 | + } | ||
76 | + | ||
77 | + function assign () { | ||
78 | + var tasks = []; | ||
79 | + for (var dashboardId in vm.dashboards.selections) { | ||
80 | + tasks.push(dashboardService.assignDashboardToEdge(edgeId, dashboardId)); | ||
81 | + } | ||
82 | + $q.all(tasks).then(function () { | ||
83 | + $mdDialog.hide(); | ||
84 | + }); | ||
85 | + } | ||
86 | + | ||
87 | + function noData () { | ||
88 | + return vm.dashboards.data.length == 0 && !vm.dashboards.hasNext; | ||
89 | + } | ||
90 | + | ||
91 | + function hasData () { | ||
92 | + return vm.dashboards.data.length > 0; | ||
93 | + } | ||
94 | + | ||
95 | + function toggleDashboardSelection ($event, dashboard) { | ||
96 | + $event.stopPropagation(); | ||
97 | + var selected = angular.isDefined(dashboard.selected) && dashboard.selected; | ||
98 | + dashboard.selected = !selected; | ||
99 | + if (dashboard.selected) { | ||
100 | + vm.dashboards.selections[dashboard.id.id] = true; | ||
101 | + vm.dashboards.selectedCount++; | ||
102 | + } else { | ||
103 | + delete vm.dashboards.selections[dashboard.id.id]; | ||
104 | + vm.dashboards.selectedCount--; | ||
105 | + } | ||
106 | + } | ||
107 | + | ||
108 | + function searchDashboardTextUpdated () { | ||
109 | + vm.dashboards = { | ||
110 | + pageSize: vm.dashboards.pageSize, | ||
111 | + data: [], | ||
112 | + nextPageLink: { | ||
113 | + limit: vm.dashboards.pageSize, | ||
114 | + textSearch: vm.searchText | ||
115 | + }, | ||
116 | + selections: {}, | ||
117 | + selectedCount: 0, | ||
118 | + hasNext: true, | ||
119 | + pending: false | ||
120 | + }; | ||
121 | + } | ||
122 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2019 The Thingsboard Authors | ||
4 | + | ||
5 | + Licensed under the Apache License, Version 2.0 (the "License"); | ||
6 | + you may not use this file except in compliance with the License. | ||
7 | + You may obtain a copy of the License at | ||
8 | + | ||
9 | + http://www.apache.org/licenses/LICENSE-2.0 | ||
10 | + | ||
11 | + Unless required by applicable law or agreed to in writing, software | ||
12 | + distributed under the License is distributed on an "AS IS" BASIS, | ||
13 | + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
14 | + See the License for the specific language governing permissions and | ||
15 | + limitations under the License. | ||
16 | + | ||
17 | +--> | ||
18 | +<md-dialog aria-label="{{ 'dashboard.assign-dashboard-to-edge' | translate }}"> | ||
19 | + <form name="theForm" ng-submit="vm.assign()"> | ||
20 | + <md-toolbar> | ||
21 | + <div class="md-toolbar-tools"> | ||
22 | + <h2 translate>dashboard.assign-dashboard-to-edge</h2> | ||
23 | + <span flex></span> | ||
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> | ||
26 | + </md-button> | ||
27 | + </div> | ||
28 | + </md-toolbar> | ||
29 | + <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> | ||
30 | + <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | ||
31 | + <md-dialog-content> | ||
32 | + <div class="md-dialog-content"> | ||
33 | + <fieldset> | ||
34 | + <span translate>dashboard.assign-dashboard-to-edge-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="dashboard-search" autofocus ng-model="vm.searchText" | ||
41 | + ng-change="vm.searchDashboardTextUpdated()" | ||
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()">dashboard.no-dashboards-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="dashboard in vm.theDashboards" md-on-demand | ||
54 | + class="repeated-item" flex> | ||
55 | + <md-checkbox ng-click="vm.toggleDashboardSelection($event, dashboard)" | ||
56 | + aria-label="{{ 'item.selected' | translate }}" | ||
57 | + ng-checked="dashboard.selected"></md-checkbox> | ||
58 | + <span> {{ dashboard.title }} </span> | ||
59 | + </md-list-item> | ||
60 | + </md-list> | ||
61 | + </md-virtual-repeat-container> | ||
62 | + </div> | ||
63 | + </fieldset> | ||
64 | + </div> | ||
65 | + </md-dialog-content> | ||
66 | + <md-dialog-actions layout="row"> | ||
67 | + <span flex></span> | ||
68 | + <md-button ng-disabled="$root.loading || vm.dashboards.selectedCount == 0" type="submit" | ||
69 | + class="md-raised md-primary"> | ||
70 | + {{ 'action.assign' | translate }} | ||
71 | + </md-button> | ||
72 | + <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | ||
73 | + translate }} | ||
74 | + </md-button> | ||
75 | + </md-dialog-actions> | ||
76 | + </form> | ||
77 | +</md-dialog> |
@@ -124,4 +124,25 @@ export default function DashboardRoutes($stateProvider) { | @@ -124,4 +124,25 @@ export default function DashboardRoutes($stateProvider) { | ||
124 | label: '{"icon": "dashboard", "label": "customer.dashboard"}' | 124 | label: '{"icon": "dashboard", "label": "customer.dashboard"}' |
125 | } | 125 | } |
126 | }) | 126 | }) |
127 | + .state('home.edges.dashboards', { | ||
128 | + url: '/:edgeId/dashboards', | ||
129 | + params: {'topIndex': 0}, | ||
130 | + module: 'private', | ||
131 | + auth: ['TENANT_ADMIN'], | ||
132 | + views: { | ||
133 | + "content@home": { | ||
134 | + templateUrl: dashboardsTemplate, | ||
135 | + controllerAs: 'vm', | ||
136 | + controller: 'DashboardsController' | ||
137 | + } | ||
138 | + }, | ||
139 | + data: { | ||
140 | + dashboardsType: 'edge', | ||
141 | + searchEnabled: true, | ||
142 | + pageTitle: 'edge.dashboards' | ||
143 | + }, | ||
144 | + ncyBreadcrumb: { | ||
145 | + label: '{"icon": "dashboard", "label": "{{ vm.edgeDashboardsTitle }}", "translate": "false"}' | ||
146 | + } | ||
147 | + }) | ||
127 | } | 148 | } |
@@ -21,6 +21,7 @@ import addDashboardsToCustomerTemplate from './add-dashboards-to-customer.tpl.ht | @@ -21,6 +21,7 @@ import addDashboardsToCustomerTemplate from './add-dashboards-to-customer.tpl.ht | ||
21 | 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'; | 22 | import manageAssignedCustomersTemplate from './manage-assigned-customers.tpl.html'; |
23 | import manageAssignedEdgesTemplate from './manage-assigned-edges.tpl.html'; | 23 | import manageAssignedEdgesTemplate from './manage-assigned-edges.tpl.html'; |
24 | +import addDashboardsToEdgeTemplate from './add-dashboards-to-edge.tpl.html'; | ||
24 | 25 | ||
25 | /* eslint-enable import/no-unresolved, import/default */ | 26 | /* eslint-enable import/no-unresolved, import/default */ |
26 | 27 | ||
@@ -60,6 +61,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -60,6 +61,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
60 | $state, $stateParams, $mdDialog, $document, $q, $translate) { | 61 | $state, $stateParams, $mdDialog, $document, $q, $translate) { |
61 | 62 | ||
62 | var customerId = $stateParams.customerId; | 63 | var customerId = $stateParams.customerId; |
64 | + var edgeId = $stateParams.edgeId; | ||
63 | 65 | ||
64 | var dashboardActionsList = [ | 66 | var dashboardActionsList = [ |
65 | { | 67 | { |
@@ -215,7 +217,7 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -215,7 +217,7 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
215 | }, | 217 | }, |
216 | name: function() { return $translate.instant('action.assign') }, | 218 | name: function() { return $translate.instant('action.assign') }, |
217 | details: function() { return $translate.instant('dashboard.manage-assigned-edges') }, | 219 | details: function() { return $translate.instant('dashboard.manage-assigned-edges') }, |
218 | - icon: "assignment", | 220 | + icon: "wifi_tethering", |
219 | isEnabled: function(dashboard) { | 221 | isEnabled: function(dashboard) { |
220 | return dashboard; | 222 | return dashboard; |
221 | } | 223 | } |
@@ -256,6 +258,32 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -256,6 +258,32 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
256 | ); | 258 | ); |
257 | 259 | ||
258 | dashboardGroupActionsList.push( | 260 | dashboardGroupActionsList.push( |
261 | + { | ||
262 | + onAction: function ($event, items) { | ||
263 | + assignDashboardsToEdges($event, items); | ||
264 | + }, | ||
265 | + name: function() { return $translate.instant('dashboard.assign-dashboards') }, | ||
266 | + details: function(selectedCount) { | ||
267 | + return $translate.instant('dashboard.assign-dashboards-to-edge-text', {count: selectedCount}, "messageformat"); | ||
268 | + }, | ||
269 | + icon: "wifi_tethering" | ||
270 | + } | ||
271 | + ); | ||
272 | + | ||
273 | + dashboardGroupActionsList.push( | ||
274 | + { | ||
275 | + onAction: function ($event, items) { | ||
276 | + unassignDashboardsFromEdges($event, items); | ||
277 | + }, | ||
278 | + name: function() { return $translate.instant('dashboard.unassign-dashboards') }, | ||
279 | + details: function(selectedCount) { | ||
280 | + return $translate.instant('dashboard.unassign-dashboards-from-edge-action-text', {count: selectedCount}, "messageformat"); | ||
281 | + }, | ||
282 | + icon: "portable_wifi_off" | ||
283 | + } | ||
284 | + ); | ||
285 | + | ||
286 | + dashboardGroupActionsList.push( | ||
259 | { | 287 | { |
260 | onAction: function ($event, items) { | 288 | onAction: function ($event, items) { |
261 | assignDashboardsToCustomers($event, items); | 289 | assignDashboardsToCustomers($event, items); |
@@ -386,6 +414,60 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -386,6 +414,60 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
386 | } else if (vm.dashboardsScope === 'customer_user') { | 414 | } else if (vm.dashboardsScope === 'customer_user') { |
387 | vm.dashboardGridConfig.addItemAction = {}; | 415 | vm.dashboardGridConfig.addItemAction = {}; |
388 | } | 416 | } |
417 | + } else if (vm.dashboardsScope === 'edge') { | ||
418 | + fetchDashboardsFunction = function (pageLink) { | ||
419 | + return dashboardService.getEdgeDashboards(edgeId, pageLink); | ||
420 | + }; | ||
421 | + deleteDashboardFunction = function (dashboardId) { | ||
422 | + return dashboardService.unassignDashboardFromEdge(edgeId, dashboardId); | ||
423 | + }; | ||
424 | + refreshDashboardsParamsFunction = function () { | ||
425 | + return {"edgeId": edgeId, "topIndex": vm.topIndex}; | ||
426 | + }; | ||
427 | + | ||
428 | + dashboardActionsList.push( | ||
429 | + { | ||
430 | + onAction: function ($event, item) { | ||
431 | + exportDashboard($event, item); | ||
432 | + }, | ||
433 | + name: function() { $translate.instant('action.export') }, | ||
434 | + details: function() { return $translate.instant('dashboard.export') }, | ||
435 | + icon: "file_download" | ||
436 | + } | ||
437 | + ); | ||
438 | + | ||
439 | + dashboardActionsList.push( | ||
440 | + { | ||
441 | + onAction: function ($event, item) { | ||
442 | + unassignFromEdge($event, item, edgeId); | ||
443 | + }, | ||
444 | + name: function() { return $translate.instant('action.unassign') }, | ||
445 | + details: function() { return $translate.instant('dashboard.unassign-from-edge') }, | ||
446 | + icon: "assignment_return" | ||
447 | + } | ||
448 | + ); | ||
449 | + | ||
450 | + dashboardGroupActionsList.push( | ||
451 | + { | ||
452 | + onAction: function ($event, items) { | ||
453 | + unassignDashboardsFromEdge($event, items, edgeId); | ||
454 | + }, | ||
455 | + name: function() { return $translate.instant('dashboard.unassign-dashboards') }, | ||
456 | + details: function(selectedCount) { | ||
457 | + return $translate.instant('dashboard.unassign-dashboards-from-edge-action-title', {count: selectedCount}, "messageformat"); | ||
458 | + }, | ||
459 | + icon: "assignment_return" | ||
460 | + } | ||
461 | + ); | ||
462 | + | ||
463 | + vm.dashboardGridConfig.addItemAction = { | ||
464 | + onAction: function ($event) { | ||
465 | + addDashboardsToEdge($event); | ||
466 | + }, | ||
467 | + name: function() { return $translate.instant('dashboard.assign-dashboards') }, | ||
468 | + details: function() { return $translate.instant('dashboard.assign-new-dashboard') }, | ||
469 | + icon: "add" | ||
470 | + }; | ||
389 | } | 471 | } |
390 | 472 | ||
391 | vm.dashboardGridConfig.refreshParamsFunc = refreshDashboardsParamsFunction; | 473 | vm.dashboardGridConfig.refreshParamsFunc = refreshDashboardsParamsFunction; |
@@ -628,21 +710,40 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -628,21 +710,40 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
628 | showManageAssignedEdgesDialog($event, [dashboard.id.id], 'manage', dashboard.assignedEdgesIds); | 710 | showManageAssignedEdgesDialog($event, [dashboard.id.id], 'manage', dashboard.assignedEdgesIds); |
629 | } | 711 | } |
630 | 712 | ||
631 | - // function assignDashboardsToEdges($event, items) { | ||
632 | - // var dashboardIds = []; | ||
633 | - // for (var id in items.selections) { | ||
634 | - // dashboardIds.push(id); | ||
635 | - // } | ||
636 | - // showManageAssignedEdgesDialog($event, dashboardIds, 'assign'); | ||
637 | - // } | ||
638 | - // | ||
639 | - // function unassignDashboardsFromEdges($event, items) { | ||
640 | - // var dashboardIds = []; | ||
641 | - // for (var id in items.selections) { | ||
642 | - // dashboardIds.push(id); | ||
643 | - // } | ||
644 | - // showManageAssignedEdgesDialog($event, dashboardIds, 'unassign'); | ||
645 | - // } | 713 | + function assignDashboardsToEdges($event, items) { |
714 | + var dashboardIds = []; | ||
715 | + for (var id in items.selections) { | ||
716 | + dashboardIds.push(id); | ||
717 | + } | ||
718 | + showManageAssignedEdgesDialog($event, dashboardIds, 'assign'); | ||
719 | + } | ||
720 | + | ||
721 | + function unassignDashboardsFromEdges($event, items) { | ||
722 | + var dashboardIds = []; | ||
723 | + for (var id in items.selections) { | ||
724 | + dashboardIds.push(id); | ||
725 | + } | ||
726 | + showManageAssignedEdgesDialog($event, dashboardIds, 'unassign'); | ||
727 | + } | ||
728 | + | ||
729 | + function unassignDashboardsFromEdge($event, items, edgeId) { | ||
730 | + var confirm = $mdDialog.confirm() | ||
731 | + .targetEvent($event) | ||
732 | + .title($translate.instant('dashboard.unassign-dashboards-title', {count: items.selectedCount}, 'messageformat')) | ||
733 | + .htmlContent($translate.instant('dashboard.unassign-dashboards-from-edge-text')) | ||
734 | + .ariaLabel($translate.instant('dashboard.unassign-dashboards')) | ||
735 | + .cancel($translate.instant('action.no')) | ||
736 | + .ok($translate.instant('action.yes')); | ||
737 | + $mdDialog.show(confirm).then(function () { | ||
738 | + var tasks = []; | ||
739 | + for (var id in items.selections) { | ||
740 | + tasks.push(dashboardService.unassignDashboardFromEdge(edgeId, id)); | ||
741 | + } | ||
742 | + $q.all(tasks).then(function () { | ||
743 | + vm.grid.refreshList(); | ||
744 | + }); | ||
745 | + }); | ||
746 | + } | ||
646 | 747 | ||
647 | function showManageAssignedEdgesDialog($event, dashboardIds, actionType, assignedEdges) { | 748 | function showManageAssignedEdgesDialog($event, dashboardIds, actionType, assignedEdges) { |
648 | if ($event) { | 749 | if ($event) { |
@@ -661,4 +762,61 @@ export function DashboardsController(userService, dashboardService, customerServ | @@ -661,4 +762,61 @@ export function DashboardsController(userService, dashboardService, customerServ | ||
661 | }, function () { | 762 | }, function () { |
662 | }); | 763 | }); |
663 | } | 764 | } |
765 | + | ||
766 | + function addDashboardsToEdge($event) { | ||
767 | + if ($event) { | ||
768 | + $event.stopPropagation(); | ||
769 | + } | ||
770 | + var pageSize = 10; | ||
771 | + dashboardService.getTenantDashboards({limit: pageSize, textSearch: ''}).then( | ||
772 | + function success(_dashboards) { | ||
773 | + var dashboards = { | ||
774 | + pageSize: pageSize, | ||
775 | + data: _dashboards.data, | ||
776 | + nextPageLink: _dashboards.nextPageLink, | ||
777 | + selections: {}, | ||
778 | + selectedCount: 0, | ||
779 | + hasNext: _dashboards.hasNext, | ||
780 | + pending: false | ||
781 | + }; | ||
782 | + if (dashboards.hasNext) { | ||
783 | + dashboards.nextPageLink.limit = pageSize; | ||
784 | + } | ||
785 | + $mdDialog.show({ | ||
786 | + controller: 'AddDashboardsToEdgeController', | ||
787 | + controllerAs: 'vm', | ||
788 | + templateUrl: addDashboardsToEdgeTemplate, | ||
789 | + locals: {edgeId: edgeId, dashboards: dashboards}, | ||
790 | + parent: angular.element($document[0].body), | ||
791 | + fullscreen: true, | ||
792 | + targetEvent: $event | ||
793 | + }).then(function () { | ||
794 | + vm.grid.refreshList(); | ||
795 | + }, function () { | ||
796 | + }); | ||
797 | + }, | ||
798 | + function fail() { | ||
799 | + }); | ||
800 | + } | ||
801 | + | ||
802 | + function unassignFromEdge($event, dashboard, edgeId) { | ||
803 | + if ($event) { | ||
804 | + $event.stopPropagation(); | ||
805 | + } | ||
806 | + var title = $translate.instant('dashboard.unassign-dashboard-title', {dashboardTitle: dashboard.title}); | ||
807 | + var content = $translate.instant('dashboard.unassign-dashboard-from-edge-text'); | ||
808 | + var label = $translate.instant('dashboard.unassign-dashboard'); | ||
809 | + var confirm = $mdDialog.confirm() | ||
810 | + .targetEvent($event) | ||
811 | + .title(title) | ||
812 | + .htmlContent(content) | ||
813 | + .ariaLabel(label) | ||
814 | + .cancel($translate.instant('action.no')) | ||
815 | + .ok($translate.instant('action.yes')); | ||
816 | + $mdDialog.show(confirm).then(function () { | ||
817 | + dashboardService.unassignDashboardFromEdge(edgeId, dashboard.id.id).then(function success() { | ||
818 | + vm.grid.refreshList(); | ||
819 | + }); | ||
820 | + }); | ||
821 | + } | ||
664 | } | 822 | } |
@@ -47,6 +47,7 @@ import AddWidgetController from './add-widget.controller'; | @@ -47,6 +47,7 @@ import AddWidgetController from './add-widget.controller'; | ||
47 | import DashboardDirective from './dashboard.directive'; | 47 | import DashboardDirective from './dashboard.directive'; |
48 | import EditWidgetDirective from './edit-widget.directive'; | 48 | import EditWidgetDirective from './edit-widget.directive'; |
49 | import DashboardToolbar from './dashboard-toolbar.directive'; | 49 | import DashboardToolbar from './dashboard-toolbar.directive'; |
50 | +import AddDashboardsToEdgeController from './add-dashboards-to-edge.controller'; | ||
50 | 51 | ||
51 | export default angular.module('thingsboard.dashboard', [ | 52 | export default angular.module('thingsboard.dashboard', [ |
52 | uiRouter, | 53 | uiRouter, |
@@ -79,6 +80,7 @@ export default angular.module('thingsboard.dashboard', [ | @@ -79,6 +80,7 @@ export default angular.module('thingsboard.dashboard', [ | ||
79 | .controller('ManageAssignedCustomersController', ManageAssignedCustomersController) | 80 | .controller('ManageAssignedCustomersController', ManageAssignedCustomersController) |
80 | .controller('ManageAssignedEdgesController', ManageAssignedEdgesController) | 81 | .controller('ManageAssignedEdgesController', ManageAssignedEdgesController) |
81 | .controller('AddWidgetController', AddWidgetController) | 82 | .controller('AddWidgetController', AddWidgetController) |
83 | + .controller('AddDashboardsToEdgeController', AddDashboardsToEdgeController) | ||
82 | .directive('tbDashboardDetails', DashboardDirective) | 84 | .directive('tbDashboardDetails', DashboardDirective) |
83 | .directive('tbEditWidget', EditWidgetDirective) | 85 | .directive('tbEditWidget', EditWidgetDirective) |
84 | .directive('tbDashboardToolbar', DashboardToolbar) | 86 | .directive('tbDashboardToolbar', DashboardToolbar) |
@@ -219,6 +219,19 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | @@ -219,6 +219,19 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | ||
219 | edgeActionsList.push( | 219 | edgeActionsList.push( |
220 | { | 220 | { |
221 | onAction: function ($event, item) { | 221 | onAction: function ($event, item) { |
222 | + openEdgeDashboards($event, item); | ||
223 | + }, | ||
224 | + name: function() { return $translate.instant('dashboard.dashboards') }, | ||
225 | + details: function() { | ||
226 | + return $translate.instant('edge.manage-edge-dashboards'); | ||
227 | + }, | ||
228 | + icon: "dashboard" | ||
229 | + } | ||
230 | + ); | ||
231 | + | ||
232 | + edgeActionsList.push( | ||
233 | + { | ||
234 | + onAction: function ($event, item) { | ||
222 | vm.grid.deleteItem($event, item); | 235 | vm.grid.deleteItem($event, item); |
223 | }, | 236 | }, |
224 | name: function() { return $translate.instant('action.delete') }, | 237 | name: function() { return $translate.instant('action.delete') }, |
@@ -240,6 +253,8 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | @@ -240,6 +253,8 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | ||
240 | } | 253 | } |
241 | ); | 254 | ); |
242 | 255 | ||
256 | + | ||
257 | + | ||
243 | edgeGroupActionsList.push( | 258 | edgeGroupActionsList.push( |
244 | { | 259 | { |
245 | onAction: function ($event) { | 260 | onAction: function ($event) { |
@@ -531,4 +546,18 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | @@ -531,4 +546,18 @@ export function EdgeController($rootScope, userService, edgeService, customerSer | ||
531 | }); | 546 | }); |
532 | }); | 547 | }); |
533 | } | 548 | } |
549 | + | ||
550 | + function openEdgeDashboards($event, edge) { | ||
551 | + if ($event) { | ||
552 | + $event.stopPropagation(); | ||
553 | + } | ||
554 | + $state.go('home.edges.dashboards', {edgeId: edge.id.id}); | ||
555 | + } | ||
556 | + | ||
557 | + // function openEdgeRuleChains($event, edge) { | ||
558 | + // if ($event) { | ||
559 | + // $event.stopPropagation(); | ||
560 | + // } | ||
561 | + // $state.go('home.edges.rule-chains', {edgeId: edge.id.id}); | ||
562 | + // } | ||
534 | } | 563 | } |
@@ -569,7 +569,20 @@ | @@ -569,7 +569,20 @@ | ||
569 | "hide-details": "Hide details", | 569 | "hide-details": "Hide details", |
570 | "select-state": "Select target state", | 570 | "select-state": "Select target state", |
571 | "state-controller": "State controller", | 571 | "state-controller": "State controller", |
572 | - "manage-assigned-edges": "Manage assigned edges" | 572 | + "manage-assigned-edges": "Manage assigned edges", |
573 | + "unassign-dashboard-from-edge-text": "After the confirmation the dashboard will be unassigned and won't be accessible by the edge.", | ||
574 | + "assigned-edges": "Assigned edges", | ||
575 | + "unassign-from-edge": "Unassign from edge", | ||
576 | + "unassign-dashboards-from-edge-action-title": "Unassign { count, plural, 1 {1 dashboard} other {# dashboards} } from edge", | ||
577 | + "unassign-dashboards-from-edge-text": "After the confirmation all selected dashboards will be unassigned and won't be accessible by the edge.", | ||
578 | + "assign-dashboard-to-edge": "Assign Dashboard(s) To Edge", | ||
579 | + "assign-dashboard-to-edge-text": "Please select the dashboards to assign to the edge", | ||
580 | + "assign-dashboards-to-edge-text": "Assign { count, plural, 1 {1 dashboard} other {# dashboards} } to edges", | ||
581 | + "unassign-dashboards-from-edge-action-text": "Unassign { count, plural, 1 {1 dashboard} other {# dashboards} } from edges", | ||
582 | + "assign-to-edges": "Assign Dashboard(s) To Edges", | ||
583 | + "assign-to-edges-text": "Please select the edges to assign the dashboard(s)", | ||
584 | + "unassign-from-edges": "Unassign Dashboard(s) From Edges", | ||
585 | + "unassign-from-edges-text": "Please select the edges to unassign from the dashboard(s)" | ||
573 | }, | 586 | }, |
574 | "datakey": { | 587 | "datakey": { |
575 | "settings": "Settings", | 588 | "settings": "Settings", |
@@ -759,7 +772,10 @@ | @@ -759,7 +772,10 @@ | ||
759 | "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", | 772 | "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", |
760 | "import": "Import edge", | 773 | "import": "Import edge", |
761 | "label": "Label", | 774 | "label": "Label", |
762 | - "assign-new-edge": "Assign new edge" | 775 | + "assign-new-edge": "Assign new edge", |
776 | + "manage-edge-dashboards": "Manage edge dashboards", | ||
777 | + "unassign-from-edge": "Unassign from edge", | ||
778 | + "dashboards": "Edge Dashboards" | ||
763 | }, | 779 | }, |
764 | "error": { | 780 | "error": { |
765 | "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", | 781 | "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", |
@@ -188,7 +188,7 @@ function Menu(userService, $state, $rootScope) { | @@ -188,7 +188,7 @@ function Menu(userService, $state, $rootScope) { | ||
188 | name: 'edge.edges', | 188 | name: 'edge.edges', |
189 | type: 'link', | 189 | type: 'link', |
190 | state: 'home.edges', | 190 | state: 'home.edges', |
191 | - icon: 'toys' | 191 | + icon: 'router' |
192 | }, | 192 | }, |
193 | { | 193 | { |
194 | name: 'widget.widget-library', | 194 | name: 'widget.widget-library', |
@@ -265,7 +265,7 @@ function Menu(userService, $state, $rootScope) { | @@ -265,7 +265,7 @@ function Menu(userService, $state, $rootScope) { | ||
265 | places: [ | 265 | places: [ |
266 | { | 266 | { |
267 | name: 'edge.edges', | 267 | name: 'edge.edges', |
268 | - icon: 'toys', | 268 | + icon: 'router', |
269 | state: 'home.edges' | 269 | state: 'home.edges' |
270 | } | 270 | } |
271 | ] | 271 | ] |
@@ -326,7 +326,7 @@ function Menu(userService, $state, $rootScope) { | @@ -326,7 +326,7 @@ function Menu(userService, $state, $rootScope) { | ||
326 | name: 'edge.edges', | 326 | name: 'edge.edges', |
327 | type: 'link', | 327 | type: 'link', |
328 | state: 'home.edges', | 328 | state: 'home.edges', |
329 | - icon: 'toys' | 329 | + icon: 'router' |
330 | }, | 330 | }, |
331 | { | 331 | { |
332 | name: 'dashboard.dashboards', | 332 | name: 'dashboard.dashboards', |
@@ -371,7 +371,7 @@ function Menu(userService, $state, $rootScope) { | @@ -371,7 +371,7 @@ function Menu(userService, $state, $rootScope) { | ||
371 | places: [ | 371 | places: [ |
372 | { | 372 | { |
373 | name: 'edge.edges', | 373 | name: 'edge.edges', |
374 | - icon: 'toys', | 374 | + icon: 'router', |
375 | state: 'home.edges' | 375 | state: 'home.edges' |
376 | } | 376 | } |
377 | ] | 377 | ] |