Commit b45bee7843a428d3401ad22b4200a2e754201f75
Merge remote-tracking branch 'origin/develop/2.6-edge' into develop/3.3-edge
Showing
36 changed files
with
161 additions
and
3409 deletions
... | ... | @@ -18,6 +18,7 @@ package org.thingsboard.server.service.edge.rpc; |
18 | 18 | import com.datastax.oss.driver.api.core.uuid.Uuids; |
19 | 19 | import com.fasterxml.jackson.core.JsonProcessingException; |
20 | 20 | import com.fasterxml.jackson.databind.ObjectMapper; |
21 | +import com.fasterxml.jackson.databind.node.ObjectNode; | |
21 | 22 | import com.google.common.util.concurrent.FutureCallback; |
22 | 23 | import com.google.common.util.concurrent.Futures; |
23 | 24 | import com.google.common.util.concurrent.ListenableFuture; |
... | ... | @@ -342,8 +343,8 @@ public final class EdgeGrpcSession implements Closeable { |
342 | 343 | case CREDENTIALS_REQUEST: |
343 | 344 | downlinkMsg = processCredentialsRequestMessage(edgeEvent); |
344 | 345 | break; |
345 | - case ENTITY_EXISTS_REQUEST: | |
346 | - downlinkMsg = processEntityExistsRequestMessage(edgeEvent); | |
346 | + case ENTITY_MERGE_REQUEST: | |
347 | + downlinkMsg = processEntityMergeRequestMessage(edgeEvent); | |
347 | 348 | break; |
348 | 349 | case RPC_CALL: |
349 | 350 | downlinkMsg = processRpcCallMsg(edgeEvent); |
... | ... | @@ -359,13 +360,18 @@ public final class EdgeGrpcSession implements Closeable { |
359 | 360 | return result; |
360 | 361 | } |
361 | 362 | |
362 | - private DownlinkMsg processEntityExistsRequestMessage(EdgeEvent edgeEvent) { | |
363 | + private DownlinkMsg processEntityMergeRequestMessage(EdgeEvent edgeEvent) { | |
363 | 364 | DownlinkMsg downlinkMsg = null; |
364 | 365 | if (EdgeEventType.DEVICE.equals(edgeEvent.getType())) { |
365 | 366 | DeviceId deviceId = new DeviceId(edgeEvent.getEntityId()); |
366 | 367 | Device device = ctx.getDeviceService().findDeviceById(edge.getTenantId(), deviceId); |
367 | 368 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); |
368 | - DeviceUpdateMsg d = ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(UpdateMsgType.DEVICE_CONFLICT_RPC_MESSAGE, device, customerId); | |
369 | + String conflictName = null; | |
370 | + if(edgeEvent.getBody() != null) { | |
371 | + conflictName = edgeEvent.getBody().get("conflictName").asText(); | |
372 | + } | |
373 | + DeviceUpdateMsg d = ctx.getDeviceMsgConstructor() | |
374 | + .constructDeviceUpdatedMsg(UpdateMsgType.ENTITY_MERGE_RPC_MESSAGE, device, customerId, conflictName); | |
369 | 375 | downlinkMsg = DownlinkMsg.newBuilder() |
370 | 376 | .addAllDeviceUpdateMsg(Collections.singletonList(d)) |
371 | 377 | .build(); |
... | ... | @@ -504,7 +510,7 @@ public final class EdgeGrpcSession implements Closeable { |
504 | 510 | if (device != null) { |
505 | 511 | CustomerId customerId = getCustomerIdIfEdgeAssignedToCustomer(device); |
506 | 512 | DeviceUpdateMsg deviceUpdateMsg = |
507 | - ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId); | |
513 | + ctx.getDeviceMsgConstructor().constructDeviceUpdatedMsg(msgType, device, customerId, null); | |
508 | 514 | downlinkMsg = DownlinkMsg.newBuilder() |
509 | 515 | .addAllDeviceUpdateMsg(Collections.singletonList(deviceUpdateMsg)) |
510 | 516 | .build(); | ... | ... |
... | ... | @@ -38,7 +38,7 @@ public class DeviceMsgConstructor { |
38 | 38 | |
39 | 39 | protected static final ObjectMapper mapper = new ObjectMapper(); |
40 | 40 | |
41 | - public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId) { | |
41 | + public DeviceUpdateMsg constructDeviceUpdatedMsg(UpdateMsgType msgType, Device device, CustomerId customerId, String conflictName) { | |
42 | 42 | DeviceUpdateMsg.Builder builder = DeviceUpdateMsg.newBuilder() |
43 | 43 | .setMsgType(msgType) |
44 | 44 | .setIdMSB(device.getId().getId().getMostSignificantBits()) |
... | ... | @@ -55,6 +55,9 @@ public class DeviceMsgConstructor { |
55 | 55 | if (device.getAdditionalInfo() != null) { |
56 | 56 | builder.setAdditionalInfo(JacksonUtil.toString(device.getAdditionalInfo())); |
57 | 57 | } |
58 | + if (conflictName != null) { | |
59 | + builder.setConflictName(conflictName); | |
60 | + } | |
58 | 61 | return builder.build(); |
59 | 62 | } |
60 | 63 | ... | ... |
... | ... | @@ -37,6 +37,7 @@ import org.thingsboard.server.dao.dashboard.DashboardService; |
37 | 37 | import org.thingsboard.server.dao.device.DeviceCredentialsService; |
38 | 38 | import org.thingsboard.server.dao.device.DeviceService; |
39 | 39 | import org.thingsboard.server.dao.edge.EdgeEventService; |
40 | +import org.thingsboard.server.dao.edge.EdgeService; | |
40 | 41 | import org.thingsboard.server.dao.entityview.EntityViewService; |
41 | 42 | import org.thingsboard.server.dao.relation.RelationService; |
42 | 43 | import org.thingsboard.server.dao.user.UserService; |
... | ... | @@ -65,6 +66,9 @@ public abstract class BaseProcessor { |
65 | 66 | protected EntityViewService entityViewService; |
66 | 67 | |
67 | 68 | @Autowired |
69 | + protected EdgeService edgeService; | |
70 | + | |
71 | + @Autowired | |
68 | 72 | protected CustomerService customerService; |
69 | 73 | |
70 | 74 | @Autowired | ... | ... |
... | ... | @@ -17,12 +17,14 @@ package org.thingsboard.server.service.edge.rpc.processor; |
17 | 17 | |
18 | 18 | import com.fasterxml.jackson.core.JsonProcessingException; |
19 | 19 | import com.fasterxml.jackson.databind.node.ObjectNode; |
20 | +import com.google.common.util.concurrent.FutureCallback; | |
20 | 21 | import com.google.common.util.concurrent.Futures; |
21 | 22 | import com.google.common.util.concurrent.ListenableFuture; |
22 | 23 | import com.google.common.util.concurrent.SettableFuture; |
23 | 24 | import lombok.extern.slf4j.Slf4j; |
24 | 25 | import org.apache.commons.lang.RandomStringUtils; |
25 | 26 | import org.apache.commons.lang.StringUtils; |
27 | +import org.checkerframework.checker.nullness.qual.Nullable; | |
26 | 28 | import org.springframework.stereotype.Component; |
27 | 29 | import org.thingsboard.rule.engine.api.RpcError; |
28 | 30 | import org.thingsboard.server.common.data.DataConstants; |
... | ... | @@ -52,6 +54,7 @@ import org.thingsboard.server.queue.util.TbCoreComponent; |
52 | 54 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponse; |
53 | 55 | import org.thingsboard.server.service.rpc.FromDeviceRpcResponseActorMsg; |
54 | 56 | |
57 | +import java.util.List; | |
55 | 58 | import java.util.UUID; |
56 | 59 | import java.util.concurrent.locks.ReentrantLock; |
57 | 60 | |
... | ... | @@ -64,38 +67,62 @@ public class DeviceProcessor extends BaseProcessor { |
64 | 67 | |
65 | 68 | public ListenableFuture<Void> onDeviceUpdate(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { |
66 | 69 | log.trace("[{}] onDeviceUpdate [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); |
67 | - DeviceId edgeDeviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | |
68 | 70 | switch (deviceUpdateMsg.getMsgType()) { |
69 | 71 | case ENTITY_CREATED_RPC_MESSAGE: |
70 | 72 | String deviceName = deviceUpdateMsg.getName(); |
71 | 73 | Device device = deviceService.findDeviceByTenantIdAndName(tenantId, deviceName); |
72 | 74 | if (device != null) { |
73 | - log.info("[{}] Device with name '{}' already exists on the cloud. Updating id of device entity on the edge", tenantId, deviceName); | |
74 | - if (!device.getId().equals(edgeDeviceId)) { | |
75 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); | |
76 | - } | |
77 | - } else { | |
78 | - Device deviceById = deviceService.findDeviceById(edge.getTenantId(), edgeDeviceId); | |
79 | - if (deviceById != null) { | |
80 | - log.info("[{}] Device ID [{}] already used by other device on the cloud. Creating new device and replacing device entity on the edge", tenantId, edgeDeviceId.getId()); | |
81 | - device = createDevice(tenantId, edge, deviceUpdateMsg); | |
75 | + ListenableFuture<List<EdgeId>> future = edgeService.findRelatedEdgeIdsByEntityId(tenantId, device.getId()); | |
76 | + SettableFuture<Void> futureToSet = SettableFuture.create(); | |
77 | + Futures.addCallback(future, new FutureCallback<List<EdgeId>>() { | |
78 | + @Override | |
79 | + public void onSuccess(@Nullable List<EdgeId> edgeIds) { | |
80 | + boolean update = false; | |
81 | + if (edgeIds != null && !edgeIds.isEmpty()) { | |
82 | + if (edgeIds.contains(edge.getId())) { | |
83 | + update = true; | |
84 | + } | |
85 | + } | |
86 | + Device device; | |
87 | + if (update) { | |
88 | + log.info("[{}] Device with name '{}' already exists on the cloud, and related to this edge [{}]. " + | |
89 | + "deviceUpdateMsg [{}], Updating device", tenantId, deviceName, edge.getId(), deviceUpdateMsg); | |
90 | + updateDevice(tenantId, edge, deviceUpdateMsg); | |
91 | + } else { | |
92 | + log.info("[{}] Device with name '{}' already exists on the cloud, but not related to this edge [{}]. deviceUpdateMsg [{}]." + | |
93 | + "Creating a new device with random prefix and relate to this edge", tenantId, deviceName, edge.getId(), deviceUpdateMsg); | |
94 | + String newDeviceName = deviceUpdateMsg.getName() + "_" + RandomStringUtils.randomAlphabetic(15); | |
95 | + device = createDevice(tenantId, edge, deviceUpdateMsg, newDeviceName); | |
96 | + ObjectNode body = mapper.createObjectNode(); | |
97 | + body.put("conflictName", deviceName); | |
98 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), body); | |
99 | + deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | |
100 | + } | |
101 | + futureToSet.set(null); | |
102 | + } | |
82 | 103 | |
83 | - // TODO: voba - properly handle device credentials from edge to cloud | |
84 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_EXISTS_REQUEST, device.getId(), null); | |
85 | - } else { | |
86 | - device = createDevice(tenantId, edge, deviceUpdateMsg); | |
87 | - } | |
104 | + @Override | |
105 | + public void onFailure(Throwable t) { | |
106 | + log.error("[{}] Failed to get related edge ids by device id [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId(), t); | |
107 | + futureToSet.setException(t); | |
108 | + } | |
109 | + }, dbCallbackExecutorService); | |
110 | + return futureToSet; | |
111 | + } else { | |
112 | + log.info("[{}] Creating new device and replacing device entity on the edge [{}]", tenantId, deviceUpdateMsg); | |
113 | + device = createDevice(tenantId, edge, deviceUpdateMsg, deviceUpdateMsg.getName()); | |
114 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.ENTITY_MERGE_REQUEST, device.getId(), null); | |
115 | + deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | |
88 | 116 | } |
89 | - // TODO: voba - assign device only in case device is not assigned yet. Missing functionality to check this relation prior assignment | |
90 | - deviceService.assignDeviceToEdge(edge.getTenantId(), device.getId(), edge.getId()); | |
91 | 117 | break; |
92 | 118 | case ENTITY_UPDATED_RPC_MESSAGE: |
93 | 119 | updateDevice(tenantId, edge, deviceUpdateMsg); |
94 | 120 | break; |
95 | 121 | case ENTITY_DELETED_RPC_MESSAGE: |
96 | - Device deviceToDelete = deviceService.findDeviceById(tenantId, edgeDeviceId); | |
122 | + DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | |
123 | + Device deviceToDelete = deviceService.findDeviceById(tenantId, deviceId); | |
97 | 124 | if (deviceToDelete != null) { |
98 | - deviceService.unassignDeviceFromEdge(tenantId, edgeDeviceId, edge.getId()); | |
125 | + deviceService.unassignDeviceFromEdge(tenantId, deviceId, edge.getId()); | |
99 | 126 | } |
100 | 127 | break; |
101 | 128 | case UNRECOGNIZED: |
... | ... | @@ -105,7 +132,6 @@ public class DeviceProcessor extends BaseProcessor { |
105 | 132 | return Futures.immediateFuture(null); |
106 | 133 | } |
107 | 134 | |
108 | - | |
109 | 135 | public ListenableFuture<Void> onDeviceCredentialsUpdate(TenantId tenantId, DeviceCredentialsUpdateMsg deviceCredentialsUpdateMsg) { |
110 | 136 | log.debug("Executing onDeviceCredentialsUpdate, deviceCredentialsUpdateMsg [{}]", deviceCredentialsUpdateMsg); |
111 | 137 | DeviceId deviceId = new DeviceId(new UUID(deviceCredentialsUpdateMsg.getDeviceIdMSB(), deviceCredentialsUpdateMsg.getDeviceIdLSB())); |
... | ... | @@ -133,37 +159,34 @@ public class DeviceProcessor extends BaseProcessor { |
133 | 159 | private void updateDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { |
134 | 160 | DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); |
135 | 161 | Device device = deviceService.findDeviceById(tenantId, deviceId); |
136 | - device.setName(deviceUpdateMsg.getName()); | |
137 | - device.setType(deviceUpdateMsg.getType()); | |
138 | - device.setLabel(deviceUpdateMsg.getLabel()); | |
139 | - device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | |
140 | - deviceService.saveDevice(device); | |
141 | - | |
142 | - saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | |
162 | + if (device != null) { | |
163 | + device.setName(deviceUpdateMsg.getName()); | |
164 | + device.setType(deviceUpdateMsg.getType()); | |
165 | + device.setLabel(deviceUpdateMsg.getLabel()); | |
166 | + device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); | |
167 | + deviceService.saveDevice(device); | |
168 | + saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | |
169 | + } else { | |
170 | + log.warn("[{}] can't find device [{}], edge [{}]", tenantId, deviceUpdateMsg, edge.getId()); | |
171 | + } | |
143 | 172 | } |
144 | 173 | |
145 | - private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg) { | |
174 | + private Device createDevice(TenantId tenantId, Edge edge, DeviceUpdateMsg deviceUpdateMsg, String deviceName) { | |
146 | 175 | Device device; |
147 | 176 | try { |
148 | 177 | deviceCreationLock.lock(); |
149 | 178 | log.debug("[{}] Creating device entity [{}] from edge [{}]", tenantId, deviceUpdateMsg, edge.getName()); |
150 | -// DeviceId deviceId = new DeviceId(new UUID(deviceUpdateMsg.getIdMSB(), deviceUpdateMsg.getIdLSB())); | |
151 | 179 | device = new Device(); |
152 | -// device.setId(deviceId); | |
153 | 180 | device.setTenantId(edge.getTenantId()); |
154 | 181 | device.setCustomerId(edge.getCustomerId()); |
155 | - device.setName(deviceUpdateMsg.getName()); | |
182 | + device.setName(deviceName); | |
156 | 183 | device.setType(deviceUpdateMsg.getType()); |
157 | 184 | device.setLabel(deviceUpdateMsg.getLabel()); |
158 | 185 | device.setAdditionalInfo(JacksonUtil.toJsonNode(deviceUpdateMsg.getAdditionalInfo())); |
159 | 186 | device = deviceService.saveDevice(device); |
160 | - // TODO: voba - is this still required? | |
161 | -// createDeviceCredentials(device); | |
162 | 187 | createRelationFromEdge(tenantId, edge.getId(), device.getId()); |
163 | 188 | deviceStateService.onDeviceAdded(device); |
164 | 189 | pushDeviceCreatedEventToRuleEngine(tenantId, edge, device); |
165 | - | |
166 | - // saveEdgeEvent(tenantId, edge.getId(), EdgeEventType.DEVICE, EdgeEventActionType.CREDENTIALS_REQUEST, deviceId, null); | |
167 | 190 | } finally { |
168 | 191 | deviceCreationLock.unlock(); |
169 | 192 | } |
... | ... | @@ -179,14 +202,6 @@ public class DeviceProcessor extends BaseProcessor { |
179 | 202 | relationService.saveRelation(tenantId, relation); |
180 | 203 | } |
181 | 204 | |
182 | - private void createDeviceCredentials(Device device) { | |
183 | - DeviceCredentials deviceCredentials = new DeviceCredentials(); | |
184 | - deviceCredentials.setDeviceId(device.getId()); | |
185 | - deviceCredentials.setCredentialsType(DeviceCredentialsType.ACCESS_TOKEN); | |
186 | - deviceCredentials.setCredentialsId(RandomStringUtils.randomAlphanumeric(20)); | |
187 | - deviceCredentialsService.createDeviceCredentials(device.getTenantId(), deviceCredentials); | |
188 | - } | |
189 | - | |
190 | 205 | private void pushDeviceCreatedEventToRuleEngine(TenantId tenantId, Edge edge, Device device) { |
191 | 206 | try { |
192 | 207 | DeviceId deviceId = device.getId(); | ... | ... |
... | ... | @@ -26,6 +26,7 @@ import com.google.protobuf.AbstractMessage; |
26 | 26 | import com.google.protobuf.InvalidProtocolBufferException; |
27 | 27 | import com.google.protobuf.MessageLite; |
28 | 28 | import lombok.extern.slf4j.Slf4j; |
29 | +import org.apache.commons.lang.RandomStringUtils; | |
29 | 30 | import org.junit.After; |
30 | 31 | import org.junit.Assert; |
31 | 32 | import org.junit.Before; |
... | ... | @@ -962,6 +963,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { |
962 | 963 | private void testSendMessagesToCloud() throws Exception { |
963 | 964 | log.info("Sending messages to cloud"); |
964 | 965 | sendDevice(); |
966 | + sendDeviceWithNameThatAlreadyExistsOnCloud(); | |
965 | 967 | sendRelationRequest(); |
966 | 968 | sendAlarm(); |
967 | 969 | sendTelemetry(); |
... | ... | @@ -972,8 +974,7 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { |
972 | 974 | sendDeviceCredentialsRequest(); |
973 | 975 | sendDeviceRpcResponse(); |
974 | 976 | sendDeviceCredentialsUpdate(); |
975 | - // TODO: voba - fix this test | |
976 | - // sendAttributesRequest(); | |
977 | + sendAttributesRequest(); | |
977 | 978 | log.info("Messages were sent successfully"); |
978 | 979 | } |
979 | 980 | |
... | ... | @@ -991,17 +992,64 @@ abstract public class BaseEdgeTest extends AbstractControllerTest { |
991 | 992 | uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); |
992 | 993 | |
993 | 994 | edgeImitator.expectResponsesAmount(1); |
995 | + edgeImitator.expectMessageAmount(1); | |
996 | + testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); | |
997 | + | |
998 | + edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); | |
999 | + | |
1000 | + edgeImitator.waitForResponses(); | |
1001 | + edgeImitator.waitForMessages(); | |
1002 | + | |
1003 | + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | |
1004 | + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | |
1005 | + DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | |
1006 | + Assert.assertEquals("Edge Device 2", latestDeviceUpdateMsg.getName()); | |
1007 | + | |
1008 | + UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); | |
1009 | + | |
1010 | + Device device = doGet("/api/device/" + newDeviceId, Device.class); | |
1011 | + Assert.assertNotNull(device); | |
1012 | + Assert.assertEquals("Edge Device 2", device.getName()); | |
1013 | + } | |
994 | 1014 | |
1015 | + private void sendDeviceWithNameThatAlreadyExistsOnCloud() throws Exception { | |
1016 | + String deviceOnCloudName = RandomStringUtils.randomAlphanumeric(15); | |
1017 | + Device deviceOnCloud = saveDevice(deviceOnCloudName); | |
1018 | + | |
1019 | + UUID uuid = Uuids.timeBased(); | |
1020 | + | |
1021 | + UplinkMsg.Builder uplinkMsgBuilder = UplinkMsg.newBuilder(); | |
1022 | + DeviceUpdateMsg.Builder deviceUpdateMsgBuilder = DeviceUpdateMsg.newBuilder(); | |
1023 | + deviceUpdateMsgBuilder.setIdMSB(uuid.getMostSignificantBits()); | |
1024 | + deviceUpdateMsgBuilder.setIdLSB(uuid.getLeastSignificantBits()); | |
1025 | + deviceUpdateMsgBuilder.setName(deviceOnCloudName); | |
1026 | + deviceUpdateMsgBuilder.setType("test"); | |
1027 | + deviceUpdateMsgBuilder.setMsgType(UpdateMsgType.ENTITY_CREATED_RPC_MESSAGE); | |
1028 | + testAutoGeneratedCodeByProtobuf(deviceUpdateMsgBuilder); | |
1029 | + uplinkMsgBuilder.addDeviceUpdateMsg(deviceUpdateMsgBuilder.build()); | |
1030 | + | |
1031 | + edgeImitator.expectResponsesAmount(1); | |
1032 | + edgeImitator.expectMessageAmount(1); | |
995 | 1033 | testAutoGeneratedCodeByProtobuf(uplinkMsgBuilder); |
996 | 1034 | |
997 | 1035 | edgeImitator.sendUplinkMsg(uplinkMsgBuilder.build()); |
1036 | + | |
998 | 1037 | edgeImitator.waitForResponses(); |
1038 | + edgeImitator.waitForMessages(); | |
1039 | + | |
1040 | + AbstractMessage latestMessage = edgeImitator.getLatestMessage(); | |
1041 | + Assert.assertTrue(latestMessage instanceof DeviceUpdateMsg); | |
1042 | + DeviceUpdateMsg latestDeviceUpdateMsg = (DeviceUpdateMsg) latestMessage; | |
1043 | + Assert.assertNotEquals(deviceOnCloudName, latestDeviceUpdateMsg.getName()); | |
1044 | + Assert.assertEquals(deviceOnCloudName, latestDeviceUpdateMsg.getConflictName()); | |
999 | 1045 | |
1000 | - // TODO: voba - add proper validation once DeviceProcessor | |
1046 | + UUID newDeviceId = new UUID(latestDeviceUpdateMsg.getIdMSB(), latestDeviceUpdateMsg.getIdLSB()); | |
1001 | 1047 | |
1002 | -// Device device = doGet("/api/device/" + uuid.toString(), Device.class); | |
1003 | -// Assert.assertNotNull(device); | |
1004 | -// Assert.assertEquals("Edge Device 2", device.getName()); | |
1048 | + Assert.assertNotEquals(deviceOnCloud.getId().getId(), newDeviceId); | |
1049 | + | |
1050 | + Device device = doGet("/api/device/" + newDeviceId, Device.class); | |
1051 | + Assert.assertNotNull(device); | |
1052 | + Assert.assertNotEquals(deviceOnCloudName, device.getName()); | |
1005 | 1053 | } |
1006 | 1054 | |
1007 | 1055 | private void sendRelationRequest() throws Exception { | ... | ... |
... | ... | @@ -97,7 +97,7 @@ enum UpdateMsgType { |
97 | 97 | ENTITY_DELETED_RPC_MESSAGE = 2; |
98 | 98 | ALARM_ACK_RPC_MESSAGE = 3; |
99 | 99 | ALARM_CLEAR_RPC_MESSAGE = 4; |
100 | - DEVICE_CONFLICT_RPC_MESSAGE = 5; | |
100 | + ENTITY_MERGE_RPC_MESSAGE = 5; | |
101 | 101 | } |
102 | 102 | |
103 | 103 | message EntityDataProto { |
... | ... | @@ -182,6 +182,7 @@ message DeviceUpdateMsg { |
182 | 182 | string type = 7; |
183 | 183 | string label = 8; |
184 | 184 | string additionalInfo = 9; |
185 | + string conflictName = 10; | |
185 | 186 | } |
186 | 187 | |
187 | 188 | message DeviceCredentialsUpdateMsg { | ... | ... |
... | ... | @@ -109,6 +109,7 @@ import org.thingsboard.server.common.data.rule.DefaultRuleChainCreateRequest; |
109 | 109 | import org.thingsboard.server.common.data.rule.RuleChain; |
110 | 110 | import org.thingsboard.server.common.data.rule.RuleChainData; |
111 | 111 | import org.thingsboard.server.common.data.rule.RuleChainMetaData; |
112 | +import org.thingsboard.server.common.data.rule.RuleChainType; | |
112 | 113 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
113 | 114 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
114 | 115 | import org.thingsboard.server.common.data.security.model.SecuritySettings; |
... | ... | @@ -120,6 +121,7 @@ import org.thingsboard.server.common.data.widget.WidgetsBundle; |
120 | 121 | import java.io.Closeable; |
121 | 122 | import java.io.IOException; |
122 | 123 | import java.net.URI; |
124 | +import java.util.Arrays; | |
123 | 125 | import java.util.Collections; |
124 | 126 | import java.util.HashMap; |
125 | 127 | import java.util.List; |
... | ... | @@ -700,22 +702,31 @@ public class RestClient implements ClientHttpRequestInterceptor, Closeable { |
700 | 702 | } |
701 | 703 | |
702 | 704 | public List<ComponentDescriptor> getComponentDescriptorsByType(ComponentType componentType) { |
705 | + return getComponentDescriptorsByType(componentType, RuleChainType.CORE); | |
706 | + } | |
707 | + | |
708 | + public List<ComponentDescriptor> getComponentDescriptorsByType(ComponentType componentType, RuleChainType ruleChainType) { | |
703 | 709 | return restTemplate.exchange( |
704 | - baseURL + "/api/components?componentType={componentType}", | |
710 | + baseURL + "/api/components/" + componentType.name() + "/?ruleChainType={ruleChainType}", | |
705 | 711 | HttpMethod.GET, HttpEntity.EMPTY, |
706 | 712 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { |
707 | 713 | }, |
708 | - componentType).getBody(); | |
714 | + ruleChainType).getBody(); | |
709 | 715 | } |
710 | 716 | |
711 | 717 | public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<ComponentType> componentTypes) { |
718 | + return getComponentDescriptorsByTypes(componentTypes, RuleChainType.CORE); | |
719 | + } | |
720 | + | |
721 | + public List<ComponentDescriptor> getComponentDescriptorsByTypes(List<ComponentType> componentTypes, RuleChainType ruleChainType) { | |
712 | 722 | return restTemplate.exchange( |
713 | - baseURL + "/api/components?componentTypes={componentTypes}", | |
723 | + baseURL + "/api/components?componentTypes={componentTypes}&ruleChainType={ruleChainType}", | |
714 | 724 | HttpMethod.GET, |
715 | 725 | HttpEntity.EMPTY, |
716 | 726 | new ParameterizedTypeReference<List<ComponentDescriptor>>() { |
717 | 727 | }, |
718 | - listEnumToString(componentTypes)) | |
728 | + listEnumToString(componentTypes), | |
729 | + ruleChainType) | |
719 | 730 | .getBody(); |
720 | 731 | } |
721 | 732 | ... | ... |
... | ... | @@ -1117,6 +1117,7 @@ |
1117 | 1117 | "edge": { |
1118 | 1118 | "edge": "Edge", |
1119 | 1119 | "edges": "Edges", |
1120 | + "edge-file": "Edge file", | |
1120 | 1121 | "management": "Edge management", |
1121 | 1122 | "no-edges-matching": "No edges matching '{{entity}}' were found.", |
1122 | 1123 | "add": "Add Edge", |
... | ... | @@ -1173,17 +1174,19 @@ |
1173 | 1174 | "make-private-edge-text": "After the confirmation the edge and all its data will be made private and won't be accessible by others.", |
1174 | 1175 | "import": "Import edge", |
1175 | 1176 | "label": "Label", |
1176 | - "load-entity-error": "Entity not found. Failed to load info", | |
1177 | + "load-entity-error": "Failed to load data. Entity not found or has been deleted.", | |
1177 | 1178 | "assign-new-edge": "Assign new edge", |
1178 | 1179 | "manage-edge-dashboards": "Manage edge dashboards", |
1179 | 1180 | "unassign-from-edge": "Unassign from edge", |
1180 | 1181 | "dashboards": "Edge Dashboards", |
1181 | 1182 | "manage-edge-rulechains": "Manage edge rule chains", |
1183 | + "rulechains": "Edge Rule Chains", | |
1184 | + "rulechain": "Edge Rule Chain", | |
1182 | 1185 | "edge-key": "Edge key", |
1183 | - "copy-edge-key": "Copy Edge key", | |
1186 | + "copy-edge-key": "Copy edge key", | |
1184 | 1187 | "edge-key-copied-message": "Edge key has been copied to clipboard", |
1185 | 1188 | "edge-secret": "Edge secret", |
1186 | - "copy-edge-secret": "Copy Edge secret", | |
1189 | + "copy-edge-secret": "Copy edge secret", | |
1187 | 1190 | "edge-secret-copied-message": "Edge secret has been copied to clipboard", |
1188 | 1191 | "manage-edge-assets": "Manage edge assets", |
1189 | 1192 | "manage-edge-devices": "Manage edge devices", |
... | ... | @@ -1191,22 +1194,23 @@ |
1191 | 1194 | "assets": "Edge assets", |
1192 | 1195 | "devices": "Edge devices", |
1193 | 1196 | "entity-views": "Edge entity views", |
1194 | - "set-root-rulechain-text": "Please select root rule chain for edge(s)", | |
1195 | - "set-root-rulechain-to-edges": "Set root rule chain for Edge(s)", | |
1196 | - "set-root-rulechain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", | |
1197 | + "set-root-rule-chain-text": "Please select root rule chain for edge(s)", | |
1198 | + "set-root-rule-chain-to-edges": "Set root rule chain for Edge(s)", | |
1199 | + "set-root-rule-chain-to-edges-text": "Set root rule chain for { count, plural, 1 {1 edge} other {# edges} }", | |
1197 | 1200 | "status": "Received by edge", |
1198 | 1201 | "success": "Deployed", |
1199 | 1202 | "failed": "Pending", |
1200 | 1203 | "search": "Search edges", |
1201 | 1204 | "selected-edges": "{ count, plural, 1 {1 edge} other {# edges} } selected", |
1202 | - "enter-edge-type": "Enter entity view type", | |
1203 | 1205 | "any-edge": "Any edge", |
1204 | 1206 | "no-edge-types-matching": "No edge types matching '{{entitySubtype}}' were found.", |
1205 | 1207 | "edge-type-list-empty": "No device types selected.", |
1206 | 1208 | "edge-types": "Edge types", |
1207 | 1209 | "dashboard": "Edge dashboard", |
1208 | 1210 | "unassign-edges-action-title": "Unassign { count, plural, 1 {1 edge} other {# edges} } from customer", |
1209 | - "enter-edge-type": "Enter edge type" | |
1211 | + "enter-edge-type": "Enter edge type", | |
1212 | + "deployed": "Deployed", | |
1213 | + "pending": "Pending" | |
1210 | 1214 | }, |
1211 | 1215 | "error": { |
1212 | 1216 | "unable-to-connect": "Unable to connect to the server! Please check your internet connection.", | ... | ... |
ui/src/app/api/edge.service.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 | -export default angular.module('thingsboard.api.edge', []) | |
17 | - .factory('edgeService', EdgeService) | |
18 | - .name; | |
19 | - | |
20 | -/*@ngInject*/ | |
21 | -function EdgeService($http, $q, customerService) { | |
22 | - | |
23 | - var service = { | |
24 | - getEdges: getEdges, | |
25 | - getEdgesByIds: getEdgesByIds, | |
26 | - getEdge: getEdge, | |
27 | - deleteEdge: deleteEdge, | |
28 | - saveEdge: saveEdge, | |
29 | - getEdgeTypes: getEdgeTypes, | |
30 | - getTenantEdges: getTenantEdges, | |
31 | - getCustomerEdges: getCustomerEdges, | |
32 | - assignEdgeToCustomer: assignEdgeToCustomer, | |
33 | - unassignEdgeFromCustomer: unassignEdgeFromCustomer, | |
34 | - makeEdgePublic: makeEdgePublic, | |
35 | - setRootRuleChain: setRootRuleChain, | |
36 | - getEdgeEvents: getEdgeEvents, | |
37 | - syncEdge: syncEdge | |
38 | - }; | |
39 | - | |
40 | - return service; | |
41 | - | |
42 | - function getEdges(pageLink, config) { | |
43 | - var deferred = $q.defer(); | |
44 | - var url = '/api/edges?limit=' + pageLink.limit; | |
45 | - if (angular.isDefined(pageLink.textSearch)) { | |
46 | - url += '&textSearch=' + pageLink.textSearch; | |
47 | - } | |
48 | - if (angular.isDefined(pageLink.idOffset)) { | |
49 | - url += '&idOffset=' + pageLink.idOffset; | |
50 | - } | |
51 | - if (angular.isDefined(pageLink.textOffset)) { | |
52 | - url += '&textOffset=' + pageLink.textOffset; | |
53 | - } | |
54 | - $http.get(url, config).then(function success(response) { | |
55 | - deferred.resolve(response.data); | |
56 | - }, function fail() { | |
57 | - deferred.reject(); | |
58 | - }); | |
59 | - return deferred.promise; | |
60 | - } | |
61 | - | |
62 | - function getEdgesByIds(edgeIds, config) { | |
63 | - var deferred = $q.defer(); | |
64 | - var ids = ''; | |
65 | - for (var i=0;i<edgeIds.length;i++) { | |
66 | - if (i>0) { | |
67 | - ids += ','; | |
68 | - } | |
69 | - ids += edgeIds[i]; | |
70 | - } | |
71 | - var url = '/api/edges?edgeIds=' + ids; | |
72 | - $http.get(url, config).then(function success(response) { | |
73 | - var entities = response.data; | |
74 | - entities.sort(function (entity1, entity2) { | |
75 | - var id1 = entity1.id.id; | |
76 | - var id2 = entity2.id.id; | |
77 | - var index1 = edgeIds.indexOf(id1); | |
78 | - var index2 = edgeIds.indexOf(id2); | |
79 | - return index1 - index2; | |
80 | - }); | |
81 | - deferred.resolve(entities); | |
82 | - }, function fail() { | |
83 | - deferred.reject(); | |
84 | - }); | |
85 | - return deferred.promise; | |
86 | - } | |
87 | - | |
88 | - function getEdge(edgeId, config) { | |
89 | - var deferred = $q.defer(); | |
90 | - var url = '/api/edge/' + edgeId; | |
91 | - $http.get(url, config).then(function success(response) { | |
92 | - deferred.resolve(response.data); | |
93 | - }, function fail(response) { | |
94 | - deferred.reject(response.data); | |
95 | - }); | |
96 | - return deferred.promise; | |
97 | - } | |
98 | - | |
99 | - function saveEdge(edge) { | |
100 | - var deferred = $q.defer(); | |
101 | - var url = '/api/edge'; | |
102 | - $http.post(url, edge).then(function success(response) { | |
103 | - deferred.resolve(response.data); | |
104 | - }, function fail(response) { | |
105 | - deferred.reject(response.data); | |
106 | - }); | |
107 | - return deferred.promise; | |
108 | - } | |
109 | - | |
110 | - function deleteEdge(edgeId) { | |
111 | - var deferred = $q.defer(); | |
112 | - var url = '/api/edge/' + edgeId; | |
113 | - $http.delete(url).then(function success() { | |
114 | - deferred.resolve(); | |
115 | - }, function fail(response) { | |
116 | - deferred.reject(response.data); | |
117 | - }); | |
118 | - return deferred.promise; | |
119 | - } | |
120 | - | |
121 | - function getEdgeTypes(config) { | |
122 | - var deferred = $q.defer(); | |
123 | - var url = '/api/edge/types'; | |
124 | - $http.get(url, config).then(function success(response) { | |
125 | - deferred.resolve(response.data); | |
126 | - }, function fail() { | |
127 | - deferred.reject(); | |
128 | - }); | |
129 | - return deferred.promise; | |
130 | - } | |
131 | - | |
132 | - function getTenantEdges(pageLink, applyCustomersInfo, config, type) { | |
133 | - var deferred = $q.defer(); | |
134 | - var url = '/api/tenant/edges?limit=' + pageLink.limit; | |
135 | - if (angular.isDefined(pageLink.textSearch)) { | |
136 | - url += '&textSearch=' + pageLink.textSearch; | |
137 | - } | |
138 | - if (angular.isDefined(pageLink.idOffset)) { | |
139 | - url += '&idOffset=' + pageLink.idOffset; | |
140 | - } | |
141 | - if (angular.isDefined(pageLink.textOffset)) { | |
142 | - url += '&textOffset=' + pageLink.textOffset; | |
143 | - } | |
144 | - if (angular.isDefined(type) && type.length) { | |
145 | - url += '&type=' + type; | |
146 | - } | |
147 | - $http.get(url, config).then(function success(response) { | |
148 | - if (applyCustomersInfo) { | |
149 | - customerService.applyAssignedCustomersInfo(response.data.data).then( | |
150 | - function success(data) { | |
151 | - response.data.data = data; | |
152 | - deferred.resolve(response.data); | |
153 | - }, | |
154 | - function fail() { | |
155 | - deferred.reject(); | |
156 | - } | |
157 | - ); | |
158 | - } else { | |
159 | - deferred.resolve(response.data); | |
160 | - } | |
161 | - }, function fail() { | |
162 | - deferred.reject(); | |
163 | - }); | |
164 | - return deferred.promise; | |
165 | - } | |
166 | - | |
167 | - function getCustomerEdges(customerId, pageLink, applyCustomersInfo, config, type) { | |
168 | - var deferred = $q.defer(); | |
169 | - var url = '/api/customer/' + customerId + '/edges?limit=' + pageLink.limit; | |
170 | - if (angular.isDefined(pageLink.textSearch)) { | |
171 | - url += '&textSearch=' + pageLink.textSearch; | |
172 | - } | |
173 | - if (angular.isDefined(pageLink.idOffset)) { | |
174 | - url += '&idOffset=' + pageLink.idOffset; | |
175 | - } | |
176 | - if (angular.isDefined(pageLink.textOffset)) { | |
177 | - url += '&textOffset=' + pageLink.textOffset; | |
178 | - } | |
179 | - if (angular.isDefined(type) && type.length) { | |
180 | - url += '&type=' + type; | |
181 | - } | |
182 | - $http.get(url, config).then(function success(response) { | |
183 | - if (applyCustomersInfo) { | |
184 | - customerService.applyAssignedCustomerInfo(response.data.data, customerId).then( | |
185 | - function success(data) { | |
186 | - response.data.data = data; | |
187 | - deferred.resolve(response.data); | |
188 | - }, | |
189 | - function fail() { | |
190 | - deferred.reject(); | |
191 | - } | |
192 | - ); | |
193 | - } else { | |
194 | - deferred.resolve(response.data); | |
195 | - } | |
196 | - }, function fail() { | |
197 | - deferred.reject(); | |
198 | - }); | |
199 | - | |
200 | - return deferred.promise; | |
201 | - } | |
202 | - | |
203 | - function assignEdgeToCustomer(customerId, edgeId) { | |
204 | - var deferred = $q.defer(); | |
205 | - var url = '/api/customer/' + customerId + '/edge/' + edgeId; | |
206 | - $http.post(url, null).then(function success(response) { | |
207 | - deferred.resolve(response.data); | |
208 | - }, function fail() { | |
209 | - deferred.reject(); | |
210 | - }); | |
211 | - return deferred.promise; | |
212 | - } | |
213 | - | |
214 | - function unassignEdgeFromCustomer(edgeId) { | |
215 | - var deferred = $q.defer(); | |
216 | - var url = '/api/customer/edge/' + edgeId; | |
217 | - $http.delete(url).then(function success(response) { | |
218 | - deferred.resolve(response.data); | |
219 | - }, function fail() { | |
220 | - deferred.reject(); | |
221 | - }); | |
222 | - return deferred.promise; | |
223 | - } | |
224 | - | |
225 | - function makeEdgePublic(edgeId) { | |
226 | - var deferred = $q.defer(); | |
227 | - var url = '/api/customer/public/edge/' + edgeId; | |
228 | - $http.post(url, null).then(function success(response) { | |
229 | - deferred.resolve(response.data); | |
230 | - }, function fail() { | |
231 | - deferred.reject(); | |
232 | - }); | |
233 | - return deferred.promise; | |
234 | - } | |
235 | - | |
236 | - function setRootRuleChain(edgeId, ruleChainId) { | |
237 | - var deferred = $q.defer(); | |
238 | - var url = '/api/edge/' + edgeId + '/' + ruleChainId + '/root'; | |
239 | - $http.post(url).then(function success(response) { | |
240 | - deferred.resolve(response.data); | |
241 | - }, function fail() { | |
242 | - deferred.reject(); | |
243 | - }); | |
244 | - return deferred.promise; | |
245 | - } | |
246 | - | |
247 | - function getEdgeEvents(edgeId, pageLink) { | |
248 | - var deferred = $q.defer(); | |
249 | - var url = '/api/edge/' + edgeId + '/events' + '?limit=' + pageLink.limit; | |
250 | - if (angular.isDefined(pageLink.startTime) && pageLink.startTime != null) { | |
251 | - url += '&startTime=' + pageLink.startTime; | |
252 | - } | |
253 | - if (angular.isDefined(pageLink.endTime) && pageLink.endTime != null) { | |
254 | - url += '&endTime=' + pageLink.endTime; | |
255 | - } | |
256 | - if (angular.isDefined(pageLink.idOffset) && pageLink.idOffset != null) { | |
257 | - url += '&offset=' + pageLink.idOffset; | |
258 | - } | |
259 | - $http.get(url, null).then(function success(response) { | |
260 | - deferred.resolve(response.data); | |
261 | - }, function fail(response) { | |
262 | - deferred.reject(response.data); | |
263 | - }); | |
264 | - return deferred.promise; | |
265 | - } | |
266 | - | |
267 | - function syncEdge(edgeId) { | |
268 | - var deferred = $q.defer(); | |
269 | - var url = '/api/edge/sync'; | |
270 | - $http.post(url, edgeId).then(function success(response) { | |
271 | - deferred.resolve(response); | |
272 | - }, function fail(response) { | |
273 | - deferred.reject(response.data); | |
274 | - }); | |
275 | - return deferred.promise; | |
276 | - } | |
277 | -} |
ui/src/app/asset/add-assets-to-edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AddAssetsToEdgeController(assetService, $mdDialog, $q, edgeId, assets) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.assets = assets; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.hasData = hasData; | |
27 | - vm.noData = noData; | |
28 | - vm.searchAssetTextUpdated = searchAssetTextUpdated; | |
29 | - vm.toggleAssetSelection = toggleAssetSelection; | |
30 | - | |
31 | - vm.theAssets = { | |
32 | - getItemAtIndex: function (index) { | |
33 | - if (index > vm.assets.data.length) { | |
34 | - vm.theAssets.fetchMoreItems_(index); | |
35 | - return null; | |
36 | - } | |
37 | - var item = vm.assets.data[index]; | |
38 | - if (item) { | |
39 | - item.indexNumber = index + 1; | |
40 | - } | |
41 | - return item; | |
42 | - }, | |
43 | - | |
44 | - getLength: function () { | |
45 | - if (vm.assets.hasNext) { | |
46 | - return vm.assets.data.length + vm.assets.nextPageLink.limit; | |
47 | - } else { | |
48 | - return vm.assets.data.length; | |
49 | - } | |
50 | - }, | |
51 | - | |
52 | - fetchMoreItems_: function () { | |
53 | - if (vm.assets.hasNext && !vm.assets.pending) { | |
54 | - vm.assets.pending = true; | |
55 | - assetService.getTenantAssets(vm.assets.nextPageLink, false).then( | |
56 | - function success(assets) { | |
57 | - vm.assets.data = vm.assets.data.concat(assets.data); | |
58 | - vm.assets.nextPageLink = assets.nextPageLink; | |
59 | - vm.assets.hasNext = assets.hasNext; | |
60 | - if (vm.assets.hasNext) { | |
61 | - vm.assets.nextPageLink.limit = vm.assets.pageSize; | |
62 | - } | |
63 | - vm.assets.pending = false; | |
64 | - }, | |
65 | - function fail() { | |
66 | - vm.assets.hasNext = false; | |
67 | - vm.assets.pending = false; | |
68 | - }); | |
69 | - } | |
70 | - } | |
71 | - }; | |
72 | - | |
73 | - function cancel () { | |
74 | - $mdDialog.cancel(); | |
75 | - } | |
76 | - | |
77 | - function assign() { | |
78 | - var tasks = []; | |
79 | - for (var assetId in vm.assets.selections) { | |
80 | - tasks.push(assetService.assignAssetToEdge(edgeId, assetId)); | |
81 | - } | |
82 | - $q.all(tasks).then(function () { | |
83 | - $mdDialog.hide(); | |
84 | - }); | |
85 | - } | |
86 | - | |
87 | - function noData() { | |
88 | - return vm.assets.data.length == 0 && !vm.assets.hasNext; | |
89 | - } | |
90 | - | |
91 | - function hasData() { | |
92 | - return vm.assets.data.length > 0; | |
93 | - } | |
94 | - | |
95 | - function toggleAssetSelection($event, asset) { | |
96 | - $event.stopPropagation(); | |
97 | - var selected = angular.isDefined(asset.selected) && asset.selected; | |
98 | - asset.selected = !selected; | |
99 | - if (asset.selected) { | |
100 | - vm.assets.selections[asset.id.id] = true; | |
101 | - vm.assets.selectedCount++; | |
102 | - } else { | |
103 | - delete vm.assets.selections[asset.id.id]; | |
104 | - vm.assets.selectedCount--; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - function searchAssetTextUpdated() { | |
109 | - vm.assets = { | |
110 | - pageSize: vm.assets.pageSize, | |
111 | - data: [], | |
112 | - nextPageLink: { | |
113 | - limit: vm.assets.pageSize, | |
114 | - textSearch: vm.searchText | |
115 | - }, | |
116 | - selections: {}, | |
117 | - selectedCount: 0, | |
118 | - hasNext: true, | |
119 | - pending: false | |
120 | - }; | |
121 | - } | |
122 | - | |
123 | -} |
ui/src/app/asset/add-assets-to-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.assign-to-edge' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>asset.assign-asset-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>asset.assign-asset-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="asset-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchAssetTextUpdated()" | |
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()">asset.no-assets-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="asset in vm.theAssets" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleAssetSelection($event, asset)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="asset.selected"></md-checkbox> | |
58 | - <span> {{ asset.name }} </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.assets.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> | |
\ No newline at end of file |
ui/src/app/dashboard/add-dashboards-to-edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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, types, $mdDialog, $q, edgeId, dashboards) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.types = types; | |
22 | - vm.dashboards = dashboards; | |
23 | - vm.searchText = ''; | |
24 | - | |
25 | - vm.assign = assign; | |
26 | - vm.cancel = cancel; | |
27 | - vm.hasData = hasData; | |
28 | - vm.noData = noData; | |
29 | - vm.searchDashboardTextUpdated = searchDashboardTextUpdated; | |
30 | - vm.toggleDashboardSelection = toggleDashboardSelection; | |
31 | - | |
32 | - vm.theDashboards = { | |
33 | - getItemAtIndex: function (index) { | |
34 | - if (index > vm.dashboards.data.length) { | |
35 | - vm.theDashboards.fetchMoreItems_(index); | |
36 | - return null; | |
37 | - } | |
38 | - var item = vm.dashboards.data[index]; | |
39 | - if (item) { | |
40 | - item.indexNumber = index + 1; | |
41 | - } | |
42 | - return item; | |
43 | - }, | |
44 | - | |
45 | - getLength: function () { | |
46 | - if (vm.dashboards.hasNext) { | |
47 | - return vm.dashboards.data.length + vm.dashboards.nextPageLink.limit; | |
48 | - } else { | |
49 | - return vm.dashboards.data.length; | |
50 | - } | |
51 | - }, | |
52 | - | |
53 | - fetchMoreItems_: function () { | |
54 | - if (vm.dashboards.hasNext && !vm.dashboards.pending) { | |
55 | - vm.dashboards.pending = true; | |
56 | - dashboardService.getTenantDashboards(vm.dashboards.nextPageLink).then( | |
57 | - function success(dashboards) { | |
58 | - vm.dashboards.data = vm.dashboards.data.concat(dashboards.data); | |
59 | - vm.dashboards.nextPageLink = dashboards.nextPageLink; | |
60 | - vm.dashboards.hasNext = dashboards.hasNext; | |
61 | - if (vm.dashboards.hasNext) { | |
62 | - vm.dashboards.nextPageLink.limit = vm.dashboards.pageSize; | |
63 | - } | |
64 | - vm.dashboards.pending = false; | |
65 | - }, | |
66 | - function fail() { | |
67 | - vm.dashboards.hasNext = false; | |
68 | - vm.dashboards.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 vm.dashboards.selections) { | |
81 | - tasks.push(dashboardService.assignDashboardToEdge(edgeId, dashboardId)); | |
82 | - } | |
83 | - $q.all(tasks).then(function () { | |
84 | - $mdDialog.hide(); | |
85 | - }); | |
86 | - } | |
87 | - | |
88 | - function noData () { | |
89 | - return vm.dashboards.data.length == 0 && !vm.dashboards.hasNext; | |
90 | - } | |
91 | - | |
92 | - function hasData () { | |
93 | - return vm.dashboards.data.length > 0; | |
94 | - } | |
95 | - | |
96 | - function toggleDashboardSelection ($event, dashboard) { | |
97 | - $event.stopPropagation(); | |
98 | - var selected = angular.isDefined(dashboard.selected) && dashboard.selected; | |
99 | - dashboard.selected = !selected; | |
100 | - if (dashboard.selected) { | |
101 | - vm.dashboards.selections[dashboard.id.id] = true; | |
102 | - vm.dashboards.selectedCount++; | |
103 | - } else { | |
104 | - delete vm.dashboards.selections[dashboard.id.id]; | |
105 | - vm.dashboards.selectedCount--; | |
106 | - } | |
107 | - } | |
108 | - | |
109 | - function searchDashboardTextUpdated () { | |
110 | - vm.dashboards = { | |
111 | - pageSize: vm.dashboards.pageSize, | |
112 | - data: [], | |
113 | - nextPageLink: { | |
114 | - limit: vm.dashboards.pageSize, | |
115 | - textSearch: vm.searchText | |
116 | - }, | |
117 | - selections: {}, | |
118 | - selectedCount: 0, | |
119 | - hasNext: true, | |
120 | - pending: false | |
121 | - }; | |
122 | - } | |
123 | -} | |
\ No newline at end of file |
ui/src/app/dashboard/add-dashboards-to-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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> | |
\ No newline at end of file |
ui/src/app/device/add-devices-to-edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AddDevicesToEdgeController(deviceService, $mdDialog, $q, edgeId, devices) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.devices = devices; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.hasData = hasData; | |
27 | - vm.noData = noData; | |
28 | - vm.searchDeviceTextUpdated = searchDeviceTextUpdated; | |
29 | - vm.toggleDeviceSelection = toggleDeviceSelection; | |
30 | - | |
31 | - vm.theDevices = { | |
32 | - getItemAtIndex: function (index) { | |
33 | - if (index > vm.devices.data.length) { | |
34 | - vm.theDevices.fetchMoreItems_(index); | |
35 | - return null; | |
36 | - } | |
37 | - var item = vm.devices.data[index]; | |
38 | - if (item) { | |
39 | - item.indexNumber = index + 1; | |
40 | - } | |
41 | - return item; | |
42 | - }, | |
43 | - | |
44 | - getLength: function () { | |
45 | - if (vm.devices.hasNext) { | |
46 | - return vm.devices.data.length + vm.devices.nextPageLink.limit; | |
47 | - } else { | |
48 | - return vm.devices.data.length; | |
49 | - } | |
50 | - }, | |
51 | - | |
52 | - fetchMoreItems_: function () { | |
53 | - if (vm.devices.hasNext && !vm.devices.pending) { | |
54 | - vm.devices.pending = true; | |
55 | - deviceService.getTenantDevices(vm.devices.nextPageLink, false).then( | |
56 | - function success(devices) { | |
57 | - vm.devices.data = vm.devices.data.concat(devices.data); | |
58 | - vm.devices.nextPageLink = devices.nextPageLink; | |
59 | - vm.devices.hasNext = devices.hasNext; | |
60 | - if (vm.devices.hasNext) { | |
61 | - vm.devices.nextPageLink.limit = vm.devices.pageSize; | |
62 | - } | |
63 | - vm.devices.pending = false; | |
64 | - }, | |
65 | - function fail() { | |
66 | - vm.devices.hasNext = false; | |
67 | - vm.devices.pending = false; | |
68 | - }); | |
69 | - } | |
70 | - } | |
71 | - }; | |
72 | - | |
73 | - function cancel () { | |
74 | - $mdDialog.cancel(); | |
75 | - } | |
76 | - | |
77 | - function assign() { | |
78 | - var tasks = []; | |
79 | - for (var deviceId in vm.devices.selections) { | |
80 | - tasks.push(deviceService.assignDeviceToEdge(edgeId, deviceId)); | |
81 | - } | |
82 | - $q.all(tasks).then(function () { | |
83 | - $mdDialog.hide(); | |
84 | - }); | |
85 | - } | |
86 | - | |
87 | - function noData() { | |
88 | - return vm.devices.data.length == 0 && !vm.devices.hasNext; | |
89 | - } | |
90 | - | |
91 | - function hasData() { | |
92 | - return vm.devices.data.length > 0; | |
93 | - } | |
94 | - | |
95 | - function toggleDeviceSelection($event, device) { | |
96 | - $event.stopPropagation(); | |
97 | - var selected = angular.isDefined(device.selected) && device.selected; | |
98 | - device.selected = !selected; | |
99 | - if (device.selected) { | |
100 | - vm.devices.selections[device.id.id] = true; | |
101 | - vm.devices.selectedCount++; | |
102 | - } else { | |
103 | - delete vm.devices.selections[device.id.id]; | |
104 | - vm.devices.selectedCount--; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - function searchDeviceTextUpdated() { | |
109 | - vm.devices = { | |
110 | - pageSize: vm.devices.pageSize, | |
111 | - data: [], | |
112 | - nextPageLink: { | |
113 | - limit: vm.devices.pageSize, | |
114 | - textSearch: vm.searchText | |
115 | - }, | |
116 | - selections: {}, | |
117 | - selectedCount: 0, | |
118 | - hasNext: true, | |
119 | - pending: false | |
120 | - }; | |
121 | - } | |
122 | - | |
123 | -} |
ui/src/app/device/add-devices-to-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.assign-to-edge' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>device.assign-device-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>device.assign-device-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="device-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchDeviceTextUpdated()" | |
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()">device.no-devices-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="device in vm.theDevices" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleDeviceSelection($event, device)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="device.selected"></md-checkbox> | |
58 | - <span> {{ device.name }} </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.devices.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> | |
\ No newline at end of file |
ui/src/app/edge/add-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.add' | translate }}" tb-help="'edges'" help-container-id="help-container" style="width: 600px;"> | |
19 | - <form name="theForm" ng-submit="vm.add()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>edge.add</h2> | |
23 | - <span flex></span> | |
24 | - <div id="help-container"></div> | |
25 | - <md-button class="md-icon-button" ng-click="vm.cancel()"> | |
26 | - <ng-md-icon icon="close" aria-label="{{ 'dialog.close' | translate }}"></ng-md-icon> | |
27 | - </md-button> | |
28 | - </div> | |
29 | - </md-toolbar> | |
30 | - <md-progress-linear class="md-warn" md-mode="indeterminate" ng-disabled="!$root.loading" ng-show="$root.loading"></md-progress-linear> | |
31 | - <span style="min-height: 5px;" flex="" ng-show="!$root.loading"></span> | |
32 | - <md-dialog-content> | |
33 | - <div class="md-dialog-content"> | |
34 | - <tb-edge edge="vm.item" is-edit="true" is-create="true" the-form="theForm"></tb-edge> | |
35 | - </div> | |
36 | - </md-dialog-content> | |
37 | - <md-dialog-actions layout="row"> | |
38 | - <span flex></span> | |
39 | - <md-button ng-disabled="$root.loading || theForm.$invalid || !theForm.$dirty" type="submit" class="md-raised md-primary"> | |
40 | - {{ 'action.add' | translate }} | |
41 | - </md-button> | |
42 | - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | translate }}</md-button> | |
43 | - </md-dialog-actions> | |
44 | - </form> | |
45 | -</md-dialog> | |
46 | - |
ui/src/app/edge/add-edges-to-customer.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AddEdgesToCustomerController(edgeService, $mdDialog, $q, customerId, edges) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.edges = edges; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.hasData = hasData; | |
27 | - vm.noData = noData; | |
28 | - vm.searchEdgeTextUpdated = searchEdgeTextUpdated; | |
29 | - vm.toggleEdgeSelection = toggleEdgeSelection; | |
30 | - | |
31 | - vm.theEdges = { | |
32 | - getItemAtIndex: function (index) { | |
33 | - if (index > vm.edges.data.length) { | |
34 | - vm.theEdges.fetchMoreItems_(index); | |
35 | - return null; | |
36 | - } | |
37 | - var item = vm.edges.data[index]; | |
38 | - if (item) { | |
39 | - item.indexNumber = index + 1; | |
40 | - } | |
41 | - return item; | |
42 | - }, | |
43 | - | |
44 | - getLength: function () { | |
45 | - if (vm.edges.hasNext) { | |
46 | - return vm.edges.data.length + vm.edges.nextPageLink.limit; | |
47 | - } else { | |
48 | - return vm.edges.data.length; | |
49 | - } | |
50 | - }, | |
51 | - | |
52 | - fetchMoreItems_: function () { | |
53 | - if (vm.edges.hasNext && !vm.edges.pending) { | |
54 | - vm.edges.pending = true; | |
55 | - edgeService.getTenantEdges(vm.edges.nextPageLink, false).then( | |
56 | - function success(edges) { | |
57 | - vm.edges.data = vm.edges.data.concat(edges.data); | |
58 | - vm.edges.nextPageLink = edges.nextPageLink; | |
59 | - vm.edges.hasNext = edges.hasNext; | |
60 | - if (vm.edges.hasNext) { | |
61 | - vm.edges.nextPageLink.limit = vm.edges.pageSize; | |
62 | - } | |
63 | - vm.edges.pending = false; | |
64 | - }, | |
65 | - function fail() { | |
66 | - vm.edges.hasNext = false; | |
67 | - vm.edges.pending = false; | |
68 | - }); | |
69 | - } | |
70 | - } | |
71 | - }; | |
72 | - | |
73 | - function cancel () { | |
74 | - $mdDialog.cancel(); | |
75 | - } | |
76 | - | |
77 | - function assign() { | |
78 | - var tasks = []; | |
79 | - for (var edgeId in vm.edges.selections) { | |
80 | - tasks.push(edgeService.assignEdgeToCustomer(customerId, edgeId)); | |
81 | - } | |
82 | - $q.all(tasks).then(function () { | |
83 | - $mdDialog.hide(); | |
84 | - }); | |
85 | - } | |
86 | - | |
87 | - function noData() { | |
88 | - return vm.edges.data.length == 0 && !vm.edges.hasNext; | |
89 | - } | |
90 | - | |
91 | - function hasData() { | |
92 | - return vm.edges.data.length > 0; | |
93 | - } | |
94 | - | |
95 | - function toggleEdgeSelection($event, edge) { | |
96 | - $event.stopPropagation(); | |
97 | - var selected = angular.isDefined(edge.selected) && edge.selected; | |
98 | - edge.selected = !selected; | |
99 | - if (edge.selected) { | |
100 | - vm.edges.selections[edge.id.id] = true; | |
101 | - vm.edges.selectedCount++; | |
102 | - } else { | |
103 | - delete vm.edges.selections[edge.id.id]; | |
104 | - vm.edges.selectedCount--; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - function searchEdgeTextUpdated() { | |
109 | - vm.edges = { | |
110 | - pageSize: vm.edges.pageSize, | |
111 | - data: [], | |
112 | - nextPageLink: { | |
113 | - limit: vm.edges.pageSize, | |
114 | - textSearch: vm.searchText | |
115 | - }, | |
116 | - selections: {}, | |
117 | - selectedCount: 0, | |
118 | - hasNext: true, | |
119 | - pending: false | |
120 | - }; | |
121 | - } | |
122 | - | |
123 | -} |
ui/src/app/edge/add-edges-to-customer.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.assign-to-customer' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>edge.assign-edge-to-customer</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>edge.assign-edge-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="edge-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchEdgeTextUpdated()" | |
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()">edge.no-edges-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="edge in vm.theEdges" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleEdgeSelection($event, edge)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="edge.selected"></md-checkbox> | |
58 | - <span> {{ edge.name }} </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.edges.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> | |
\ No newline at end of file |
ui/src/app/edge/assign-to-customer.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AssignEdgeToCustomerController(customerService, edgeService, $mdDialog, $q, edgeIds, 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 i=0;i<edgeIds.length;i++) { | |
81 | - tasks.push(edgeService.assignEdgeToCustomer(vm.customers.selection.id.id, edgeIds[i])); | |
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/edge/assign-to-customer.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.assign-edge-to-customer' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>edge.assign-edge-to-customer</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>edge.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> | |
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.customers.selection==null" type="submit" class="md-raised md-primary"> | |
69 | - {{ 'action.assign' | translate }} | |
70 | - </md-button> | |
71 | - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | |
72 | - translate }} | |
73 | - </md-button> | |
74 | - </md-dialog-actions> | |
75 | - </form> | |
76 | -</md-dialog> | |
\ No newline at end of file |
ui/src/app/edge/edge-card.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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 | -<div flex layout="column"> | |
19 | - <div style="text-transform: uppercase; padding-bottom: 5px;">{{vm.item.type}}</div> | |
20 | - <div class="tb-card-description">{{vm.item.additionalInfo.description}}</div> | |
21 | - <div style="padding-top: 5px;" class="tb-small" ng-show="vm.isAssignedToCustomer()">{{'edge.assigned-to-customer' | translate}} '{{vm.item.assignedCustomer.title}}'</div> | |
22 | - <div style="padding-top: 5px;" class="tb-small" ng-show="vm.isPublic()">{{'edge.public' | translate}}</div> | |
23 | -</div> |
ui/src/app/edge/edge-fieldset.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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-button ng-click="onAssignToCustomer({event: $event})" | |
19 | - ng-show="!isEdit && edgeScope === 'tenant' && !isAssignedToCustomer" | |
20 | - class="md-raised md-primary">{{ 'edge.assign-to-customer' | translate }}</md-button> | |
21 | -<md-button ng-click="onUnassignFromCustomer({event: $event, isPublic: isPublic})" | |
22 | - ng-show="!isEdit && (edgeScope === 'customer' || edgeScope === 'tenant') && isAssignedToCustomer" | |
23 | - class="md-raised md-primary">{{ isPublic ? 'edge.make-private' : 'edge.unassign-from-customer' | translate }}</md-button> | |
24 | -<md-button ng-click="onManageEdgeAssets({event: $event})" | |
25 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
26 | - class="md-raised md-primary">{{ 'edge.manage-edge-assets' | translate }}</md-button> | |
27 | -<md-button ng-click="onManageEdgeDevices({event: $event})" | |
28 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
29 | - class="md-raised md-primary">{{ 'edge.manage-edge-devices' | translate }}</md-button> | |
30 | -<md-button ng-click="onManageEdgeEntityViews({event: $event})" | |
31 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
32 | - class="md-raised md-primary">{{ 'edge.manage-edge-entity-views' | translate }}</md-button> | |
33 | -<md-button ng-click="onManageEdgeDashboards({event: $event})" | |
34 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
35 | - class="md-raised md-primary">{{ 'edge.manage-edge-dashboards' | translate }}</md-button> | |
36 | -<md-button ng-click="onManageEdgeRuleChains({event: $event})" | |
37 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
38 | - class="md-raised md-primary">{{ 'edge.manage-edge-rulechains' | translate }}</md-button> | |
39 | -<md-button ng-click="onDeleteEdge({event: $event})" | |
40 | - ng-show="!isEdit && edgeScope === 'tenant'" | |
41 | - class="md-raised md-primary">{{ 'edge.delete' | translate }}</md-button> | |
42 | - | |
43 | -<div layout="row"> | |
44 | - <md-button ngclipboard data-clipboard-action="copy" | |
45 | - ngclipboard-success="onEdgeIdCopied()" | |
46 | - data-clipboard-text="{{edge.id.id}}" ng-show="!isEdit" | |
47 | - class="md-raised"> | |
48 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
49 | - <span translate>edge.copy-id</span> | |
50 | - </md-button> | |
51 | - <md-button ngclipboard data-clipboard-action="copy" | |
52 | - ngclipboard-success="onEdgeInfoCopied('key')" | |
53 | - data-clipboard-text="{{edge.routingKey}}" ng-show="!isEdit" | |
54 | - class="md-raised"> | |
55 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
56 | - <span translate>edge.copy-edge-key</span> | |
57 | - </md-button> | |
58 | - <md-button ngclipboard data-clipboard-action="copy" | |
59 | - ngclipboard-success="onEdgeInfoCopied('secret')" | |
60 | - data-clipboard-text="{{edge.secret}}" ng-show="!isEdit" | |
61 | - class="md-raised"> | |
62 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
63 | - <span translate>edge.copy-edge-secret</span> | |
64 | - </md-button> | |
65 | - <md-button ng-click="onEdgeSync(edge.id)" | |
66 | - ng-show="!isEdit" | |
67 | - class="md-raised"> | |
68 | - <md-icon md-svg-icon="mdi:sync"></md-icon> | |
69 | - <span translate>edge.sync</span> | |
70 | - </md-button> | |
71 | -</div> | |
72 | - | |
73 | -<md-content class="md-padding" layout="column"> | |
74 | - <md-input-container class="md-block" | |
75 | - ng-show="!isEdit && isAssignedToCustomer && !isPublic && edgeScope === 'tenant'"> | |
76 | - <label translate>edge.assigned-to-customer</label> | |
77 | - <input ng-model="assignedCustomer.title" disabled> | |
78 | - </md-input-container> | |
79 | - <div class="tb-small" style="padding-bottom: 10px; padding-left: 2px;" | |
80 | - ng-show="!isEdit && isPublic && (edgeScope === 'customer' || edgeScope === 'tenant')"> | |
81 | - {{ 'edge.edge-public' | translate }} | |
82 | - </div> | |
83 | - <fieldset ng-disabled="$root.loading || !isEdit"> | |
84 | - <md-input-container class="md-block"> | |
85 | - <label translate>edge.name</label> | |
86 | - <input required name="name" ng-model="edge.name"> | |
87 | - <div ng-messages="theForm.name.$error"> | |
88 | - <div translate ng-message="required">edge.name-required</div> | |
89 | - </div> | |
90 | - </md-input-container> | |
91 | - <tb-entity-subtype-autocomplete | |
92 | - ng-disabled="$root.loading || !isEdit" | |
93 | - tb-required="true" | |
94 | - the-form="theForm" | |
95 | - ng-model="edge.type" | |
96 | - entity-type="types.entityType.edge"> | |
97 | - </tb-entity-subtype-autocomplete> | |
98 | - <md-input-container class="md-block"> | |
99 | - <label translate>edge.label</label> | |
100 | - <input name="label" ng-model="edge.label"> | |
101 | - </md-input-container> | |
102 | - <md-input-container class="md-block"> | |
103 | - <label translate>edge.description</label> | |
104 | - <textarea ng-model="edge.additionalInfo.description" rows="2"></textarea> | |
105 | - </md-input-container> | |
106 | - <md-input-container class="md-block"> | |
107 | - <label translate>edge.edge-license-key</label> | |
108 | - <input required name="edgeLicenseKey" ng-model="edge.edgeLicenseKey"> | |
109 | - <div ng-messages="theForm.edgeLicenseKey.$error"> | |
110 | - <div translate ng-message="required">edge.edge-license-key-required</div> | |
111 | - </div> | |
112 | - </md-input-container> | |
113 | - <md-input-container class="md-block"> | |
114 | - <label translate>edge.cloud-endpoint</label> | |
115 | - <input required name="cloudEndpoint" ng-model="edge.cloudEndpoint"> | |
116 | - <div ng-messages="theForm.cloudEndpoint.$error"> | |
117 | - <div translate ng-message="required">edge.cloud-endpoint-required</div> | |
118 | - </div> | |
119 | - </md-input-container> | |
120 | - </fieldset> | |
121 | - <div layout="row"> | |
122 | - | |
123 | - <md-input-container class="md-block" flex> | |
124 | - <label translate>edge.edge-key</label> | |
125 | - <input ng-model="edge.routingKey" disabled> | |
126 | - </md-input-container> | |
127 | - <md-button class="md-icon-button" style="margin-top: 14px;" | |
128 | - ngclipboard data-clipboard-action="copy" | |
129 | - ngclipboard-success="onEdgeInfoCopied('key')" | |
130 | - data-clipboard-text="{{edge.routingKey}}"> | |
131 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
132 | - <md-tooltip md-direction="top"> | |
133 | - {{ 'edge.copy-edge-key' | translate }} | |
134 | - </md-tooltip> | |
135 | - </md-button> | |
136 | - </div> | |
137 | - <div layout="row"> | |
138 | - <md-input-container class="md-block" flex> | |
139 | - <label translate>edge.edge-secret</label> | |
140 | - <input ng-model="edge.secret" disabled> | |
141 | - </md-input-container> | |
142 | - <md-button class="md-icon-button" style="margin-top: 14px;" | |
143 | - ngclipboard data-clipboard-action="copy" | |
144 | - data-clipboard-text="{{edge.secret}}" | |
145 | - ngclipboard-success="onEdgeInfoCopied('secret')"> | |
146 | - <md-icon md-svg-icon="mdi:clipboard-arrow-left"></md-icon> | |
147 | - <md-tooltip md-direction="top"> | |
148 | - {{ 'edge.copy-edge-secret' | translate }} | |
149 | - </md-tooltip> | |
150 | - </md-button> | |
151 | - </div> | |
152 | -</md-content> |
ui/src/app/edge/edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 | -/* eslint-disable import/no-unresolved, import/default */ | |
17 | - | |
18 | -import addEdgeTemplate from './add-edge.tpl.html'; | |
19 | -import edgeCard from './edge-card.tpl.html'; | |
20 | -import assignToCustomerTemplate from './assign-to-customer.tpl.html'; | |
21 | -import addEdgesToCustomerTemplate from './add-edges-to-customer.tpl.html'; | |
22 | -import setRootRuleChainToEdgesTemplate from './set-root-rulechain-to-edges.tpl.html'; | |
23 | - | |
24 | -/* eslint-enable import/no-unresolved, import/default */ | |
25 | - | |
26 | -/*@ngInject*/ | |
27 | -export function EdgeCardController(types) { | |
28 | - | |
29 | - var vm = this; | |
30 | - | |
31 | - vm.types = types; | |
32 | - | |
33 | - vm.isAssignedToCustomer = function() { | |
34 | - if (vm.item && vm.item.customerId && vm.parentCtl.edgesScope === 'tenant' && | |
35 | - vm.item.customerId.id != vm.types.id.nullUid && !vm.item.assignedCustomer.isPublic) { | |
36 | - return true; | |
37 | - } | |
38 | - return false; | |
39 | - } | |
40 | - | |
41 | - vm.isPublic = function() { | |
42 | - if (vm.item && vm.item.assignedCustomer && vm.parentCtl.edgesScope === 'tenant' && vm.item.assignedCustomer.isPublic) { | |
43 | - return true; | |
44 | - } | |
45 | - return false; | |
46 | - } | |
47 | -} | |
48 | - | |
49 | - | |
50 | -/*@ngInject*/ | |
51 | -export function EdgeController($rootScope, userService, edgeService, customerService, ruleChainService, | |
52 | - $state, $stateParams, $document, $mdDialog, $q, $translate, types, importExport) { | |
53 | - | |
54 | - var customerId = $stateParams.customerId; | |
55 | - | |
56 | - var edgeActionsList = []; | |
57 | - | |
58 | - var edgeGroupActionsList = []; | |
59 | - | |
60 | - var edgeAddItemActionsList = [ | |
61 | - { | |
62 | - onAction: function ($event) { | |
63 | - vm.grid.addItem($event); | |
64 | - }, | |
65 | - name: function() { return $translate.instant('action.add') }, | |
66 | - details: function() { return $translate.instant('edge.add-edge-text') }, | |
67 | - icon: "insert_drive_file" | |
68 | - }, | |
69 | - { | |
70 | - onAction: function ($event) { | |
71 | - importExport.importEntities($event, types.entityType.edge).then( | |
72 | - function() { | |
73 | - vm.grid.refreshList(); | |
74 | - } | |
75 | - ); | |
76 | - }, | |
77 | - name: function() { return $translate.instant('action.import') }, | |
78 | - details: function() { return $translate.instant('edge.import') }, | |
79 | - icon: "file_upload" | |
80 | - } | |
81 | - ]; | |
82 | - | |
83 | - var vm = this; | |
84 | - | |
85 | - vm.types = types; | |
86 | - | |
87 | - vm.edgeGridConfig = { | |
88 | - deleteItemTitleFunc: deleteEdgeTitle, | |
89 | - deleteItemContentFunc: deleteEdgeText, | |
90 | - deleteItemsTitleFunc: deleteEdgesTitle, | |
91 | - deleteItemsActionTitleFunc: deleteEdgesActionTitle, | |
92 | - deleteItemsContentFunc: deleteEdgesText, | |
93 | - | |
94 | - saveItemFunc: saveEdge, | |
95 | - | |
96 | - getItemTitleFunc: getEdgeTitle, | |
97 | - | |
98 | - itemCardController: 'EdgeCardController', | |
99 | - itemCardTemplateUrl: edgeCard, | |
100 | - parentCtl: vm, | |
101 | - | |
102 | - actionsList: edgeActionsList, | |
103 | - groupActionsList: edgeGroupActionsList, | |
104 | - addItemActions: edgeAddItemActionsList, | |
105 | - | |
106 | - onGridInited: gridInited, | |
107 | - | |
108 | - addItemTemplateUrl: addEdgeTemplate, | |
109 | - | |
110 | - addItemText: function() { return $translate.instant('edge.add-edge-text') }, | |
111 | - noItemsText: function() { return $translate.instant('edge.no-edges-text') }, | |
112 | - itemDetailsText: function() { return $translate.instant('edge.edge-details') }, | |
113 | - isDetailsReadOnly: isCustomerUser, | |
114 | - isSelectionEnabled: function () { | |
115 | - return !isCustomerUser(); | |
116 | - } | |
117 | - }; | |
118 | - | |
119 | - if (angular.isDefined($stateParams.items) && $stateParams.items !== null) { | |
120 | - vm.edgeGridConfig.items = $stateParams.items; | |
121 | - } | |
122 | - | |
123 | - if (angular.isDefined($stateParams.topIndex) && $stateParams.topIndex > 0) { | |
124 | - vm.edgeGridConfig.topIndex = $stateParams.topIndex; | |
125 | - } | |
126 | - | |
127 | - vm.edgesScope = $state.$current.data.edgesType; | |
128 | - | |
129 | - vm.assignToCustomer = assignToCustomer; | |
130 | - vm.makePublic = makePublic; | |
131 | - vm.unassignFromCustomer = unassignFromCustomer; | |
132 | - vm.openEdgeAssets = openEdgeAssets; | |
133 | - vm.openEdgeDevices = openEdgeDevices; | |
134 | - vm.openEdgeEntityViews = openEdgeEntityViews; | |
135 | - vm.openEdgeDashboards = openEdgeDashboards; | |
136 | - vm.openEdgeRuleChains = openEdgeRuleChains; | |
137 | - | |
138 | - initController(); | |
139 | - | |
140 | - function initController() { | |
141 | - var fetchEdgesFunction = null; | |
142 | - var deleteEdgeFunction = null; | |
143 | - var refreshEdgesParamsFunction = null; | |
144 | - | |
145 | - var user = userService.getCurrentUser(); | |
146 | - | |
147 | - if (user.authority === 'CUSTOMER_USER') { | |
148 | - vm.edgesScope = 'customer_user'; | |
149 | - customerId = user.customerId; | |
150 | - } | |
151 | - if (customerId) { | |
152 | - vm.customerEdgesTitle = $translate.instant('customer.edges'); | |
153 | - customerService.getShortCustomerInfo(customerId).then( | |
154 | - function success(info) { | |
155 | - if (info.isPublic) { | |
156 | - vm.customerEdgesTitle = $translate.instant('customer.public-edges'); | |
157 | - } | |
158 | - } | |
159 | - ); | |
160 | - } | |
161 | - | |
162 | - if (vm.edgesScope === 'tenant') { | |
163 | - fetchEdgesFunction = function (pageLink, edgeType) { | |
164 | - return edgeService.getTenantEdges(pageLink, true, null, edgeType); | |
165 | - }; | |
166 | - deleteEdgeFunction = function (edgeId) { | |
167 | - return edgeService.deleteEdge(edgeId); | |
168 | - }; | |
169 | - refreshEdgesParamsFunction = function() { | |
170 | - return {"topIndex": vm.topIndex}; | |
171 | - }; | |
172 | - | |
173 | - edgeActionsList.push({ | |
174 | - onAction: function ($event, item) { | |
175 | - makePublic($event, item); | |
176 | - }, | |
177 | - name: function() { return $translate.instant('action.share') }, | |
178 | - details: function() { return $translate.instant('edge.make-public') }, | |
179 | - icon: "share", | |
180 | - isEnabled: function(edge) { | |
181 | - return edge && (!edge.customerId || edge.customerId.id === types.id.nullUid); | |
182 | - } | |
183 | - }); | |
184 | - | |
185 | - edgeActionsList.push( | |
186 | - { | |
187 | - onAction: function ($event, item) { | |
188 | - assignToCustomer($event, [ item.id.id ]); | |
189 | - }, | |
190 | - name: function() { return $translate.instant('action.assign') }, | |
191 | - details: function() { return $translate.instant('edge.assign-to-customer') }, | |
192 | - icon: "assignment_ind", | |
193 | - isEnabled: function(edge) { | |
194 | - return edge && (!edge.customerId || edge.customerId.id === types.id.nullUid); | |
195 | - } | |
196 | - } | |
197 | - ); | |
198 | - | |
199 | - edgeActionsList.push( | |
200 | - { | |
201 | - onAction: function ($event, item) { | |
202 | - unassignFromCustomer($event, item, false); | |
203 | - }, | |
204 | - name: function() { return $translate.instant('action.unassign') }, | |
205 | - details: function() { return $translate.instant('edge.unassign-from-customer') }, | |
206 | - icon: "assignment_return", | |
207 | - isEnabled: function(edge) { | |
208 | - return edge && edge.customerId && edge.customerId.id !== types.id.nullUid && !edge.assignedCustomer.isPublic; | |
209 | - } | |
210 | - } | |
211 | - ); | |
212 | - | |
213 | - edgeActionsList.push({ | |
214 | - onAction: function ($event, item) { | |
215 | - unassignFromCustomer($event, item, true); | |
216 | - }, | |
217 | - name: function() { return $translate.instant('action.make-private') }, | |
218 | - details: function() { return $translate.instant('edge.make-private') }, | |
219 | - icon: "reply", | |
220 | - isEnabled: function(edge) { | |
221 | - return edge && edge.customerId && edge.customerId.id !== types.id.nullUid && edge.assignedCustomer.isPublic; | |
222 | - } | |
223 | - }); | |
224 | - | |
225 | - edgeActionsList.push( | |
226 | - { | |
227 | - onAction: function ($event, item) { | |
228 | - openEdgeAssets($event, item); | |
229 | - }, | |
230 | - name: function() { return $translate.instant('asset.assets') }, | |
231 | - details: function() { | |
232 | - return $translate.instant('edge.manage-edge-assets'); | |
233 | - }, | |
234 | - icon: "domain" | |
235 | - } | |
236 | - ); | |
237 | - | |
238 | - edgeActionsList.push( | |
239 | - { | |
240 | - onAction: function ($event, item) { | |
241 | - openEdgeDevices($event, item); | |
242 | - }, | |
243 | - name: function() { return $translate.instant('device.devices') }, | |
244 | - details: function() { | |
245 | - return $translate.instant('edge.manage-edge-devices'); | |
246 | - }, | |
247 | - icon: "devices_other" | |
248 | - } | |
249 | - ); | |
250 | - | |
251 | - edgeActionsList.push( | |
252 | - { | |
253 | - onAction: function ($event, item) { | |
254 | - openEdgeEntityViews($event, item); | |
255 | - }, | |
256 | - name: function() { return $translate.instant('entity-view.entity-views') }, | |
257 | - details: function() { | |
258 | - return $translate.instant('edge.manage-edge-entity-views'); | |
259 | - }, | |
260 | - icon: "view_quilt" | |
261 | - } | |
262 | - ); | |
263 | - | |
264 | - edgeActionsList.push( | |
265 | - { | |
266 | - onAction: function ($event, item) { | |
267 | - openEdgeDashboards($event, item); | |
268 | - }, | |
269 | - name: function() { return $translate.instant('dashboard.dashboards') }, | |
270 | - details: function() { | |
271 | - return $translate.instant('edge.manage-edge-dashboards'); | |
272 | - }, | |
273 | - icon: "dashboard" | |
274 | - } | |
275 | - ); | |
276 | - | |
277 | - edgeActionsList.push( | |
278 | - { | |
279 | - onAction: function ($event, item) { | |
280 | - openEdgeRuleChains($event, item); | |
281 | - }, | |
282 | - name: function() { return $translate.instant('rulechain.rulechains') }, | |
283 | - details: function() { | |
284 | - return $translate.instant('edge.manage-edge-rulechains'); | |
285 | - }, | |
286 | - icon: "code" | |
287 | - } | |
288 | - ); | |
289 | - | |
290 | - edgeActionsList.push( | |
291 | - { | |
292 | - onAction: function ($event, item) { | |
293 | - vm.grid.deleteItem($event, item); | |
294 | - }, | |
295 | - name: function() { return $translate.instant('action.delete') }, | |
296 | - details: function() { return $translate.instant('edge.delete') }, | |
297 | - icon: "delete" | |
298 | - } | |
299 | - ); | |
300 | - | |
301 | - edgeGroupActionsList.push( | |
302 | - { | |
303 | - onAction: function ($event, items) { | |
304 | - setRootRuleChainToEdges($event, items); | |
305 | - }, | |
306 | - name: function() { return $translate.instant('edge.set-rootrule-chain-to-edges') }, | |
307 | - details: function(selectedCount) { | |
308 | - return $translate.instant('edge.set-root-rulechain-to-edges-text', {count: selectedCount}, "messageformat"); | |
309 | - }, | |
310 | - icon: "flag" | |
311 | - } | |
312 | - ); | |
313 | - | |
314 | - edgeGroupActionsList.push( | |
315 | - { | |
316 | - onAction: function ($event, items) { | |
317 | - assignEdgesToCustomer($event, items); | |
318 | - }, | |
319 | - name: function() { return $translate.instant('edge.assign-edges') }, | |
320 | - details: function(selectedCount) { | |
321 | - return $translate.instant('edge.assign-edges-text', {count: selectedCount}, "messageformat"); | |
322 | - }, | |
323 | - icon: "assignment_ind" | |
324 | - } | |
325 | - ); | |
326 | - | |
327 | - edgeGroupActionsList.push( | |
328 | - { | |
329 | - onAction: function ($event) { | |
330 | - vm.grid.deleteItems($event); | |
331 | - }, | |
332 | - name: function() { return $translate.instant('edge.delete-edges') }, | |
333 | - details: deleteEdgesActionTitle, | |
334 | - icon: "delete" | |
335 | - } | |
336 | - ); | |
337 | - | |
338 | - } else if (vm.edgesScope === 'customer' || vm.edgesScope === 'customer_user') { | |
339 | - fetchEdgesFunction = function (pageLink, edgeType) { | |
340 | - return edgeService.getCustomerEdges(customerId, pageLink, true, null, edgeType); | |
341 | - }; | |
342 | - deleteEdgeFunction = function (edgeId) { | |
343 | - return edgeService.unassignEdgeFromCustomer(edgeId); | |
344 | - }; | |
345 | - refreshEdgesParamsFunction = function () { | |
346 | - return {"customerId": customerId, "topIndex": vm.topIndex}; | |
347 | - }; | |
348 | - | |
349 | - if (vm.edgesScope === 'customer') { | |
350 | - edgeActionsList.push( | |
351 | - { | |
352 | - onAction: function ($event, item) { | |
353 | - unassignFromCustomer($event, item, false); | |
354 | - }, | |
355 | - name: function() { return $translate.instant('action.unassign') }, | |
356 | - details: function() { return $translate.instant('edge.unassign-from-customer') }, | |
357 | - icon: "assignment_return", | |
358 | - isEnabled: function(edge) { | |
359 | - return edge && !edge.assignedCustomer.isPublic; | |
360 | - } | |
361 | - } | |
362 | - ); | |
363 | - edgeActionsList.push( | |
364 | - { | |
365 | - onAction: function ($event, item) { | |
366 | - unassignFromCustomer($event, item, true); | |
367 | - }, | |
368 | - name: function() { return $translate.instant('action.make-private') }, | |
369 | - details: function() { return $translate.instant('edge.make-private') }, | |
370 | - icon: "reply", | |
371 | - isEnabled: function(edge) { | |
372 | - return edge && edge.assignedCustomer.isPublic; | |
373 | - } | |
374 | - } | |
375 | - ); | |
376 | - | |
377 | - edgeGroupActionsList.push( | |
378 | - { | |
379 | - onAction: function ($event, items) { | |
380 | - unassignEdgesFromCustomer($event, items); | |
381 | - }, | |
382 | - name: function() { return $translate.instant('edge.unassign-edges') }, | |
383 | - details: function(selectedCount) { | |
384 | - return $translate.instant('edge.unassign-edges-action-title', {count: selectedCount}, "messageformat"); | |
385 | - }, | |
386 | - icon: "assignment_return" | |
387 | - } | |
388 | - ); | |
389 | - | |
390 | - vm.edgeGridConfig.addItemAction = { | |
391 | - onAction: function ($event) { | |
392 | - addEdgesToCustomer($event); | |
393 | - }, | |
394 | - name: function() { return $translate.instant('edge.assign-edges') }, | |
395 | - details: function() { return $translate.instant('edge.assign-new-edge') }, | |
396 | - icon: "add" | |
397 | - }; | |
398 | - | |
399 | - | |
400 | - } else if (vm.edgesScope === 'customer_user') { | |
401 | - vm.edgeGridConfig.addItemAction = {}; | |
402 | - } | |
403 | - vm.edgeGridConfig.addItemActions = []; | |
404 | - | |
405 | - } | |
406 | - | |
407 | - vm.edgeGridConfig.refreshParamsFunc = refreshEdgesParamsFunction; | |
408 | - vm.edgeGridConfig.fetchItemsFunc = fetchEdgesFunction; | |
409 | - vm.edgeGridConfig.deleteItemFunc = deleteEdgeFunction; | |
410 | - | |
411 | - } | |
412 | - | |
413 | - function deleteEdgeTitle(edge) { | |
414 | - return $translate.instant('edge.delete-edge-title', {edgeName: edge.name}); | |
415 | - } | |
416 | - | |
417 | - function deleteEdgeText() { | |
418 | - return $translate.instant('edge.delete-edge-text'); | |
419 | - } | |
420 | - | |
421 | - function deleteEdgesTitle(selectedCount) { | |
422 | - return $translate.instant('edge.delete-edges-title', {count: selectedCount}, 'messageformat'); | |
423 | - } | |
424 | - | |
425 | - function deleteEdgesActionTitle(selectedCount) { | |
426 | - return $translate.instant('edge.delete-edges-action-title', {count: selectedCount}, 'messageformat'); | |
427 | - } | |
428 | - | |
429 | - function deleteEdgesText () { | |
430 | - return $translate.instant('edge.delete-edges-text'); | |
431 | - } | |
432 | - | |
433 | - function gridInited(grid) { | |
434 | - vm.grid = grid; | |
435 | - } | |
436 | - | |
437 | - function getEdgeTitle(edge) { | |
438 | - return edge ? edge.name : ''; | |
439 | - } | |
440 | - | |
441 | - function saveEdge(edge) { | |
442 | - var deferred = $q.defer(); | |
443 | - edgeService.saveEdge(edge).then( | |
444 | - function success(savedEdge) { | |
445 | - $rootScope.$broadcast('edgeSaved'); | |
446 | - var edges = [ savedEdge ]; | |
447 | - customerService.applyAssignedCustomersInfo(edges).then( | |
448 | - function success(items) { | |
449 | - if (items && items.length == 1) { | |
450 | - deferred.resolve(items[0]); | |
451 | - } else { | |
452 | - deferred.reject(); | |
453 | - } | |
454 | - }, | |
455 | - function fail() { | |
456 | - deferred.reject(); | |
457 | - } | |
458 | - ); | |
459 | - }, | |
460 | - function fail() { | |
461 | - deferred.reject(); | |
462 | - } | |
463 | - ); | |
464 | - return deferred.promise; | |
465 | - } | |
466 | - | |
467 | - function isCustomerUser() { | |
468 | - return vm.edgesScope === 'customer_user'; | |
469 | - } | |
470 | - | |
471 | - function assignToCustomer($event, edgeIds) { | |
472 | - if ($event) { | |
473 | - $event.stopPropagation(); | |
474 | - } | |
475 | - var pageSize = 10; | |
476 | - customerService.getCustomers({limit: pageSize, textSearch: ''}).then( | |
477 | - function success(_customers) { | |
478 | - var customers = { | |
479 | - pageSize: pageSize, | |
480 | - data: _customers.data, | |
481 | - nextPageLink: _customers.nextPageLink, | |
482 | - selection: null, | |
483 | - hasNext: _customers.hasNext, | |
484 | - pending: false | |
485 | - }; | |
486 | - if (customers.hasNext) { | |
487 | - customers.nextPageLink.limit = pageSize; | |
488 | - } | |
489 | - $mdDialog.show({ | |
490 | - controller: 'AssignEdgeToCustomerController', | |
491 | - controllerAs: 'vm', | |
492 | - templateUrl: assignToCustomerTemplate, | |
493 | - locals: {edgeIds: edgeIds, customers: customers}, | |
494 | - parent: angular.element($document[0].body), | |
495 | - fullscreen: true, | |
496 | - targetEvent: $event | |
497 | - }).then(function () { | |
498 | - vm.grid.refreshList(); | |
499 | - }, function () { | |
500 | - }); | |
501 | - }, | |
502 | - function fail() { | |
503 | - }); | |
504 | - } | |
505 | - | |
506 | - function addEdgesToCustomer($event) { | |
507 | - if ($event) { | |
508 | - $event.stopPropagation(); | |
509 | - } | |
510 | - var pageSize = 10; | |
511 | - edgeService.getTenantEdges({limit: pageSize, textSearch: ''}, false).then( | |
512 | - function success(_edges) { | |
513 | - var edges = { | |
514 | - pageSize: pageSize, | |
515 | - data: _edges.data, | |
516 | - nextPageLink: _edges.nextPageLink, | |
517 | - selections: {}, | |
518 | - selectedCount: 0, | |
519 | - hasNext: _edges.hasNext, | |
520 | - pending: false | |
521 | - }; | |
522 | - if (edges.hasNext) { | |
523 | - edges.nextPageLink.limit = pageSize; | |
524 | - } | |
525 | - $mdDialog.show({ | |
526 | - controller: 'AddEdgesToCustomerController', | |
527 | - controllerAs: 'vm', | |
528 | - templateUrl: addEdgesToCustomerTemplate, | |
529 | - locals: {customerId: customerId, edges: edges}, | |
530 | - parent: angular.element($document[0].body), | |
531 | - fullscreen: true, | |
532 | - targetEvent: $event | |
533 | - }).then(function () { | |
534 | - vm.grid.refreshList(); | |
535 | - }, function () { | |
536 | - }); | |
537 | - }, | |
538 | - function fail() { | |
539 | - }); | |
540 | - } | |
541 | - | |
542 | - function setRootRuleChainToEdges($event, items) { | |
543 | - var edgeIds = []; | |
544 | - for (var id in items.selections) { | |
545 | - edgeIds.push(id); | |
546 | - } | |
547 | - setRootRuleChain($event, edgeIds); | |
548 | - } | |
549 | - | |
550 | - function setRootRuleChain($event, edgeIds) { | |
551 | - if ($event) { | |
552 | - $event.stopPropagation(); | |
553 | - } | |
554 | - var pageSize = 10; | |
555 | - ruleChainService.getEdgesRuleChains({limit: pageSize, textSearch: ''}).then( | |
556 | - function success(_ruleChains) { | |
557 | - var ruleChains = { | |
558 | - pageSize: pageSize, | |
559 | - data: _ruleChains.data, | |
560 | - nextPageLink: _ruleChains.nextPageLink, | |
561 | - selection: null, | |
562 | - hasNext: _ruleChains.hasNext, | |
563 | - pending: false | |
564 | - }; | |
565 | - if (ruleChains.hasNext) { | |
566 | - ruleChains.nextPageLink.limit = pageSize; | |
567 | - } | |
568 | - $mdDialog.show({ | |
569 | - controller: 'SetRootRuleChainToEdgesController', | |
570 | - controllerAs: 'vm', | |
571 | - templateUrl: setRootRuleChainToEdgesTemplate, | |
572 | - locals: {edgeIds: edgeIds, ruleChains: ruleChains}, | |
573 | - parent: angular.element($document[0].body), | |
574 | - fullscreen: true, | |
575 | - targetEvent: $event | |
576 | - }).then(function () { | |
577 | - vm.grid.refreshList(); | |
578 | - }, function () { | |
579 | - }); | |
580 | - }, | |
581 | - function fail() { | |
582 | - }); | |
583 | - } | |
584 | - | |
585 | - function assignEdgesToCustomer($event, items) { | |
586 | - var edgeIds = []; | |
587 | - for (var id in items.selections) { | |
588 | - edgeIds.push(id); | |
589 | - } | |
590 | - assignToCustomer($event, edgeIds); | |
591 | - } | |
592 | - | |
593 | - function unassignFromCustomer($event, edge, isPublic) { | |
594 | - if ($event) { | |
595 | - $event.stopPropagation(); | |
596 | - } | |
597 | - var title; | |
598 | - var content; | |
599 | - var label; | |
600 | - if (isPublic) { | |
601 | - title = $translate.instant('edge.make-private-edge-title', {edgeName: edge.name}); | |
602 | - content = $translate.instant('edge.make-private-edge-text'); | |
603 | - label = $translate.instant('edge.make-private'); | |
604 | - } else { | |
605 | - title = $translate.instant('edge.unassign-edge-title', {edgeName: edge.name}); | |
606 | - content = $translate.instant('edge.unassign-edge-text'); | |
607 | - label = $translate.instant('edge.unassign-edge'); | |
608 | - } | |
609 | - var confirm = $mdDialog.confirm() | |
610 | - .targetEvent($event) | |
611 | - .title(title) | |
612 | - .htmlContent(content) | |
613 | - .ariaLabel(label) | |
614 | - .cancel($translate.instant('action.no')) | |
615 | - .ok($translate.instant('action.yes')); | |
616 | - $mdDialog.show(confirm).then(function () { | |
617 | - edgeService.unassignEdgeFromCustomer(edge.id.id).then(function success() { | |
618 | - vm.grid.refreshList(); | |
619 | - }); | |
620 | - }); | |
621 | - } | |
622 | - | |
623 | - function unassignEdgesFromCustomer($event, items) { | |
624 | - var confirm = $mdDialog.confirm() | |
625 | - .targetEvent($event) | |
626 | - .title($translate.instant('edge.unassign-edges-title', {count: items.selectedCount}, 'messageformat')) | |
627 | - .htmlContent($translate.instant('edge.unassign-edges-text')) | |
628 | - .ariaLabel($translate.instant('edge.unassign-edge')) | |
629 | - .cancel($translate.instant('action.no')) | |
630 | - .ok($translate.instant('action.yes')); | |
631 | - $mdDialog.show(confirm).then(function () { | |
632 | - var tasks = []; | |
633 | - for (var id in items.selections) { | |
634 | - tasks.push(edgeService.unassignEdgeFromCustomer(id)); | |
635 | - } | |
636 | - $q.all(tasks).then(function () { | |
637 | - vm.grid.refreshList(); | |
638 | - }); | |
639 | - }); | |
640 | - } | |
641 | - | |
642 | - function makePublic($event, edge) { | |
643 | - if ($event) { | |
644 | - $event.stopPropagation(); | |
645 | - } | |
646 | - var confirm = $mdDialog.confirm() | |
647 | - .targetEvent($event) | |
648 | - .title($translate.instant('edge.make-public-edge-title', {edgeName: edge.name})) | |
649 | - .htmlContent($translate.instant('edge.make-public-edge-text')) | |
650 | - .ariaLabel($translate.instant('edge.make-public')) | |
651 | - .cancel($translate.instant('action.no')) | |
652 | - .ok($translate.instant('action.yes')); | |
653 | - $mdDialog.show(confirm).then(function () { | |
654 | - edgeService.makeEdgePublic(edge.id.id).then(function success() { | |
655 | - vm.grid.refreshList(); | |
656 | - }); | |
657 | - }); | |
658 | - } | |
659 | - | |
660 | - function openEdgeDashboards($event, edge) { | |
661 | - if ($event) { | |
662 | - $event.stopPropagation(); | |
663 | - } | |
664 | - $state.go('home.edges.dashboards', {edgeId: edge.id.id}); | |
665 | - } | |
666 | - | |
667 | - function openEdgeRuleChains($event, edge) { | |
668 | - if ($event) { | |
669 | - $event.stopPropagation(); | |
670 | - } | |
671 | - $state.go('home.edges.ruleChains', {edgeId: edge.id.id}); | |
672 | - } | |
673 | - | |
674 | - function openEdgeAssets($event, edge) { | |
675 | - if ($event) { | |
676 | - $event.stopPropagation(); | |
677 | - } | |
678 | - $state.go('home.edges.assets', {edgeId: edge.id.id}); | |
679 | - } | |
680 | - | |
681 | - function openEdgeDevices($event, edge) { | |
682 | - if ($event) { | |
683 | - $event.stopPropagation(); | |
684 | - } | |
685 | - $state.go('home.edges.devices', {edgeId: edge.id.id}); | |
686 | - } | |
687 | - | |
688 | - function openEdgeEntityViews($event, edge) { | |
689 | - if ($event) { | |
690 | - $event.stopPropagation(); | |
691 | - } | |
692 | - $state.go('home.edges.entityViews', {edgeId: edge.id.id}); | |
693 | - } | |
694 | - | |
695 | -} |
ui/src/app/edge/edge.directive.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 | -/* eslint-disable import/no-unresolved, import/default */ | |
17 | - | |
18 | -import edgeFieldsetTemplate from './edge-fieldset.tpl.html'; | |
19 | - | |
20 | -/* eslint-enable import/no-unresolved, import/default */ | |
21 | - | |
22 | -/*@ngInject*/ | |
23 | -export default function EdgeDirective($compile, $templateCache, $translate, $mdDialog, $document, utils, toast, types, customerService, edgeService) { | |
24 | - var linker = function (scope, element) { | |
25 | - var template = $templateCache.get(edgeFieldsetTemplate); | |
26 | - element.html(template); | |
27 | - | |
28 | - scope.types = types; | |
29 | - scope.isAssignedToCustomer = false; | |
30 | - scope.isPublic = false; | |
31 | - scope.assignedCustomer = null; | |
32 | - | |
33 | - scope.$watch('edge', function(newVal) { | |
34 | - if (newVal) { | |
35 | - if (!scope.edge.id) { | |
36 | - scope.edge.routingKey = utils.guid(''); | |
37 | - scope.edge.secret = generateSecret(20); | |
38 | - scope.edge.cloudEndpoint = utils.baseUrl(); | |
39 | - } | |
40 | - if (scope.edge.customerId && scope.edge.customerId.id !== types.id.nullUid) { | |
41 | - scope.isAssignedToCustomer = true; | |
42 | - customerService.getShortCustomerInfo(scope.edge.customerId.id).then( | |
43 | - function success(customer) { | |
44 | - scope.assignedCustomer = customer; | |
45 | - scope.isPublic = customer.isPublic; | |
46 | - } | |
47 | - ); | |
48 | - } else { | |
49 | - scope.isAssignedToCustomer = false; | |
50 | - scope.isPublic = false; | |
51 | - scope.assignedCustomer = null; | |
52 | - } | |
53 | - } | |
54 | - }); | |
55 | - | |
56 | - function generateSecret(length) { | |
57 | - if (angular.isUndefined(length) || length == null) { | |
58 | - length = 1; | |
59 | - } | |
60 | - var l = length > 10 ? 10 : length; | |
61 | - var str = Math.random().toString(36).substr(2, l); | |
62 | - if(str.length >= length){ | |
63 | - return str; | |
64 | - } | |
65 | - return str.concat(generateSecret(length - str.length)); | |
66 | - } | |
67 | - | |
68 | - scope.onEdgeIdCopied = function() { | |
69 | - toast.showSuccess($translate.instant('edge.id-copied-message'), 750, angular.element(element).parent().parent(), 'bottom left'); | |
70 | - }; | |
71 | - | |
72 | - scope.onEdgeSync = function (edgeId) { | |
73 | - edgeService.syncEdge(edgeId).then( | |
74 | - function success() { | |
75 | - toast.showSuccess($translate.instant('edge.sync-message'), 750, angular.element(element).parent().parent(), 'bottom left'); | |
76 | - }, | |
77 | - function fail(error) { | |
78 | - toast.showError(error); | |
79 | - } | |
80 | - ); | |
81 | - } | |
82 | - | |
83 | - $compile(element.contents())(scope); | |
84 | - | |
85 | - scope.onEdgeInfoCopied = function(type) { | |
86 | - let infoTypeLabel = ""; | |
87 | - switch (type) { | |
88 | - case 'key': | |
89 | - infoTypeLabel = "edge.edge-key-copied-message"; | |
90 | - break; | |
91 | - case 'secret': | |
92 | - infoTypeLabel = "edge.edge-secret-copied-message"; | |
93 | - break; | |
94 | - } | |
95 | - toast.showSuccess($translate.instant(infoTypeLabel), 750, angular.element(element).parent().parent(), 'bottom left'); | |
96 | - }; | |
97 | - | |
98 | - }; | |
99 | - return { | |
100 | - restrict: "E", | |
101 | - link: linker, | |
102 | - scope: { | |
103 | - edge: '=', | |
104 | - isEdit: '=', | |
105 | - edgeScope: '=', | |
106 | - theForm: '=', | |
107 | - onAssignToCustomer: '&', | |
108 | - onMakePublic: '&', | |
109 | - onUnassignFromCustomer: '&', | |
110 | - onManageEdgeAssets: '&', | |
111 | - onManageEdgeDevices: '&', | |
112 | - onManageEdgeEntityViews: '&', | |
113 | - onManageEdgeDashboards: '&', | |
114 | - onManageEdgeRuleChains: '&', | |
115 | - onDeleteEdge: '&' | |
116 | - } | |
117 | - }; | |
118 | -} |
ui/src/app/edge/edge.routes.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 | -/* eslint-disable import/no-unresolved, import/default */ | |
17 | - | |
18 | -import edgesTemplate from './edges.tpl.html'; | |
19 | -import entityViewsTemplate from "../entity-view/entity-views.tpl.html"; | |
20 | -import devicesTemplate from "../device/devices.tpl.html"; | |
21 | -import assetsTemplate from "../asset/assets.tpl.html"; | |
22 | -import dashboardsTemplate from "../dashboard/dashboards.tpl.html"; | |
23 | -import dashboardTemplate from "../dashboard/dashboard.tpl.html"; | |
24 | -import ruleChainsTemplate from "../rulechain/rulechains.tpl.html"; | |
25 | -import ruleChainTemplate from "../rulechain/rulechain.tpl.html"; | |
26 | - | |
27 | -/* eslint-enable import/no-unresolved, import/default */ | |
28 | - | |
29 | -/*@ngInject*/ | |
30 | -export default function EdgeRoutes($stateProvider, types) { | |
31 | - $stateProvider | |
32 | - .state('home.edges', { | |
33 | - url: '/edges', | |
34 | - params: {'topIndex': 0}, | |
35 | - module: 'private', | |
36 | - auth: ['TENANT_ADMIN', 'CUSTOMER_USER'], | |
37 | - views: { | |
38 | - "content@home": { | |
39 | - templateUrl: edgesTemplate, | |
40 | - controller: 'EdgeController', | |
41 | - controllerAs: 'vm' | |
42 | - } | |
43 | - }, | |
44 | - data: { | |
45 | - edgesType: 'tenant', | |
46 | - searchEnabled: true, | |
47 | - searchByEntitySubtype: true, | |
48 | - searchEntityType: types.entityType.edge, | |
49 | - pageTitle: 'edge.edges' | |
50 | - }, | |
51 | - ncyBreadcrumb: { | |
52 | - label: '{"icon": "router", "label": "edge.edges"}' | |
53 | - } | |
54 | - }).state('home.edges.entityViews', { | |
55 | - url: '/:edgeId/entityViews', | |
56 | - params: {'topIndex': 0}, | |
57 | - module: 'private', | |
58 | - auth: ['TENANT_ADMIN'], | |
59 | - views: { | |
60 | - "content@home": { | |
61 | - templateUrl: entityViewsTemplate, | |
62 | - controllerAs: 'vm', | |
63 | - controller: 'EntityViewController' | |
64 | - } | |
65 | - }, | |
66 | - data: { | |
67 | - entityViewsType: 'edge', | |
68 | - searchEnabled: true, | |
69 | - searchByEntitySubtype: true, | |
70 | - searchEntityType: types.entityType.entityView, | |
71 | - pageTitle: 'edge.entity-views' | |
72 | - }, | |
73 | - ncyBreadcrumb: { | |
74 | - label: '{"icon": "view_quilt", "label": "edge.entity-views"}' | |
75 | - } | |
76 | - }).state('home.edges.devices', { | |
77 | - url: '/:edgeId/devices', | |
78 | - params: {'topIndex': 0}, | |
79 | - module: 'private', | |
80 | - auth: ['TENANT_ADMIN'], | |
81 | - views: { | |
82 | - "content@home": { | |
83 | - templateUrl: devicesTemplate, | |
84 | - controllerAs: 'vm', | |
85 | - controller: 'DeviceController' | |
86 | - } | |
87 | - }, | |
88 | - data: { | |
89 | - devicesType: 'edge', | |
90 | - searchEnabled: true, | |
91 | - searchByEntitySubtype: true, | |
92 | - searchEntityType: types.entityType.device, | |
93 | - pageTitle: 'edge.devices' | |
94 | - }, | |
95 | - ncyBreadcrumb: { | |
96 | - label: '{"icon": "devices_other", "label": "edge.devices"}' | |
97 | - } | |
98 | - }).state('home.edges.assets', { | |
99 | - url: '/:edgeId/assets', | |
100 | - params: {'topIndex': 0}, | |
101 | - module: 'private', | |
102 | - auth: ['TENANT_ADMIN'], | |
103 | - views: { | |
104 | - "content@home": { | |
105 | - templateUrl: assetsTemplate, | |
106 | - controllerAs: 'vm', | |
107 | - controller: 'AssetController' | |
108 | - } | |
109 | - }, | |
110 | - data: { | |
111 | - assetsType: 'edge', | |
112 | - searchEnabled: true, | |
113 | - searchByEntitySubtype: true, | |
114 | - searchEntityType: types.entityType.asset, | |
115 | - pageTitle: 'edge.assets' | |
116 | - }, | |
117 | - ncyBreadcrumb: { | |
118 | - label: '{"icon": "domain", "label": "edge.assets"}' | |
119 | - } | |
120 | - }).state('home.edges.dashboards', { | |
121 | - url: '/:edgeId/dashboards', | |
122 | - params: {'topIndex': 0}, | |
123 | - module: 'private', | |
124 | - auth: ['TENANT_ADMIN'], | |
125 | - views: { | |
126 | - "content@home": { | |
127 | - templateUrl: dashboardsTemplate, | |
128 | - controllerAs: 'vm', | |
129 | - controller: 'DashboardsController' | |
130 | - } | |
131 | - }, | |
132 | - data: { | |
133 | - dashboardsType: 'edge', | |
134 | - searchEnabled: true, | |
135 | - pageTitle: 'edge.dashboards' | |
136 | - }, | |
137 | - ncyBreadcrumb: { | |
138 | - label: '{"icon": "dashboard", "label": "edge.dashboards"}' | |
139 | - } | |
140 | - }).state('home.edges.dashboards.dashboard', { | |
141 | - url: '/:dashboardId?state', | |
142 | - reloadOnSearch: false, | |
143 | - module: 'private', | |
144 | - auth: ['TENANT_ADMIN', 'CUSTOMER_USER'], | |
145 | - views: { | |
146 | - "content@home": { | |
147 | - templateUrl: dashboardTemplate, | |
148 | - controller: 'DashboardController', | |
149 | - controllerAs: 'vm' | |
150 | - } | |
151 | - }, | |
152 | - data: { | |
153 | - widgetEditMode: false, | |
154 | - searchEnabled: false, | |
155 | - pageTitle: 'dashboard.dashboard', | |
156 | - dashboardsType: 'edge', | |
157 | - }, | |
158 | - ncyBreadcrumb: { | |
159 | - label: '{"icon": "dashboard", "label": "{{ vm.dashboard.title }}", "translate": "false"}' | |
160 | - } | |
161 | - }).state('home.customers.edges', { | |
162 | - url: '/:customerId/edges', | |
163 | - params: {'topIndex': 0}, | |
164 | - module: 'private', | |
165 | - auth: ['TENANT_ADMIN'], | |
166 | - views: { | |
167 | - "content@home": { | |
168 | - templateUrl: edgesTemplate, | |
169 | - controllerAs: 'vm', | |
170 | - controller: 'EdgeController' | |
171 | - } | |
172 | - }, | |
173 | - data: { | |
174 | - edgesType: 'customer', | |
175 | - searchEnabled: true, | |
176 | - searchByEntitySubtype: true, | |
177 | - searchEntityType: types.entityType.edge, | |
178 | - pageTitle: 'customer.edges' | |
179 | - }, | |
180 | - ncyBreadcrumb: { | |
181 | - label: '{"icon": "router", "label": "{{ vm.customerEdgesTitle }}", "translate": "false"}' | |
182 | - } | |
183 | - }).state('home.edges.ruleChains', { | |
184 | - url: '/:edgeId/ruleChains', | |
185 | - params: {'topIndex': 0}, | |
186 | - module: 'private', | |
187 | - auth: ['TENANT_ADMIN'], | |
188 | - views: { | |
189 | - "content@home": { | |
190 | - templateUrl: ruleChainsTemplate, | |
191 | - controllerAs: 'vm', | |
192 | - controller: 'RuleChainsController' | |
193 | - } | |
194 | - }, | |
195 | - data: { | |
196 | - searchEnabled: true, | |
197 | - pageTitle: 'rulechain.edge-rulechains', | |
198 | - ruleChainsType: 'edge' | |
199 | - }, | |
200 | - ncyBreadcrumb: { | |
201 | - label: '{"icon": "code", "label": "rulechain.edge-rulechains"}' | |
202 | - } | |
203 | - }).state('home.edges.ruleChains.ruleChain', { | |
204 | - url: '/:ruleChainId', | |
205 | - reloadOnSearch: false, | |
206 | - module: 'private', | |
207 | - auth: ['SYS_ADMIN', 'TENANT_ADMIN'], | |
208 | - views: { | |
209 | - "content@home": { | |
210 | - templateUrl: ruleChainTemplate, | |
211 | - controller: 'RuleChainController', | |
212 | - controllerAs: 'vm' | |
213 | - } | |
214 | - }, | |
215 | - resolve: { | |
216 | - ruleChain: | |
217 | - /*@ngInject*/ | |
218 | - function($stateParams, ruleChainService) { | |
219 | - return ruleChainService.getRuleChain($stateParams.ruleChainId); | |
220 | - }, | |
221 | - ruleChainMetaData: | |
222 | - /*@ngInject*/ | |
223 | - function($stateParams, ruleChainService) { | |
224 | - return ruleChainService.getRuleChainMetaData($stateParams.ruleChainId); | |
225 | - }, | |
226 | - ruleNodeComponents: | |
227 | - /*@ngInject*/ | |
228 | - function($stateParams, ruleChainService) { | |
229 | - return ruleChainService.getRuleNodeComponents(types.ruleChainType.edge); | |
230 | - } | |
231 | - }, | |
232 | - data: { | |
233 | - import: false, | |
234 | - searchEnabled: false, | |
235 | - pageTitle: 'edge.rulechain' | |
236 | - }, | |
237 | - ncyBreadcrumb: { | |
238 | - label: '{"icon": "code", "label": "{{ vm.ruleChain.name }}", "translate": "false"}' | |
239 | - } | |
240 | - }); | |
241 | -} |
ui/src/app/edge/edges.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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 | -<tb-grid grid-configuration="vm.edgeGridConfig"> | |
19 | - <details-buttons tb-help="'edges'" help-container-id="help-container"> | |
20 | - <div id="help-container"></div> | |
21 | - </details-buttons> | |
22 | - <md-tabs ng-class="{'tb-headless': vm.grid.detailsConfig.isDetailsEditMode}" | |
23 | - id="tabs" md-border-bottom flex class="tb-absolute-fill"> | |
24 | - <md-tab label="{{ 'edge.details' | translate }}"> | |
25 | - <tb-edge edge="vm.grid.operatingItem()" | |
26 | - is-edit="vm.grid.detailsConfig.isDetailsEditMode" | |
27 | - edge-scope="vm.edgesScope" | |
28 | - 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)" | |
31 | - on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)" | |
32 | - on-manage-edge-assets="vm.openEdgeAssets(event, vm.grid.detailsConfig.currentItem)" | |
33 | - on-manage-edge-devices="vm.openEdgeDevices(event, vm.grid.detailsConfig.currentItem)" | |
34 | - on-manage-edge-entity-views="vm.openEdgeEntityViews(event, vm.grid.detailsConfig.currentItem)" | |
35 | - on-manage-edge-dashboards="vm.openEdgeDashboards(event, vm.grid.detailsConfig.currentItem)" | |
36 | - on-manage-edge-rule-chains="vm.openEdgeRuleChains(event, vm.grid.detailsConfig.currentItem)" | |
37 | - on-delete-edge="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-edge> | |
38 | - </md-tab> | |
39 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}"> | |
40 | - <tb-attribute-table flex | |
41 | - entity-id="vm.grid.operatingItem().id.id" | |
42 | - entity-type="{{vm.types.entityType.edge}}" | |
43 | - entity-name="vm.grid.operatingItem().name" | |
44 | - default-attribute-scope="{{vm.types.attributesScope.server.value}}"> | |
45 | - </tb-attribute-table> | |
46 | - </md-tab> | |
47 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}"> | |
48 | - <tb-attribute-table flex | |
49 | - entity-id="vm.grid.operatingItem().id.id" | |
50 | - entity-type="{{vm.types.entityType.edge}}" | |
51 | - entity-name="vm.grid.operatingItem().name" | |
52 | - default-attribute-scope="{{vm.types.latestTelemetry.value}}" | |
53 | - disable-attribute-scope-selection="true"> | |
54 | - </tb-attribute-table> | |
55 | - </md-tab> | |
56 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}"> | |
57 | - <tb-alarm-table flex entity-type="vm.types.entityType.edge" | |
58 | - entity-id="vm.grid.operatingItem().id.id"> | |
59 | - </tb-alarm-table> | |
60 | - </md-tab> | |
61 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'edge.events' | translate }}"> | |
62 | - <tb-event-table flex entity-type="vm.types.entityType.edge" | |
63 | - entity-id="vm.grid.operatingItem().id.id" | |
64 | - tenant-id="vm.grid.operatingItem().tenantId.id" | |
65 | - default-event-type="{{vm.types.eventType.error.value}}"> | |
66 | - </tb-event-table> | |
67 | - </md-tab> | |
68 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}"> | |
69 | - <tb-relation-table flex | |
70 | - readonly="!('edge' | hasGenericPermission:'write')" | |
71 | - entity-id="vm.grid.operatingItem().id.id" | |
72 | - entity-type="{{vm.types.entityType.edge}}"> | |
73 | - </tb-relation-table> | |
74 | - </md-tab> | |
75 | - <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.grid.isTenantAdmin()" md-on-select="vm.grid.triggerResize()" label="{{ 'audit-log.audit-logs' | translate }}"> | |
76 | - <tb-audit-log-table flex entity-type="vm.types.entityType.edge" | |
77 | - entity-id="vm.grid.operatingItem().id.id" | |
78 | - audit-log-mode="{{vm.types.auditLogMode.entity}}"> | |
79 | - </tb-audit-log-table> | |
80 | - </md-tab> | |
81 | - </md-tabs> | |
82 | -</tb-grid> |
ui/src/app/edge/index.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 | -import uiRouter from 'angular-ui-router'; | |
17 | -import thingsboardGrid from '../components/grid.directive'; | |
18 | -import thingsboardApiUser from '../api/user.service'; | |
19 | -import thingsboardApiEdge from '../api/edge.service'; | |
20 | -import thingsboardApiCustomer from '../api/customer.service'; | |
21 | - | |
22 | -import EdgeRoutes from './edge.routes'; | |
23 | -import {EdgeController, EdgeCardController} from './edge.controller'; | |
24 | -import AssignEdgeToCustomerController from './assign-to-customer.controller'; | |
25 | -import AddEdgesToCustomerController from './add-edges-to-customer.controller'; | |
26 | -import SetRootRuleChainToEdgesController from './set-root-rule-chain-to-edges.controller'; | |
27 | -import EdgeDirective from './edge.directive'; | |
28 | - | |
29 | -export default angular.module('thingsboard.edge', [ | |
30 | - uiRouter, | |
31 | - thingsboardGrid, | |
32 | - thingsboardApiUser, | |
33 | - thingsboardApiEdge, | |
34 | - thingsboardApiCustomer | |
35 | -]) | |
36 | - .config(EdgeRoutes) | |
37 | - .controller('EdgeController', EdgeController) | |
38 | - .controller('EdgeCardController', EdgeCardController) | |
39 | - .controller('AssignEdgeToCustomerController', AssignEdgeToCustomerController) | |
40 | - .controller('AddEdgesToCustomerController', AddEdgesToCustomerController) | |
41 | - .controller('SetRootRuleChainToEdgesController', SetRootRuleChainToEdgesController) | |
42 | - .directive('tbEdge', EdgeDirective) | |
43 | - .name; |
ui/src/app/edge/set-root-rule-chain-to-edges.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 SetRootRuleChainToEdgesController(ruleChainService, edgeService, $mdDialog, $q, edgeIds, ruleChains) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.ruleChains = ruleChains; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.isRuleChainSelected = isRuleChainSelected; | |
27 | - vm.hasData = hasData; | |
28 | - vm.noData = noData; | |
29 | - vm.searchRuleChainTextUpdated = searchRuleChainTextUpdated; | |
30 | - vm.toggleRuleChainSelection = toggleRuleChainSelection; | |
31 | - | |
32 | - vm.theRuleChains = { | |
33 | - getItemAtIndex: function (index) { | |
34 | - if (index > vm.ruleChains.data.length) { | |
35 | - vm.theRuleChains.fetchMoreItems_(index); | |
36 | - return null; | |
37 | - } | |
38 | - var item = vm.ruleChains.data[index]; | |
39 | - if (item) { | |
40 | - item.indexNumber = index + 1; | |
41 | - } | |
42 | - return item; | |
43 | - }, | |
44 | - | |
45 | - getLength: function () { | |
46 | - if (vm.ruleChains.hasNext) { | |
47 | - return vm.ruleChains.data.length + vm.ruleChains.nextPageLink.limit; | |
48 | - } else { | |
49 | - return vm.ruleChains.data.length; | |
50 | - } | |
51 | - }, | |
52 | - | |
53 | - fetchMoreItems_: function () { | |
54 | - if (vm.ruleChains.hasNext && !vm.ruleChains.pending) { | |
55 | - vm.ruleChains.pending = true; | |
56 | - ruleChainService.getEdgesRuleChains(vm.ruleChains.nextPageLink).then( | |
57 | - function success(ruleChains) { | |
58 | - vm.ruleChains.data = vm.ruleChains.data.concat(ruleChains.data); | |
59 | - vm.ruleChains.nextPageLink = ruleChains.nextPageLink; | |
60 | - vm.ruleChains.hasNext = ruleChains.hasNext; | |
61 | - if (vm.ruleChains.hasNext) { | |
62 | - vm.ruleChains.nextPageLink.limit = vm.ruleChains.pageSize; | |
63 | - } | |
64 | - vm.ruleChains.pending = false; | |
65 | - }, | |
66 | - function fail() { | |
67 | - vm.ruleChains.hasNext = false; | |
68 | - vm.ruleChains.pending = false; | |
69 | - }); | |
70 | - } | |
71 | - } | |
72 | - }; | |
73 | - | |
74 | - function cancel() { | |
75 | - $mdDialog.cancel(); | |
76 | - } | |
77 | - | |
78 | - function assign() { | |
79 | - var assignTasks = []; | |
80 | - for (var i=0;i<edgeIds.length;i++) { | |
81 | - assignTasks.push(ruleChainService.assignRuleChainToEdge(edgeIds[i], vm.ruleChains.selection.id.id)); | |
82 | - } | |
83 | - $q.all(assignTasks).then(function () { | |
84 | - var setRootTasks = []; | |
85 | - for (var j=0;j<edgeIds.length;j++) { | |
86 | - setRootTasks.push(edgeService.setRootRuleChain(edgeIds[j], vm.ruleChains.selection.id.id)); | |
87 | - } | |
88 | - $q.all(setRootTasks).then(function () { | |
89 | - $mdDialog.hide(); | |
90 | - }); | |
91 | - }); | |
92 | - } | |
93 | - | |
94 | - function noData() { | |
95 | - return vm.ruleChains.data.length == 0 && !vm.ruleChains.hasNext; | |
96 | - } | |
97 | - | |
98 | - function hasData() { | |
99 | - return vm.ruleChains.data.length > 0; | |
100 | - } | |
101 | - | |
102 | - function toggleRuleChainSelection($event, ruleChain) { | |
103 | - $event.stopPropagation(); | |
104 | - if (vm.isRuleChainSelected(ruleChain)) { | |
105 | - vm.ruleChains.selection = null; | |
106 | - } else { | |
107 | - vm.ruleChains.selection = ruleChain; | |
108 | - } | |
109 | - } | |
110 | - | |
111 | - function isRuleChainSelected(ruleChain) { | |
112 | - return vm.ruleChains.selection != null && ruleChain && | |
113 | - ruleChain.id.id === vm.ruleChains.selection.id.id; | |
114 | - } | |
115 | - | |
116 | - function searchRuleChainTextUpdated() { | |
117 | - vm.ruleChains = { | |
118 | - pageSize: vm.ruleChains.pageSize, | |
119 | - data: [], | |
120 | - nextPageLink: { | |
121 | - limit: vm.ruleChains.pageSize, | |
122 | - textSearch: vm.searchText | |
123 | - }, | |
124 | - selection: null, | |
125 | - hasNext: true, | |
126 | - pending: false | |
127 | - }; | |
128 | - } | |
129 | -} |
ui/src/app/edge/set-root-rule-chain-to-edges.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.set-root-rulechain-to-edges' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>edge.set-root-rulechain-to-edges</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>edge.set-root-rulechain-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="rule-chain-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchRuleChainTextUpdated()" | |
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()">rulechain.no-rulechains-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="ruleChain in vm.theRuleChains" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleRuleChainSelection($event, ruleChain)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="vm.isRuleChainSelected(ruleChain)"></md-checkbox> | |
58 | - <span> {{ ruleChain.name }} </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.ruleChains.selection==null" type="submit" class="md-raised md-primary"> | |
69 | - {{ 'action.assign' | translate }} | |
70 | - </md-button> | |
71 | - <md-button ng-disabled="$root.loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | |
72 | - translate }} | |
73 | - </md-button> | |
74 | - </md-dialog-actions> | |
75 | - </form> | |
76 | -</md-dialog> | |
\ No newline at end of file |
ui/src/app/entity-view/add-entity-views-to-edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AddEntityViewsToEdgeController(entityViewService, $mdDialog, $q, edgeId, entityViews) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.entityViews = entityViews; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.hasData = hasData; | |
27 | - vm.noData = noData; | |
28 | - vm.searchEntityViewTextUpdated = searchEntityViewTextUpdated; | |
29 | - vm.toggleEntityViewSelection = toggleEntityViewSelection; | |
30 | - | |
31 | - vm.theEntityViews = { | |
32 | - getItemAtIndex: function (index) { | |
33 | - if (index > vm.entityViews.data.length) { | |
34 | - vm.theEntityViews.fetchMoreItems_(index); | |
35 | - return null; | |
36 | - } | |
37 | - var item = vm.entityViews.data[index]; | |
38 | - if (item) { | |
39 | - item.indexNumber = index + 1; | |
40 | - } | |
41 | - return item; | |
42 | - }, | |
43 | - | |
44 | - getLength: function () { | |
45 | - if (vm.entityViews.hasNext) { | |
46 | - return vm.entityViews.data.length + vm.entityViews.nextPageLink.limit; | |
47 | - } else { | |
48 | - return vm.entityViews.data.length; | |
49 | - } | |
50 | - }, | |
51 | - | |
52 | - fetchMoreItems_: function () { | |
53 | - if (vm.entityViews.hasNext && !vm.entityViews.pending) { | |
54 | - vm.entityViews.pending = true; | |
55 | - entityViewService.getTenantEntityViews(vm.entityViews.nextPageLink, false).then( | |
56 | - function success(entityViews) { | |
57 | - vm.entityViews.data = vm.entityViews.data.concat(entityViews.data); | |
58 | - vm.entityViews.nextPageLink = entityViews.nextPageLink; | |
59 | - vm.entityViews.hasNext = entityViews.hasNext; | |
60 | - if (vm.entityViews.hasNext) { | |
61 | - vm.entityViews.nextPageLink.limit = vm.entityViews.pageSize; | |
62 | - } | |
63 | - vm.entityViews.pending = false; | |
64 | - }, | |
65 | - function fail() { | |
66 | - vm.entityViews.hasNext = false; | |
67 | - vm.entityViews.pending = false; | |
68 | - }); | |
69 | - } | |
70 | - } | |
71 | - }; | |
72 | - | |
73 | - function cancel () { | |
74 | - $mdDialog.cancel(); | |
75 | - } | |
76 | - | |
77 | - function assign() { | |
78 | - var tasks = []; | |
79 | - for (var entityViewId in vm.entityViews.selections) { | |
80 | - tasks.push(entityViewService.assignEntityViewToEdge(edgeId, entityViewId)); | |
81 | - } | |
82 | - $q.all(tasks).then(function () { | |
83 | - $mdDialog.hide(); | |
84 | - }); | |
85 | - } | |
86 | - | |
87 | - function noData() { | |
88 | - return vm.entityViews.data.length == 0 && !vm.entityViews.hasNext; | |
89 | - } | |
90 | - | |
91 | - function hasData() { | |
92 | - return vm.entityViews.data.length > 0; | |
93 | - } | |
94 | - | |
95 | - function toggleEntityViewSelection($event, entityView) { | |
96 | - $event.stopPropagation(); | |
97 | - var selected = angular.isDefined(entityView.selected) && entityView.selected; | |
98 | - entityView.selected = !selected; | |
99 | - if (entityView.selected) { | |
100 | - vm.entityViews.selections[entityView.id.id] = true; | |
101 | - vm.entityViews.selectedCount++; | |
102 | - } else { | |
103 | - delete vm.entityViews.selections[entityView.id.id]; | |
104 | - vm.entityViews.selectedCount--; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - function searchEntityViewTextUpdated() { | |
109 | - vm.entityViews = { | |
110 | - pageSize: vm.entityViews.pageSize, | |
111 | - data: [], | |
112 | - nextPageLink: { | |
113 | - limit: vm.entityViews.pageSize, | |
114 | - textSearch: vm.searchText | |
115 | - }, | |
116 | - selections: {}, | |
117 | - selectedCount: 0, | |
118 | - hasNext: true, | |
119 | - pending: false | |
120 | - }; | |
121 | - } | |
122 | - | |
123 | -} |
ui/src/app/entity-view/add-entity-views-to-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'edge.assign-to-edge' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>entity-view.assign-entity-view-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>entity-view.assign-entity-view-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="entity-view-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchEntityViewTextUpdated()" | |
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()">entity-view.no-entity-views-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="entityView in vm.theEntityViews" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleEntityViewSelection($event, entityView)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="entityView.selected"></md-checkbox> | |
58 | - <span> {{ entityView.name }} </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.entityViews.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> | |
\ No newline at end of file |
ui/src/app/event/event-header-edge-event.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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 | -<div translate class="tb-cell" flex="20">event.event-time</div> | |
19 | -<div translate class="tb-cell" flex="20">event.event-type</div> | |
20 | -<div translate class="tb-cell" flex="40">edge.event-action</div> | |
21 | -<div translate class="tb-cell" flex="20">edge.entity-id</div> | |
22 | -<div translate class="tb-cell" flex="15">edge.status</div> | |
23 | -<div translate class="tb-cell" flex="10">edge.entity-info</div> |
ui/src/app/event/event-row-edge-event.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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 | -<div class="tb-cell" flex="20">{{ event.createdTime | date : 'yyyy-MM-dd HH:mm:ss' }}</div> | |
19 | -<div class="tb-cell" flex="20">{{ event.type }}</div> | |
20 | -<div class="tb-cell" flex="40">{{ event.action }}</div> | |
21 | -<div class="tb-cell" flex="20">{{ event.entityId }}</div> | |
22 | -<div class="tb-cell" flex="15" ng-style="{'color': statusColor}">{{ updateStatus(event.createdTime) }}</div> | |
23 | -<div class="tb-cell" flex="10"> | |
24 | - <md-button ng-if="checkEdgeEventType(event.type)" class="md-icon-button md-primary" | |
25 | - ng-click="showEdgeEntityContent($event, 'edge.entity-info', 'JSON')" | |
26 | - aria-label="{{ 'action.view' | translate }}"> | |
27 | - <md-tooltip md-direction="top"> | |
28 | - {{ 'action.view' | translate }} | |
29 | - </md-tooltip> | |
30 | - <md-icon aria-label="{{ 'action.view' | translate }}" | |
31 | - class="material-icons"> | |
32 | - more_horiz | |
33 | - </md-icon> | |
34 | - </md-button> | |
35 | -</div> | |
36 | - | |
37 | - |
ui/src/app/rulechain/add-rulechains-to-edge.controller.js
deleted
100644 → 0
1 | -/* | |
2 | - * Copyright © 2016-2020 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 AddRuleChainsToEdgeController(ruleChainService, $mdDialog, $q, $filter, edgeId, ruleChains) { | |
18 | - | |
19 | - var vm = this; | |
20 | - | |
21 | - vm.ruleChains = ruleChains; | |
22 | - vm.searchText = ''; | |
23 | - | |
24 | - vm.assign = assign; | |
25 | - vm.cancel = cancel; | |
26 | - vm.hasData = hasData; | |
27 | - vm.noData = noData; | |
28 | - vm.searchRuleChainTextUpdated = searchRuleChainTextUpdated; | |
29 | - vm.toggleRuleChainSelection = toggleRuleChainSelection; | |
30 | - | |
31 | - vm.theRuleChains = { | |
32 | - getItemAtIndex: function (index) { | |
33 | - if (index > vm.ruleChains.data.length) { | |
34 | - vm.theRuleChains.fetchMoreItems_(index); | |
35 | - return null; | |
36 | - } | |
37 | - var item = vm.ruleChains.data[index]; | |
38 | - if (item) { | |
39 | - item.indexNumber = index + 1; | |
40 | - } | |
41 | - return item; | |
42 | - }, | |
43 | - | |
44 | - getLength: function () { | |
45 | - if (vm.ruleChains.hasNext) { | |
46 | - return vm.ruleChains.data.length + vm.ruleChains.nextPageLink.limit; | |
47 | - } else { | |
48 | - return vm.ruleChains.data.length; | |
49 | - } | |
50 | - }, | |
51 | - | |
52 | - fetchMoreItems_: function () { | |
53 | - if (vm.ruleChains.hasNext && !vm.ruleChains.pending) { | |
54 | - vm.ruleChains.pending = true; | |
55 | - ruleChainService.getEdgesRuleChains(vm.ruleChains.nextPageLink).then( | |
56 | - function success(ruleChains) { | |
57 | - vm.ruleChains.data = vm.ruleChains.data.concat(ruleChains.data); | |
58 | - vm.ruleChains.nextPageLink = ruleChains.nextPageLink; | |
59 | - vm.ruleChains.hasNext = ruleChains.hasNext; | |
60 | - if (vm.ruleChains.hasNext) { | |
61 | - vm.ruleChains.nextPageLink.limit = vm.ruleChains.pageSize; | |
62 | - } | |
63 | - vm.ruleChains.pending = false; | |
64 | - }, | |
65 | - function fail() { | |
66 | - vm.ruleChains.hasNext = false; | |
67 | - vm.ruleChains.pending = false; | |
68 | - }); | |
69 | - } | |
70 | - } | |
71 | - } | |
72 | - | |
73 | - function cancel () { | |
74 | - $mdDialog.cancel(); | |
75 | - } | |
76 | - | |
77 | - function assign () { | |
78 | - var tasks = []; | |
79 | - for (var ruleChainId in vm.ruleChains.selections) { | |
80 | - tasks.push(ruleChainService.assignRuleChainToEdge(edgeId, ruleChainId)); | |
81 | - } | |
82 | - $q.all(tasks).then(function () { | |
83 | - $mdDialog.hide(); | |
84 | - }); | |
85 | - } | |
86 | - | |
87 | - function noData () { | |
88 | - return vm.ruleChains.data.length == 0 && !vm.ruleChains.hasNext; | |
89 | - } | |
90 | - | |
91 | - function hasData () { | |
92 | - return vm.ruleChains.data.length > 0; | |
93 | - } | |
94 | - | |
95 | - function toggleRuleChainSelection ($event, ruleChain) { | |
96 | - $event.stopPropagation(); | |
97 | - var selected = angular.isDefined(ruleChain.selected) && ruleChain.selected; | |
98 | - ruleChain.selected = !selected; | |
99 | - if (ruleChain.selected) { | |
100 | - vm.ruleChains.selections[ruleChain.id.id] = true; | |
101 | - vm.ruleChains.selectedCount++; | |
102 | - } else { | |
103 | - delete vm.ruleChains.selections[ruleChain.id.id]; | |
104 | - vm.ruleChains.selectedCount--; | |
105 | - } | |
106 | - } | |
107 | - | |
108 | - function searchRuleChainTextUpdated () { | |
109 | - vm.ruleChains = { | |
110 | - pageSize: vm.ruleChains.pageSize, | |
111 | - data: [], | |
112 | - nextPageLink: { | |
113 | - limit: vm.ruleChains.pageSize, | |
114 | - textSearch: vm.searchText | |
115 | - }, | |
116 | - selections: {}, | |
117 | - selectedCount: 0, | |
118 | - hasNext: true, | |
119 | - pending: false | |
120 | - }; | |
121 | - } | |
122 | -} | |
\ No newline at end of file |
ui/src/app/rulechain/add-rulechains-to-edge.tpl.html
deleted
100644 → 0
1 | -<!-- | |
2 | - | |
3 | - Copyright © 2016-2020 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="{{ 'rulechain.assign-rulechain-to-edge-title' | translate }}"> | |
19 | - <form name="theForm" ng-submit="vm.assign()"> | |
20 | - <md-toolbar> | |
21 | - <div class="md-toolbar-tools"> | |
22 | - <h2 translate>rulechain.assign-rulechain-to-edge-title</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>rulechain.assign-rulechain-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="rulechain-search" autofocus ng-model="vm.searchText" | |
41 | - ng-change="vm.searchRuleChainTextUpdated()" | |
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()">rulechain.no-rulechains-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="ruleChain in vm.theRuleChains" md-on-demand | |
54 | - class="repeated-item" flex> | |
55 | - <md-checkbox ng-click="vm.toggleRuleChainSelection($event, ruleChain)" | |
56 | - aria-label="{{ 'item.selected' | translate }}" | |
57 | - ng-checked="ruleChain.selected"></md-checkbox> | |
58 | - <span> {{ ruleChain.name }} </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.ruleChains.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> |