Showing
61 changed files
with
1516 additions
and
145 deletions
@@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.*; | @@ -21,6 +21,7 @@ import org.springframework.web.bind.annotation.*; | ||
21 | import org.thingsboard.server.common.data.id.EntityId; | 21 | import org.thingsboard.server.common.data.id.EntityId; |
22 | import org.thingsboard.server.common.data.id.EntityIdFactory; | 22 | import org.thingsboard.server.common.data.id.EntityIdFactory; |
23 | import org.thingsboard.server.common.data.relation.EntityRelation; | 23 | import org.thingsboard.server.common.data.relation.EntityRelation; |
24 | +import org.thingsboard.server.common.data.relation.EntityRelationInfo; | ||
24 | import org.thingsboard.server.dao.relation.EntityRelationsQuery; | 25 | import org.thingsboard.server.dao.relation.EntityRelationsQuery; |
25 | import org.thingsboard.server.exception.ThingsboardErrorCode; | 26 | import org.thingsboard.server.exception.ThingsboardErrorCode; |
26 | import org.thingsboard.server.exception.ThingsboardException; | 27 | import org.thingsboard.server.exception.ThingsboardException; |
@@ -128,6 +129,21 @@ public class EntityRelationController extends BaseController { | @@ -128,6 +129,21 @@ public class EntityRelationController extends BaseController { | ||
128 | } | 129 | } |
129 | 130 | ||
130 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | 131 | @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") |
132 | + @RequestMapping(value = "/relations/info", method = RequestMethod.GET, params = {"fromId", "fromType"}) | ||
133 | + @ResponseBody | ||
134 | + public List<EntityRelationInfo> findInfoByFrom(@RequestParam("fromId") String strFromId, @RequestParam("fromType") String strFromType) throws ThingsboardException { | ||
135 | + checkParameter("fromId", strFromId); | ||
136 | + checkParameter("fromType", strFromType); | ||
137 | + EntityId entityId = EntityIdFactory.getByTypeAndId(strFromType, strFromId); | ||
138 | + checkEntityId(entityId); | ||
139 | + try { | ||
140 | + return checkNotNull(relationService.findInfoByFrom(entityId).get()); | ||
141 | + } catch (Exception e) { | ||
142 | + throw handleException(e); | ||
143 | + } | ||
144 | + } | ||
145 | + | ||
146 | + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") | ||
131 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"fromId", "fromType", "relationType"}) | 147 | @RequestMapping(value = "/relations", method = RequestMethod.GET, params = {"fromId", "fromType", "relationType"}) |
132 | @ResponseBody | 148 | @ResponseBody |
133 | public List<EntityRelation> findByFrom(@RequestParam("fromId") String strFromId, @RequestParam("fromType") String strFromType | 149 | public List<EntityRelation> findByFrom(@RequestParam("fromId") String strFromId, @RequestParam("fromType") String strFromType |
@@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -20,7 +20,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
20 | 20 | ||
21 | import com.fasterxml.jackson.databind.JsonNode; | 21 | import com.fasterxml.jackson.databind.JsonNode; |
22 | 22 | ||
23 | -public class Customer extends ContactBased<CustomerId>{ | 23 | +public class Customer extends ContactBased<CustomerId> implements HasName { |
24 | 24 | ||
25 | private static final long serialVersionUID = -1599722990298929275L; | 25 | private static final long serialVersionUID = -1599722990298929275L; |
26 | 26 | ||
@@ -59,6 +59,11 @@ public class Customer extends ContactBased<CustomerId>{ | @@ -59,6 +59,11 @@ public class Customer extends ContactBased<CustomerId>{ | ||
59 | this.title = title; | 59 | this.title = title; |
60 | } | 60 | } |
61 | 61 | ||
62 | + @Override | ||
63 | + public String getName() { | ||
64 | + return title; | ||
65 | + } | ||
66 | + | ||
62 | public JsonNode getAdditionalInfo() { | 67 | public JsonNode getAdditionalInfo() { |
63 | return additionalInfo; | 68 | return additionalInfo; |
64 | } | 69 | } |
@@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.id.CustomerId; | @@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.id.CustomerId; | ||
19 | import org.thingsboard.server.common.data.id.DashboardId; | 19 | import org.thingsboard.server.common.data.id.DashboardId; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 20 | import org.thingsboard.server.common.data.id.TenantId; |
21 | 21 | ||
22 | -public class DashboardInfo extends SearchTextBased<DashboardId> { | 22 | +public class DashboardInfo extends SearchTextBased<DashboardId> implements HasName { |
23 | 23 | ||
24 | private TenantId tenantId; | 24 | private TenantId tenantId; |
25 | private CustomerId customerId; | 25 | private CustomerId customerId; |
@@ -65,6 +65,11 @@ public class DashboardInfo extends SearchTextBased<DashboardId> { | @@ -65,6 +65,11 @@ public class DashboardInfo extends SearchTextBased<DashboardId> { | ||
65 | } | 65 | } |
66 | 66 | ||
67 | @Override | 67 | @Override |
68 | + public String getName() { | ||
69 | + return title; | ||
70 | + } | ||
71 | + | ||
72 | + @Override | ||
68 | public String getSearchText() { | 73 | public String getSearchText() { |
69 | return title; | 74 | return title; |
70 | } | 75 | } |
@@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -21,7 +21,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
21 | 21 | ||
22 | import com.fasterxml.jackson.databind.JsonNode; | 22 | import com.fasterxml.jackson.databind.JsonNode; |
23 | 23 | ||
24 | -public class Device extends SearchTextBased<DeviceId> { | 24 | +public class Device extends SearchTextBased<DeviceId> implements HasName { |
25 | 25 | ||
26 | private static final long serialVersionUID = 2807343040519543363L; | 26 | private static final long serialVersionUID = 2807343040519543363L; |
27 | 27 | ||
@@ -64,6 +64,7 @@ public class Device extends SearchTextBased<DeviceId> { | @@ -64,6 +64,7 @@ public class Device extends SearchTextBased<DeviceId> { | ||
64 | this.customerId = customerId; | 64 | this.customerId = customerId; |
65 | } | 65 | } |
66 | 66 | ||
67 | + @Override | ||
67 | public String getName() { | 68 | public String getName() { |
68 | return name; | 69 | return name; |
69 | } | 70 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.common.data; | ||
17 | + | ||
18 | +public interface HasName { | ||
19 | + | ||
20 | + String getName(); | ||
21 | + | ||
22 | +} |
@@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -19,7 +19,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
19 | 19 | ||
20 | import com.fasterxml.jackson.databind.JsonNode; | 20 | import com.fasterxml.jackson.databind.JsonNode; |
21 | 21 | ||
22 | -public class Tenant extends ContactBased<TenantId>{ | 22 | +public class Tenant extends ContactBased<TenantId> implements HasName { |
23 | 23 | ||
24 | private static final long serialVersionUID = 8057243243859922101L; | 24 | private static final long serialVersionUID = 8057243243859922101L; |
25 | 25 | ||
@@ -50,6 +50,11 @@ public class Tenant extends ContactBased<TenantId>{ | @@ -50,6 +50,11 @@ public class Tenant extends ContactBased<TenantId>{ | ||
50 | this.title = title; | 50 | this.title = title; |
51 | } | 51 | } |
52 | 52 | ||
53 | + @Override | ||
54 | + public String getName() { | ||
55 | + return title; | ||
56 | + } | ||
57 | + | ||
53 | public String getRegion() { | 58 | public String getRegion() { |
54 | return region; | 59 | return region; |
55 | } | 60 | } |
@@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.security.Authority; | @@ -22,7 +22,7 @@ import org.thingsboard.server.common.data.security.Authority; | ||
22 | 22 | ||
23 | import com.fasterxml.jackson.databind.JsonNode; | 23 | import com.fasterxml.jackson.databind.JsonNode; |
24 | 24 | ||
25 | -public class User extends SearchTextBased<UserId> { | 25 | +public class User extends SearchTextBased<UserId> implements HasName { |
26 | 26 | ||
27 | private static final long serialVersionUID = 8250339805336035966L; | 27 | private static final long serialVersionUID = 8250339805336035966L; |
28 | 28 | ||
@@ -77,6 +77,11 @@ public class User extends SearchTextBased<UserId> { | @@ -77,6 +77,11 @@ public class User extends SearchTextBased<UserId> { | ||
77 | this.email = email; | 77 | this.email = email; |
78 | } | 78 | } |
79 | 79 | ||
80 | + @Override | ||
81 | + public String getName() { | ||
82 | + return email; | ||
83 | + } | ||
84 | + | ||
80 | public Authority getAuthority() { | 85 | public Authority getAuthority() { |
81 | return authority; | 86 | return authority; |
82 | } | 87 | } |
@@ -18,13 +18,14 @@ package org.thingsboard.server.common.data.alarm; | @@ -18,13 +18,14 @@ package org.thingsboard.server.common.data.alarm; | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | import lombok.Data; | 19 | import lombok.Data; |
20 | import org.thingsboard.server.common.data.BaseData; | 20 | import org.thingsboard.server.common.data.BaseData; |
21 | +import org.thingsboard.server.common.data.HasName; | ||
21 | import org.thingsboard.server.common.data.id.EntityId; | 22 | import org.thingsboard.server.common.data.id.EntityId; |
22 | 23 | ||
23 | /** | 24 | /** |
24 | * Created by ashvayka on 11.05.17. | 25 | * Created by ashvayka on 11.05.17. |
25 | */ | 26 | */ |
26 | @Data | 27 | @Data |
27 | -public class Alarm extends BaseData<AlarmId> { | 28 | +public class Alarm extends BaseData<AlarmId> implements HasName { |
28 | 29 | ||
29 | private long startTs; | 30 | private long startTs; |
30 | private long endTs; | 31 | private long endTs; |
@@ -37,4 +38,8 @@ public class Alarm extends BaseData<AlarmId> { | @@ -37,4 +38,8 @@ public class Alarm extends BaseData<AlarmId> { | ||
37 | private JsonNode details; | 38 | private JsonNode details; |
38 | private boolean propagate; | 39 | private boolean propagate; |
39 | 40 | ||
41 | + @Override | ||
42 | + public String getName() { | ||
43 | + return type; | ||
44 | + } | ||
40 | } | 45 | } |
@@ -16,12 +16,13 @@ | @@ -16,12 +16,13 @@ | ||
16 | package org.thingsboard.server.common.data.asset; | 16 | package org.thingsboard.server.common.data.asset; |
17 | 17 | ||
18 | import com.fasterxml.jackson.databind.JsonNode; | 18 | import com.fasterxml.jackson.databind.JsonNode; |
19 | +import org.thingsboard.server.common.data.HasName; | ||
19 | import org.thingsboard.server.common.data.SearchTextBased; | 20 | import org.thingsboard.server.common.data.SearchTextBased; |
20 | import org.thingsboard.server.common.data.id.AssetId; | 21 | import org.thingsboard.server.common.data.id.AssetId; |
21 | import org.thingsboard.server.common.data.id.CustomerId; | 22 | import org.thingsboard.server.common.data.id.CustomerId; |
22 | import org.thingsboard.server.common.data.id.TenantId; | 23 | import org.thingsboard.server.common.data.id.TenantId; |
23 | 24 | ||
24 | -public class Asset extends SearchTextBased<AssetId> { | 25 | +public class Asset extends SearchTextBased<AssetId> implements HasName { |
25 | 26 | ||
26 | private static final long serialVersionUID = 2807343040519543363L; | 27 | private static final long serialVersionUID = 2807343040519543363L; |
27 | 28 | ||
@@ -64,6 +65,7 @@ public class Asset extends SearchTextBased<AssetId> { | @@ -64,6 +65,7 @@ public class Asset extends SearchTextBased<AssetId> { | ||
64 | this.customerId = customerId; | 65 | this.customerId = customerId; |
65 | } | 66 | } |
66 | 67 | ||
68 | + @Override | ||
67 | public String getName() { | 69 | public String getName() { |
68 | return name; | 70 | return name; |
69 | } | 71 | } |
@@ -15,13 +15,14 @@ | @@ -15,13 +15,14 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.common.data.plugin; | 16 | package org.thingsboard.server.common.data.plugin; |
17 | 17 | ||
18 | +import org.thingsboard.server.common.data.HasName; | ||
18 | import org.thingsboard.server.common.data.SearchTextBased; | 19 | import org.thingsboard.server.common.data.SearchTextBased; |
19 | import org.thingsboard.server.common.data.id.PluginId; | 20 | import org.thingsboard.server.common.data.id.PluginId; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
21 | 22 | ||
22 | import com.fasterxml.jackson.databind.JsonNode; | 23 | import com.fasterxml.jackson.databind.JsonNode; |
23 | 24 | ||
24 | -public class PluginMetaData extends SearchTextBased<PluginId> { | 25 | +public class PluginMetaData extends SearchTextBased<PluginId> implements HasName { |
25 | 26 | ||
26 | private static final long serialVersionUID = 1L; | 27 | private static final long serialVersionUID = 1L; |
27 | 28 | ||
@@ -75,6 +76,7 @@ public class PluginMetaData extends SearchTextBased<PluginId> { | @@ -75,6 +76,7 @@ public class PluginMetaData extends SearchTextBased<PluginId> { | ||
75 | this.tenantId = tenantId; | 76 | this.tenantId = tenantId; |
76 | } | 77 | } |
77 | 78 | ||
79 | + @Override | ||
78 | public String getName() { | 80 | public String getName() { |
79 | return name; | 81 | return name; |
80 | } | 82 | } |
@@ -47,11 +47,11 @@ public class EntityRelation { | @@ -47,11 +47,11 @@ public class EntityRelation { | ||
47 | this.additionalInfo = additionalInfo; | 47 | this.additionalInfo = additionalInfo; |
48 | } | 48 | } |
49 | 49 | ||
50 | - public EntityRelation(EntityRelation device) { | ||
51 | - this.from = device.getFrom(); | ||
52 | - this.to = device.getTo(); | ||
53 | - this.type = device.getType(); | ||
54 | - this.additionalInfo = device.getAdditionalInfo(); | 50 | + public EntityRelation(EntityRelation entityRelation) { |
51 | + this.from = entityRelation.getFrom(); | ||
52 | + this.to = entityRelation.getTo(); | ||
53 | + this.type = entityRelation.getType(); | ||
54 | + this.additionalInfo = entityRelation.getAdditionalInfo(); | ||
55 | } | 55 | } |
56 | 56 | ||
57 | public EntityId getFrom() { | 57 | public EntityId getFrom() { |
common/data/src/main/java/org/thingsboard/server/common/data/relation/EntityRelationInfo.java
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.thingsboard.server.common.data.relation; | ||
18 | + | ||
19 | +public class EntityRelationInfo extends EntityRelation { | ||
20 | + | ||
21 | + private static final long serialVersionUID = 2807343097519543363L; | ||
22 | + | ||
23 | + private String toName; | ||
24 | + | ||
25 | + public EntityRelationInfo() { | ||
26 | + super(); | ||
27 | + } | ||
28 | + | ||
29 | + public EntityRelationInfo(EntityRelation entityRelation) { | ||
30 | + super(entityRelation); | ||
31 | + } | ||
32 | + | ||
33 | + public String getToName() { | ||
34 | + return toName; | ||
35 | + } | ||
36 | + | ||
37 | + public void setToName(String toName) { | ||
38 | + this.toName = toName; | ||
39 | + } | ||
40 | + | ||
41 | + @Override | ||
42 | + public boolean equals(Object o) { | ||
43 | + if (this == o) return true; | ||
44 | + if (o == null || getClass() != o.getClass()) return false; | ||
45 | + if (!super.equals(o)) return false; | ||
46 | + | ||
47 | + EntityRelationInfo that = (EntityRelationInfo) o; | ||
48 | + | ||
49 | + return toName != null ? toName.equals(that.toName) : that.toName == null; | ||
50 | + | ||
51 | + } | ||
52 | + | ||
53 | + @Override | ||
54 | + public int hashCode() { | ||
55 | + int result = super.hashCode(); | ||
56 | + result = 31 * result + (toName != null ? toName.hashCode() : 0); | ||
57 | + return result; | ||
58 | + } | ||
59 | +} |
@@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.rule; | @@ -17,6 +17,7 @@ package org.thingsboard.server.common.data.rule; | ||
17 | 17 | ||
18 | import lombok.Data; | 18 | import lombok.Data; |
19 | import lombok.ToString; | 19 | import lombok.ToString; |
20 | +import org.thingsboard.server.common.data.HasName; | ||
20 | import org.thingsboard.server.common.data.SearchTextBased; | 21 | import org.thingsboard.server.common.data.SearchTextBased; |
21 | import org.thingsboard.server.common.data.id.CustomerId; | 22 | import org.thingsboard.server.common.data.id.CustomerId; |
22 | import org.thingsboard.server.common.data.id.RuleId; | 23 | import org.thingsboard.server.common.data.id.RuleId; |
@@ -26,7 +27,7 @@ import com.fasterxml.jackson.databind.JsonNode; | @@ -26,7 +27,7 @@ import com.fasterxml.jackson.databind.JsonNode; | ||
26 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; | 27 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; |
27 | 28 | ||
28 | @Data | 29 | @Data |
29 | -public class RuleMetaData extends SearchTextBased<RuleId> { | 30 | +public class RuleMetaData extends SearchTextBased<RuleId> implements HasName { |
30 | 31 | ||
31 | private static final long serialVersionUID = -5656679015122935465L; | 32 | private static final long serialVersionUID = -5656679015122935465L; |
32 | 33 | ||
@@ -66,4 +67,9 @@ public class RuleMetaData extends SearchTextBased<RuleId> { | @@ -66,4 +67,9 @@ public class RuleMetaData extends SearchTextBased<RuleId> { | ||
66 | return name; | 67 | return name; |
67 | } | 68 | } |
68 | 69 | ||
70 | + @Override | ||
71 | + public String getName() { | ||
72 | + return name; | ||
73 | + } | ||
74 | + | ||
69 | } | 75 | } |
@@ -28,6 +28,10 @@ import java.util.Optional; | @@ -28,6 +28,10 @@ import java.util.Optional; | ||
28 | */ | 28 | */ |
29 | public interface AlarmService { | 29 | public interface AlarmService { |
30 | 30 | ||
31 | + Alarm findAlarmById(AlarmId alarmId); | ||
32 | + | ||
33 | + ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId); | ||
34 | + | ||
31 | Optional<Alarm> saveIfNotExists(Alarm alarm); | 35 | Optional<Alarm> saveIfNotExists(Alarm alarm); |
32 | 36 | ||
33 | ListenableFuture<Boolean> updateAlarm(Alarm alarm); | 37 | ListenableFuture<Boolean> updateAlarm(Alarm alarm); |
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +package org.thingsboard.server.dao.alarm; | ||
17 | + | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.springframework.stereotype.Service; | ||
21 | +import org.thingsboard.server.common.data.alarm.Alarm; | ||
22 | +import org.thingsboard.server.common.data.alarm.AlarmId; | ||
23 | +import org.thingsboard.server.common.data.alarm.AlarmQuery; | ||
24 | +import org.thingsboard.server.common.data.page.TimePageData; | ||
25 | + | ||
26 | +import java.util.Optional; | ||
27 | + | ||
28 | +@Service | ||
29 | +@Slf4j | ||
30 | +public class BaseAlarmService implements AlarmService { | ||
31 | + | ||
32 | + @Override | ||
33 | + public Alarm findAlarmById(AlarmId alarmId) { | ||
34 | + return null; | ||
35 | + } | ||
36 | + | ||
37 | + @Override | ||
38 | + public ListenableFuture<Alarm> findAlarmByIdAsync(AlarmId alarmId) { | ||
39 | + return null; | ||
40 | + } | ||
41 | + | ||
42 | + @Override | ||
43 | + public Optional<Alarm> saveIfNotExists(Alarm alarm) { | ||
44 | + return null; | ||
45 | + } | ||
46 | + | ||
47 | + @Override | ||
48 | + public ListenableFuture<Boolean> updateAlarm(Alarm alarm) { | ||
49 | + return null; | ||
50 | + } | ||
51 | + | ||
52 | + @Override | ||
53 | + public ListenableFuture<Boolean> ackAlarm(Alarm alarm) { | ||
54 | + return null; | ||
55 | + } | ||
56 | + | ||
57 | + @Override | ||
58 | + public ListenableFuture<Boolean> clearAlarm(AlarmId alarmId) { | ||
59 | + return null; | ||
60 | + } | ||
61 | + | ||
62 | + @Override | ||
63 | + public ListenableFuture<TimePageData<Alarm>> findAlarms(AlarmQuery query) { | ||
64 | + return null; | ||
65 | + } | ||
66 | +} |
@@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.page.TextPageData; | @@ -35,7 +35,7 @@ import org.thingsboard.server.common.data.page.TextPageData; | ||
35 | import org.thingsboard.server.common.data.page.TextPageLink; | 35 | import org.thingsboard.server.common.data.page.TextPageLink; |
36 | import org.thingsboard.server.common.data.relation.EntityRelation; | 36 | import org.thingsboard.server.common.data.relation.EntityRelation; |
37 | import org.thingsboard.server.dao.customer.CustomerDao; | 37 | import org.thingsboard.server.dao.customer.CustomerDao; |
38 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 38 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
39 | import org.thingsboard.server.dao.exception.DataValidationException; | 39 | import org.thingsboard.server.dao.exception.DataValidationException; |
40 | import org.thingsboard.server.dao.model.*; | 40 | import org.thingsboard.server.dao.model.*; |
41 | import org.thingsboard.server.dao.relation.EntitySearchDirection; | 41 | import org.thingsboard.server.dao.relation.EntitySearchDirection; |
@@ -55,7 +55,7 @@ import static org.thingsboard.server.dao.service.Validator.*; | @@ -55,7 +55,7 @@ import static org.thingsboard.server.dao.service.Validator.*; | ||
55 | 55 | ||
56 | @Service | 56 | @Service |
57 | @Slf4j | 57 | @Slf4j |
58 | -public class BaseAssetService extends BaseEntityService implements AssetService { | 58 | +public class BaseAssetService extends AbstractEntityService implements AssetService { |
59 | 59 | ||
60 | @Autowired | 60 | @Autowired |
61 | private AssetDao assetDao; | 61 | private AssetDao assetDao; |
@@ -31,17 +31,15 @@ import com.google.common.util.concurrent.ListenableFuture; | @@ -31,17 +31,15 @@ import com.google.common.util.concurrent.ListenableFuture; | ||
31 | import lombok.extern.slf4j.Slf4j; | 31 | import lombok.extern.slf4j.Slf4j; |
32 | import org.apache.commons.lang3.StringUtils; | 32 | import org.apache.commons.lang3.StringUtils; |
33 | import org.thingsboard.server.common.data.Customer; | 33 | import org.thingsboard.server.common.data.Customer; |
34 | -import org.thingsboard.server.common.data.asset.Asset; | ||
35 | import org.thingsboard.server.common.data.id.CustomerId; | 34 | import org.thingsboard.server.common.data.id.CustomerId; |
36 | import org.thingsboard.server.common.data.id.TenantId; | 35 | import org.thingsboard.server.common.data.id.TenantId; |
37 | import org.thingsboard.server.common.data.page.TextPageData; | 36 | import org.thingsboard.server.common.data.page.TextPageData; |
38 | import org.thingsboard.server.common.data.page.TextPageLink; | 37 | import org.thingsboard.server.common.data.page.TextPageLink; |
39 | import org.thingsboard.server.dao.dashboard.DashboardService; | 38 | import org.thingsboard.server.dao.dashboard.DashboardService; |
40 | import org.thingsboard.server.dao.device.DeviceService; | 39 | import org.thingsboard.server.dao.device.DeviceService; |
41 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 40 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
42 | import org.thingsboard.server.dao.exception.DataValidationException; | 41 | import org.thingsboard.server.dao.exception.DataValidationException; |
43 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 42 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
44 | -import org.thingsboard.server.dao.model.AssetEntity; | ||
45 | import org.thingsboard.server.dao.model.CustomerEntity; | 43 | import org.thingsboard.server.dao.model.CustomerEntity; |
46 | import org.thingsboard.server.dao.model.TenantEntity; | 44 | import org.thingsboard.server.dao.model.TenantEntity; |
47 | import org.thingsboard.server.dao.service.DataValidator; | 45 | import org.thingsboard.server.dao.service.DataValidator; |
@@ -53,7 +51,7 @@ import org.springframework.stereotype.Service; | @@ -53,7 +51,7 @@ import org.springframework.stereotype.Service; | ||
53 | import org.thingsboard.server.dao.service.Validator; | 51 | import org.thingsboard.server.dao.service.Validator; |
54 | @Service | 52 | @Service |
55 | @Slf4j | 53 | @Slf4j |
56 | -public class CustomerServiceImpl extends BaseEntityService implements CustomerService { | 54 | +public class CustomerServiceImpl extends AbstractEntityService implements CustomerService { |
57 | 55 | ||
58 | private static final String PUBLIC_CUSTOMER_TITLE = "Public"; | 56 | private static final String PUBLIC_CUSTOMER_TITLE = "Public"; |
59 | 57 |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.dashboard; | 16 | package org.thingsboard.server.dao.dashboard; |
17 | 17 | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
18 | import org.thingsboard.server.common.data.Dashboard; | 19 | import org.thingsboard.server.common.data.Dashboard; |
19 | import org.thingsboard.server.common.data.DashboardInfo; | 20 | import org.thingsboard.server.common.data.DashboardInfo; |
20 | import org.thingsboard.server.common.data.id.CustomerId; | 21 | import org.thingsboard.server.common.data.id.CustomerId; |
@@ -27,8 +28,12 @@ public interface DashboardService { | @@ -27,8 +28,12 @@ public interface DashboardService { | ||
27 | 28 | ||
28 | public Dashboard findDashboardById(DashboardId dashboardId); | 29 | public Dashboard findDashboardById(DashboardId dashboardId); |
29 | 30 | ||
31 | + public ListenableFuture<Dashboard> findDashboardByIdAsync(DashboardId dashboardId); | ||
32 | + | ||
30 | public DashboardInfo findDashboardInfoById(DashboardId dashboardId); | 33 | public DashboardInfo findDashboardInfoById(DashboardId dashboardId); |
31 | 34 | ||
35 | + public ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(DashboardId dashboardId); | ||
36 | + | ||
32 | public Dashboard saveDashboard(Dashboard dashboard); | 37 | public Dashboard saveDashboard(Dashboard dashboard); |
33 | 38 | ||
34 | public Dashboard assignDashboardToCustomer(DashboardId dashboardId, CustomerId customerId); | 39 | public Dashboard assignDashboardToCustomer(DashboardId dashboardId, CustomerId customerId); |
@@ -17,9 +17,13 @@ package org.thingsboard.server.dao.dashboard; | @@ -17,9 +17,13 @@ package org.thingsboard.server.dao.dashboard; | ||
17 | 17 | ||
18 | import static org.thingsboard.server.dao.DaoUtil.convertDataList; | 18 | import static org.thingsboard.server.dao.DaoUtil.convertDataList; |
19 | import static org.thingsboard.server.dao.DaoUtil.getData; | 19 | import static org.thingsboard.server.dao.DaoUtil.getData; |
20 | +import static org.thingsboard.server.dao.service.Validator.validateId; | ||
20 | 21 | ||
21 | import java.util.List; | 22 | import java.util.List; |
22 | 23 | ||
24 | +import com.google.common.base.Function; | ||
25 | +import com.google.common.util.concurrent.Futures; | ||
26 | +import com.google.common.util.concurrent.ListenableFuture; | ||
23 | import lombok.extern.slf4j.Slf4j; | 27 | import lombok.extern.slf4j.Slf4j; |
24 | import org.apache.commons.lang3.StringUtils; | 28 | import org.apache.commons.lang3.StringUtils; |
25 | import org.thingsboard.server.common.data.Dashboard; | 29 | import org.thingsboard.server.common.data.Dashboard; |
@@ -30,7 +34,7 @@ import org.thingsboard.server.common.data.id.TenantId; | @@ -30,7 +34,7 @@ import org.thingsboard.server.common.data.id.TenantId; | ||
30 | import org.thingsboard.server.common.data.page.TextPageData; | 34 | import org.thingsboard.server.common.data.page.TextPageData; |
31 | import org.thingsboard.server.common.data.page.TextPageLink; | 35 | import org.thingsboard.server.common.data.page.TextPageLink; |
32 | import org.thingsboard.server.dao.customer.CustomerDao; | 36 | import org.thingsboard.server.dao.customer.CustomerDao; |
33 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 37 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
34 | import org.thingsboard.server.dao.exception.DataValidationException; | 38 | import org.thingsboard.server.dao.exception.DataValidationException; |
35 | import org.thingsboard.server.dao.model.*; | 39 | import org.thingsboard.server.dao.model.*; |
36 | import org.thingsboard.server.dao.service.DataValidator; | 40 | import org.thingsboard.server.dao.service.DataValidator; |
@@ -42,7 +46,7 @@ import org.thingsboard.server.dao.service.Validator; | @@ -42,7 +46,7 @@ import org.thingsboard.server.dao.service.Validator; | ||
42 | 46 | ||
43 | @Service | 47 | @Service |
44 | @Slf4j | 48 | @Slf4j |
45 | -public class DashboardServiceImpl extends BaseEntityService implements DashboardService { | 49 | +public class DashboardServiceImpl extends AbstractEntityService implements DashboardService { |
46 | 50 | ||
47 | @Autowired | 51 | @Autowired |
48 | private DashboardDao dashboardDao; | 52 | private DashboardDao dashboardDao; |
@@ -65,6 +69,14 @@ public class DashboardServiceImpl extends BaseEntityService implements Dashboard | @@ -65,6 +69,14 @@ public class DashboardServiceImpl extends BaseEntityService implements Dashboard | ||
65 | } | 69 | } |
66 | 70 | ||
67 | @Override | 71 | @Override |
72 | + public ListenableFuture<Dashboard> findDashboardByIdAsync(DashboardId dashboardId) { | ||
73 | + log.trace("Executing findDashboardByIdAsync [{}]", dashboardId); | ||
74 | + validateId(dashboardId, "Incorrect dashboardId " + dashboardId); | ||
75 | + ListenableFuture<DashboardEntity> dashboardEntity = dashboardDao.findByIdAsync(dashboardId.getId()); | ||
76 | + return Futures.transform(dashboardEntity, (Function<? super DashboardEntity, ? extends Dashboard>) input -> getData(input)); | ||
77 | + } | ||
78 | + | ||
79 | + @Override | ||
68 | public DashboardInfo findDashboardInfoById(DashboardId dashboardId) { | 80 | public DashboardInfo findDashboardInfoById(DashboardId dashboardId) { |
69 | log.trace("Executing findDashboardInfoById [{}]", dashboardId); | 81 | log.trace("Executing findDashboardInfoById [{}]", dashboardId); |
70 | Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); | 82 | Validator.validateId(dashboardId, "Incorrect dashboardId " + dashboardId); |
@@ -73,6 +85,14 @@ public class DashboardServiceImpl extends BaseEntityService implements Dashboard | @@ -73,6 +85,14 @@ public class DashboardServiceImpl extends BaseEntityService implements Dashboard | ||
73 | } | 85 | } |
74 | 86 | ||
75 | @Override | 87 | @Override |
88 | + public ListenableFuture<DashboardInfo> findDashboardInfoByIdAsync(DashboardId dashboardId) { | ||
89 | + log.trace("Executing findDashboardInfoByIdAsync [{}]", dashboardId); | ||
90 | + validateId(dashboardId, "Incorrect dashboardId " + dashboardId); | ||
91 | + ListenableFuture<DashboardInfoEntity> dashboardInfoEntity = dashboardInfoDao.findByIdAsync(dashboardId.getId()); | ||
92 | + return Futures.transform(dashboardInfoEntity, (Function<? super DashboardInfoEntity, ? extends DashboardInfo>) input -> getData(input)); | ||
93 | + } | ||
94 | + | ||
95 | + @Override | ||
76 | public Dashboard saveDashboard(Dashboard dashboard) { | 96 | public Dashboard saveDashboard(Dashboard dashboard) { |
77 | log.trace("Executing saveDashboard [{}]", dashboard); | 97 | log.trace("Executing saveDashboard [{}]", dashboard); |
78 | dashboardValidator.validate(dashboard); | 98 | dashboardValidator.validate(dashboard); |
@@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; | @@ -37,7 +37,7 @@ import org.thingsboard.server.common.data.relation.EntityRelation; | ||
37 | import org.thingsboard.server.common.data.security.DeviceCredentials; | 37 | import org.thingsboard.server.common.data.security.DeviceCredentials; |
38 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; | 38 | import org.thingsboard.server.common.data.security.DeviceCredentialsType; |
39 | import org.thingsboard.server.dao.customer.CustomerDao; | 39 | import org.thingsboard.server.dao.customer.CustomerDao; |
40 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 40 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
41 | import org.thingsboard.server.dao.exception.DataValidationException; | 41 | import org.thingsboard.server.dao.exception.DataValidationException; |
42 | import org.thingsboard.server.dao.model.CustomerEntity; | 42 | import org.thingsboard.server.dao.model.CustomerEntity; |
43 | import org.thingsboard.server.dao.model.DeviceEntity; | 43 | import org.thingsboard.server.dao.model.DeviceEntity; |
@@ -58,7 +58,7 @@ import static org.thingsboard.server.dao.service.Validator.*; | @@ -58,7 +58,7 @@ import static org.thingsboard.server.dao.service.Validator.*; | ||
58 | 58 | ||
59 | @Service | 59 | @Service |
60 | @Slf4j | 60 | @Slf4j |
61 | -public class DeviceServiceImpl extends BaseEntityService implements DeviceService { | 61 | +public class DeviceServiceImpl extends AbstractEntityService implements DeviceService { |
62 | 62 | ||
63 | @Autowired | 63 | @Autowired |
64 | private DeviceDao deviceDao; | 64 | private DeviceDao deviceDao; |
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.thingsboard.server.dao.entity; | ||
18 | + | ||
19 | +import lombok.extern.slf4j.Slf4j; | ||
20 | +import org.springframework.beans.factory.annotation.Autowired; | ||
21 | +import org.thingsboard.server.common.data.id.EntityId; | ||
22 | +import org.thingsboard.server.dao.relation.RelationService; | ||
23 | + | ||
24 | +@Slf4j | ||
25 | +public abstract class AbstractEntityService { | ||
26 | + | ||
27 | + @Autowired | ||
28 | + protected RelationService relationService; | ||
29 | + | ||
30 | + protected void deleteEntityRelations(EntityId entityId) { | ||
31 | + log.trace("Executing deleteEntityRelations [{}]", entityId); | ||
32 | + relationService.deleteEntityRelations(entityId); | ||
33 | + } | ||
34 | + | ||
35 | + | ||
36 | +} |
@@ -15,23 +15,102 @@ | @@ -15,23 +15,102 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.entity; | 16 | package org.thingsboard.server.dao.entity; |
17 | 17 | ||
18 | +import com.google.common.base.Function; | ||
19 | +import com.google.common.util.concurrent.Futures; | ||
20 | +import com.google.common.util.concurrent.ListenableFuture; | ||
18 | import lombok.extern.slf4j.Slf4j; | 21 | import lombok.extern.slf4j.Slf4j; |
19 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
20 | -import org.thingsboard.server.common.data.id.EntityId; | ||
21 | -import org.thingsboard.server.dao.relation.RelationService; | 23 | +import org.springframework.stereotype.Service; |
24 | +import org.thingsboard.server.common.data.*; | ||
25 | +import org.thingsboard.server.common.data.alarm.AlarmId; | ||
26 | +import org.thingsboard.server.common.data.id.*; | ||
27 | +import org.thingsboard.server.dao.alarm.AlarmService; | ||
28 | +import org.thingsboard.server.dao.asset.AssetService; | ||
29 | +import org.thingsboard.server.dao.customer.CustomerService; | ||
30 | +import org.thingsboard.server.dao.dashboard.DashboardService; | ||
31 | +import org.thingsboard.server.dao.device.DeviceService; | ||
32 | +import org.thingsboard.server.dao.plugin.PluginService; | ||
33 | +import org.thingsboard.server.dao.rule.RuleService; | ||
34 | +import org.thingsboard.server.dao.tenant.TenantService; | ||
35 | +import org.thingsboard.server.dao.user.UserService; | ||
22 | 36 | ||
23 | /** | 37 | /** |
24 | * Created by ashvayka on 04.05.17. | 38 | * Created by ashvayka on 04.05.17. |
25 | */ | 39 | */ |
40 | +@Service | ||
26 | @Slf4j | 41 | @Slf4j |
27 | -public class BaseEntityService { | 42 | +public class BaseEntityService extends AbstractEntityService implements EntityService { |
28 | 43 | ||
29 | @Autowired | 44 | @Autowired |
30 | - protected RelationService relationService; | 45 | + private AssetService assetService; |
31 | 46 | ||
32 | - protected void deleteEntityRelations(EntityId entityId) { | ||
33 | - log.trace("Executing deleteEntityRelations [{}]", entityId); | ||
34 | - relationService.deleteEntityRelations(entityId); | 47 | + @Autowired |
48 | + private DeviceService deviceService; | ||
49 | + | ||
50 | + @Autowired | ||
51 | + private RuleService ruleService; | ||
52 | + | ||
53 | + @Autowired | ||
54 | + private PluginService pluginService; | ||
55 | + | ||
56 | + @Autowired | ||
57 | + private TenantService tenantService; | ||
58 | + | ||
59 | + @Autowired | ||
60 | + private CustomerService customerService; | ||
61 | + | ||
62 | + @Autowired | ||
63 | + private UserService userService; | ||
64 | + | ||
65 | + @Autowired | ||
66 | + private DashboardService dashboardService; | ||
67 | + | ||
68 | + @Autowired | ||
69 | + private AlarmService alarmService; | ||
70 | + | ||
71 | + @Override | ||
72 | + public void deleteEntityRelations(EntityId entityId) { | ||
73 | + super.deleteEntityRelations(entityId); | ||
74 | + } | ||
75 | + | ||
76 | + @Override | ||
77 | + public ListenableFuture<String> fetchEntityNameAsync(EntityId entityId) { | ||
78 | + log.trace("Executing fetchEntityNameAsync [{}]", entityId); | ||
79 | + ListenableFuture<String> entityName; | ||
80 | + ListenableFuture<? extends HasName> hasName; | ||
81 | + switch (entityId.getEntityType()) { | ||
82 | + case ASSET: | ||
83 | + hasName = assetService.findAssetByIdAsync(new AssetId(entityId.getId())); | ||
84 | + break; | ||
85 | + case DEVICE: | ||
86 | + hasName = deviceService.findDeviceByIdAsync(new DeviceId(entityId.getId())); | ||
87 | + break; | ||
88 | + case RULE: | ||
89 | + hasName = ruleService.findRuleByIdAsync(new RuleId(entityId.getId())); | ||
90 | + break; | ||
91 | + case PLUGIN: | ||
92 | + hasName = pluginService.findPluginByIdAsync(new PluginId(entityId.getId())); | ||
93 | + break; | ||
94 | + case TENANT: | ||
95 | + hasName = tenantService.findTenantByIdAsync(new TenantId(entityId.getId())); | ||
96 | + break; | ||
97 | + case CUSTOMER: | ||
98 | + hasName = customerService.findCustomerByIdAsync(new CustomerId(entityId.getId())); | ||
99 | + break; | ||
100 | + case USER: | ||
101 | + hasName = userService.findUserByIdAsync(new UserId(entityId.getId())); | ||
102 | + break; | ||
103 | + case DASHBOARD: | ||
104 | + hasName = dashboardService.findDashboardInfoByIdAsync(new DashboardId(entityId.getId())); | ||
105 | + break; | ||
106 | + case ALARM: | ||
107 | + hasName = alarmService.findAlarmByIdAsync(new AlarmId(entityId.getId())); | ||
108 | + break; | ||
109 | + default: | ||
110 | + throw new IllegalStateException("Not Implemented!"); | ||
111 | + } | ||
112 | + entityName = Futures.transform(hasName, (Function<HasName, String>) hasName1 -> hasName1.getName() ); | ||
113 | + return entityName; | ||
35 | } | 114 | } |
36 | 115 | ||
37 | } | 116 | } |
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +package org.thingsboard.server.dao.entity; | ||
18 | + | ||
19 | +import com.google.common.util.concurrent.ListenableFuture; | ||
20 | +import org.thingsboard.server.common.data.id.EntityId; | ||
21 | + | ||
22 | +public interface EntityService { | ||
23 | + | ||
24 | + ListenableFuture<String> fetchEntityNameAsync(EntityId entityId); | ||
25 | + | ||
26 | + void deleteEntityRelations(EntityId entityId); | ||
27 | + | ||
28 | +} |
@@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringUtils; | @@ -22,7 +22,6 @@ import org.apache.commons.lang3.StringUtils; | ||
22 | import org.springframework.beans.factory.annotation.Autowired; | 22 | import org.springframework.beans.factory.annotation.Autowired; |
23 | import org.springframework.stereotype.Service; | 23 | import org.springframework.stereotype.Service; |
24 | import org.thingsboard.server.common.data.id.PluginId; | 24 | import org.thingsboard.server.common.data.id.PluginId; |
25 | -import org.thingsboard.server.common.data.id.RuleId; | ||
26 | import org.thingsboard.server.common.data.id.TenantId; | 25 | import org.thingsboard.server.common.data.id.TenantId; |
27 | import org.thingsboard.server.common.data.page.TextPageData; | 26 | import org.thingsboard.server.common.data.page.TextPageData; |
28 | import org.thingsboard.server.common.data.page.TextPageLink; | 27 | import org.thingsboard.server.common.data.page.TextPageLink; |
@@ -30,9 +29,8 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; | @@ -30,9 +29,8 @@ import org.thingsboard.server.common.data.plugin.ComponentDescriptor; | ||
30 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; | 29 | import org.thingsboard.server.common.data.plugin.ComponentLifecycleState; |
31 | import org.thingsboard.server.common.data.plugin.ComponentType; | 30 | import org.thingsboard.server.common.data.plugin.ComponentType; |
32 | import org.thingsboard.server.common.data.plugin.PluginMetaData; | 31 | import org.thingsboard.server.common.data.plugin.PluginMetaData; |
33 | -import org.thingsboard.server.common.data.rule.RuleMetaData; | ||
34 | import org.thingsboard.server.dao.component.ComponentDescriptorService; | 32 | import org.thingsboard.server.dao.component.ComponentDescriptorService; |
35 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 33 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
36 | import org.thingsboard.server.dao.exception.DataValidationException; | 34 | import org.thingsboard.server.dao.exception.DataValidationException; |
37 | import org.thingsboard.server.dao.exception.DatabaseException; | 35 | import org.thingsboard.server.dao.exception.DatabaseException; |
38 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 36 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
@@ -55,7 +53,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; | @@ -55,7 +53,7 @@ import static org.thingsboard.server.dao.service.Validator.validateId; | ||
55 | 53 | ||
56 | @Service | 54 | @Service |
57 | @Slf4j | 55 | @Slf4j |
58 | -public class BasePluginService extends BaseEntityService implements PluginService { | 56 | +public class BasePluginService extends AbstractEntityService implements PluginService { |
59 | 57 | ||
60 | //TODO: move to a better place. | 58 | //TODO: move to a better place. |
61 | public static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); | 59 | public static final TenantId SYSTEM_TENANT = new TenantId(ModelConstants.NULL_UUID); |
@@ -23,9 +23,24 @@ import lombok.extern.slf4j.Slf4j; | @@ -23,9 +23,24 @@ import lombok.extern.slf4j.Slf4j; | ||
23 | import org.springframework.beans.factory.annotation.Autowired; | 23 | import org.springframework.beans.factory.annotation.Autowired; |
24 | import org.springframework.stereotype.Service; | 24 | import org.springframework.stereotype.Service; |
25 | import org.springframework.util.StringUtils; | 25 | import org.springframework.util.StringUtils; |
26 | +import org.thingsboard.server.common.data.BaseData; | ||
27 | +import org.thingsboard.server.common.data.Device; | ||
28 | +import org.thingsboard.server.common.data.EntityType; | ||
29 | +import org.thingsboard.server.common.data.asset.Asset; | ||
30 | +import org.thingsboard.server.common.data.id.AssetId; | ||
31 | +import org.thingsboard.server.common.data.id.DeviceId; | ||
26 | import org.thingsboard.server.common.data.id.EntityId; | 32 | import org.thingsboard.server.common.data.id.EntityId; |
33 | +import org.thingsboard.server.common.data.id.UUIDBased; | ||
27 | import org.thingsboard.server.common.data.relation.EntityRelation; | 34 | import org.thingsboard.server.common.data.relation.EntityRelation; |
35 | +import org.thingsboard.server.common.data.relation.EntityRelationInfo; | ||
36 | +import org.thingsboard.server.dao.asset.AssetService; | ||
37 | +import org.thingsboard.server.dao.customer.CustomerService; | ||
38 | +import org.thingsboard.server.dao.device.DeviceService; | ||
39 | +import org.thingsboard.server.dao.entity.EntityService; | ||
28 | import org.thingsboard.server.dao.exception.DataValidationException; | 40 | import org.thingsboard.server.dao.exception.DataValidationException; |
41 | +import org.thingsboard.server.dao.plugin.PluginService; | ||
42 | +import org.thingsboard.server.dao.rule.RuleService; | ||
43 | +import org.thingsboard.server.dao.tenant.TenantService; | ||
29 | 44 | ||
30 | import javax.annotation.Nullable; | 45 | import javax.annotation.Nullable; |
31 | import java.util.*; | 46 | import java.util.*; |
@@ -41,6 +56,9 @@ public class BaseRelationService implements RelationService { | @@ -41,6 +56,9 @@ public class BaseRelationService implements RelationService { | ||
41 | @Autowired | 56 | @Autowired |
42 | private RelationDao relationDao; | 57 | private RelationDao relationDao; |
43 | 58 | ||
59 | + @Autowired | ||
60 | + private EntityService entityService; | ||
61 | + | ||
44 | @Override | 62 | @Override |
45 | public ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType) { | 63 | public ListenableFuture<Boolean> checkRelation(EntityId from, EntityId to, String relationType) { |
46 | log.trace("Executing checkRelation [{}][{}][{}]", from, to, relationType); | 64 | log.trace("Executing checkRelation [{}][{}][{}]", from, to, relationType); |
@@ -100,6 +118,31 @@ public class BaseRelationService implements RelationService { | @@ -100,6 +118,31 @@ public class BaseRelationService implements RelationService { | ||
100 | } | 118 | } |
101 | 119 | ||
102 | @Override | 120 | @Override |
121 | + public ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(EntityId from) { | ||
122 | + log.trace("Executing findInfoByFrom [{}]", from); | ||
123 | + validate(from); | ||
124 | + ListenableFuture<List<EntityRelation>> relations = relationDao.findAllByFrom(from); | ||
125 | + ListenableFuture<List<EntityRelationInfo>> relationsInfo = Futures.transform(relations, | ||
126 | + (AsyncFunction<List<EntityRelation>, List<EntityRelationInfo>>) relations1 -> { | ||
127 | + List<ListenableFuture<EntityRelationInfo>> futures = new ArrayList<>(); | ||
128 | + relations1.stream().forEach(relation -> futures.add(fetchRelationInfoAsync(relation))); | ||
129 | + return Futures.successfulAsList(futures); | ||
130 | + }); | ||
131 | + return relationsInfo; | ||
132 | + } | ||
133 | + | ||
134 | + private ListenableFuture<EntityRelationInfo> fetchRelationInfoAsync(EntityRelation relation) { | ||
135 | + ListenableFuture<String> entityName = entityService.fetchEntityNameAsync(relation.getTo()); | ||
136 | + ListenableFuture<EntityRelationInfo> entityRelationInfo = | ||
137 | + Futures.transform(entityName, (Function<String, EntityRelationInfo>) entityName1 -> { | ||
138 | + EntityRelationInfo entityRelationInfo1 = new EntityRelationInfo(relation); | ||
139 | + entityRelationInfo1.setToName(entityName1); | ||
140 | + return entityRelationInfo1; | ||
141 | + }); | ||
142 | + return entityRelationInfo; | ||
143 | + } | ||
144 | + | ||
145 | + @Override | ||
103 | public ListenableFuture<List<EntityRelation>> findByFromAndType(EntityId from, String relationType) { | 146 | public ListenableFuture<List<EntityRelation>> findByFromAndType(EntityId from, String relationType) { |
104 | log.trace("Executing findByFromAndType [{}][{}]", from, relationType); | 147 | log.trace("Executing findByFromAndType [{}][{}]", from, relationType); |
105 | validate(from); | 148 | validate(from); |
@@ -18,6 +18,7 @@ package org.thingsboard.server.dao.relation; | @@ -18,6 +18,7 @@ package org.thingsboard.server.dao.relation; | ||
18 | import com.google.common.util.concurrent.ListenableFuture; | 18 | import com.google.common.util.concurrent.ListenableFuture; |
19 | import org.thingsboard.server.common.data.id.EntityId; | 19 | import org.thingsboard.server.common.data.id.EntityId; |
20 | import org.thingsboard.server.common.data.relation.EntityRelation; | 20 | import org.thingsboard.server.common.data.relation.EntityRelation; |
21 | +import org.thingsboard.server.common.data.relation.EntityRelationInfo; | ||
21 | 22 | ||
22 | import java.util.List; | 23 | import java.util.List; |
23 | 24 | ||
@@ -38,6 +39,8 @@ public interface RelationService { | @@ -38,6 +39,8 @@ public interface RelationService { | ||
38 | 39 | ||
39 | ListenableFuture<List<EntityRelation>> findByFrom(EntityId from); | 40 | ListenableFuture<List<EntityRelation>> findByFrom(EntityId from); |
40 | 41 | ||
42 | + ListenableFuture<List<EntityRelationInfo>> findInfoByFrom(EntityId from); | ||
43 | + | ||
41 | ListenableFuture<List<EntityRelation>> findByFromAndType(EntityId from, String relationType); | 44 | ListenableFuture<List<EntityRelation>> findByFromAndType(EntityId from, String relationType); |
42 | 45 | ||
43 | ListenableFuture<List<EntityRelation>> findByTo(EntityId to); | 46 | ListenableFuture<List<EntityRelation>> findByTo(EntityId to); |
@@ -23,7 +23,6 @@ import lombok.extern.slf4j.Slf4j; | @@ -23,7 +23,6 @@ import lombok.extern.slf4j.Slf4j; | ||
23 | import org.apache.commons.lang3.StringUtils; | 23 | import org.apache.commons.lang3.StringUtils; |
24 | import org.springframework.beans.factory.annotation.Autowired; | 24 | import org.springframework.beans.factory.annotation.Autowired; |
25 | import org.springframework.stereotype.Service; | 25 | import org.springframework.stereotype.Service; |
26 | -import org.thingsboard.server.common.data.asset.Asset; | ||
27 | import org.thingsboard.server.common.data.id.RuleId; | 26 | import org.thingsboard.server.common.data.id.RuleId; |
28 | import org.thingsboard.server.common.data.id.TenantId; | 27 | import org.thingsboard.server.common.data.id.TenantId; |
29 | import org.thingsboard.server.common.data.page.TextPageData; | 28 | import org.thingsboard.server.common.data.page.TextPageData; |
@@ -34,11 +33,10 @@ import org.thingsboard.server.common.data.plugin.ComponentType; | @@ -34,11 +33,10 @@ import org.thingsboard.server.common.data.plugin.ComponentType; | ||
34 | import org.thingsboard.server.common.data.plugin.PluginMetaData; | 33 | import org.thingsboard.server.common.data.plugin.PluginMetaData; |
35 | import org.thingsboard.server.common.data.rule.RuleMetaData; | 34 | import org.thingsboard.server.common.data.rule.RuleMetaData; |
36 | import org.thingsboard.server.dao.component.ComponentDescriptorService; | 35 | import org.thingsboard.server.dao.component.ComponentDescriptorService; |
37 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 36 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
38 | import org.thingsboard.server.dao.exception.DataValidationException; | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
39 | import org.thingsboard.server.dao.exception.DatabaseException; | 38 | import org.thingsboard.server.dao.exception.DatabaseException; |
40 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 39 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
41 | -import org.thingsboard.server.dao.model.AssetEntity; | ||
42 | import org.thingsboard.server.dao.model.RuleMetaDataEntity; | 40 | import org.thingsboard.server.dao.model.RuleMetaDataEntity; |
43 | import org.thingsboard.server.dao.plugin.PluginService; | 41 | import org.thingsboard.server.dao.plugin.PluginService; |
44 | import org.thingsboard.server.dao.service.DataValidator; | 42 | import org.thingsboard.server.dao.service.DataValidator; |
@@ -58,7 +56,7 @@ import static org.thingsboard.server.dao.service.Validator.validatePageLink; | @@ -58,7 +56,7 @@ import static org.thingsboard.server.dao.service.Validator.validatePageLink; | ||
58 | 56 | ||
59 | @Service | 57 | @Service |
60 | @Slf4j | 58 | @Slf4j |
61 | -public class BaseRuleService extends BaseEntityService implements RuleService { | 59 | +public class BaseRuleService extends AbstractEntityService implements RuleService { |
62 | 60 | ||
63 | private final TenantId systemTenantId = new TenantId(NULL_UUID); | 61 | private final TenantId systemTenantId = new TenantId(NULL_UUID); |
64 | 62 |
@@ -26,7 +26,6 @@ import com.google.common.util.concurrent.Futures; | @@ -26,7 +26,6 @@ import com.google.common.util.concurrent.Futures; | ||
26 | import com.google.common.util.concurrent.ListenableFuture; | 26 | import com.google.common.util.concurrent.ListenableFuture; |
27 | import lombok.extern.slf4j.Slf4j; | 27 | import lombok.extern.slf4j.Slf4j; |
28 | import org.apache.commons.lang3.StringUtils; | 28 | import org.apache.commons.lang3.StringUtils; |
29 | -import org.thingsboard.server.common.data.Customer; | ||
30 | import org.thingsboard.server.common.data.Tenant; | 29 | import org.thingsboard.server.common.data.Tenant; |
31 | import org.thingsboard.server.common.data.id.TenantId; | 30 | import org.thingsboard.server.common.data.id.TenantId; |
32 | import org.thingsboard.server.common.data.page.TextPageData; | 31 | import org.thingsboard.server.common.data.page.TextPageData; |
@@ -34,9 +33,8 @@ import org.thingsboard.server.common.data.page.TextPageLink; | @@ -34,9 +33,8 @@ import org.thingsboard.server.common.data.page.TextPageLink; | ||
34 | import org.thingsboard.server.dao.customer.CustomerService; | 33 | import org.thingsboard.server.dao.customer.CustomerService; |
35 | import org.thingsboard.server.dao.dashboard.DashboardService; | 34 | import org.thingsboard.server.dao.dashboard.DashboardService; |
36 | import org.thingsboard.server.dao.device.DeviceService; | 35 | import org.thingsboard.server.dao.device.DeviceService; |
37 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 36 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
38 | import org.thingsboard.server.dao.exception.DataValidationException; | 37 | import org.thingsboard.server.dao.exception.DataValidationException; |
39 | -import org.thingsboard.server.dao.model.CustomerEntity; | ||
40 | import org.thingsboard.server.dao.model.TenantEntity; | 38 | import org.thingsboard.server.dao.model.TenantEntity; |
41 | import org.thingsboard.server.dao.plugin.PluginService; | 39 | import org.thingsboard.server.dao.plugin.PluginService; |
42 | import org.thingsboard.server.dao.rule.RuleService; | 40 | import org.thingsboard.server.dao.rule.RuleService; |
@@ -50,7 +48,7 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService; | @@ -50,7 +48,7 @@ import org.thingsboard.server.dao.widget.WidgetsBundleService; | ||
50 | 48 | ||
51 | @Service | 49 | @Service |
52 | @Slf4j | 50 | @Slf4j |
53 | -public class TenantServiceImpl extends BaseEntityService implements TenantService { | 51 | +public class TenantServiceImpl extends AbstractEntityService implements TenantService { |
54 | 52 | ||
55 | private static final String DEFAULT_TENANT_REGION = "Global"; | 53 | private static final String DEFAULT_TENANT_REGION = "Global"; |
56 | 54 |
@@ -15,6 +15,7 @@ | @@ -15,6 +15,7 @@ | ||
15 | */ | 15 | */ |
16 | package org.thingsboard.server.dao.user; | 16 | package org.thingsboard.server.dao.user; |
17 | 17 | ||
18 | +import com.google.common.util.concurrent.ListenableFuture; | ||
18 | import org.thingsboard.server.common.data.User; | 19 | import org.thingsboard.server.common.data.User; |
19 | import org.thingsboard.server.common.data.id.CustomerId; | 20 | import org.thingsboard.server.common.data.id.CustomerId; |
20 | import org.thingsboard.server.common.data.id.TenantId; | 21 | import org.thingsboard.server.common.data.id.TenantId; |
@@ -27,6 +28,8 @@ public interface UserService { | @@ -27,6 +28,8 @@ public interface UserService { | ||
27 | 28 | ||
28 | public User findUserById(UserId userId); | 29 | public User findUserById(UserId userId); |
29 | 30 | ||
31 | + public ListenableFuture<User> findUserByIdAsync(UserId userId); | ||
32 | + | ||
30 | public User findUserByEmail(String email); | 33 | public User findUserByEmail(String email); |
31 | 34 | ||
32 | public User saveUser(User user); | 35 | public User saveUser(User user); |
@@ -23,6 +23,9 @@ import static org.thingsboard.server.dao.service.Validator.validateString; | @@ -23,6 +23,9 @@ import static org.thingsboard.server.dao.service.Validator.validateString; | ||
23 | 23 | ||
24 | import java.util.List; | 24 | import java.util.List; |
25 | 25 | ||
26 | +import com.google.common.base.Function; | ||
27 | +import com.google.common.util.concurrent.Futures; | ||
28 | +import com.google.common.util.concurrent.ListenableFuture; | ||
26 | import lombok.extern.slf4j.Slf4j; | 29 | import lombok.extern.slf4j.Slf4j; |
27 | import org.apache.commons.lang3.RandomStringUtils; | 30 | import org.apache.commons.lang3.RandomStringUtils; |
28 | import org.apache.commons.lang3.StringUtils; | 31 | import org.apache.commons.lang3.StringUtils; |
@@ -35,7 +38,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | @@ -35,7 +38,7 @@ import org.thingsboard.server.common.data.page.TextPageLink; | ||
35 | import org.thingsboard.server.common.data.security.Authority; | 38 | import org.thingsboard.server.common.data.security.Authority; |
36 | import org.thingsboard.server.common.data.security.UserCredentials; | 39 | import org.thingsboard.server.common.data.security.UserCredentials; |
37 | import org.thingsboard.server.dao.customer.CustomerDao; | 40 | import org.thingsboard.server.dao.customer.CustomerDao; |
38 | -import org.thingsboard.server.dao.entity.BaseEntityService; | 41 | +import org.thingsboard.server.dao.entity.AbstractEntityService; |
39 | import org.thingsboard.server.dao.exception.DataValidationException; | 42 | import org.thingsboard.server.dao.exception.DataValidationException; |
40 | import org.thingsboard.server.dao.exception.IncorrectParameterException; | 43 | import org.thingsboard.server.dao.exception.IncorrectParameterException; |
41 | import org.thingsboard.server.dao.model.*; | 44 | import org.thingsboard.server.dao.model.*; |
@@ -47,7 +50,7 @@ import org.springframework.stereotype.Service; | @@ -47,7 +50,7 @@ import org.springframework.stereotype.Service; | ||
47 | 50 | ||
48 | @Service | 51 | @Service |
49 | @Slf4j | 52 | @Slf4j |
50 | -public class UserServiceImpl extends BaseEntityService implements UserService { | 53 | +public class UserServiceImpl extends AbstractEntityService implements UserService { |
51 | 54 | ||
52 | @Autowired | 55 | @Autowired |
53 | private UserDao userDao; | 56 | private UserDao userDao; |
@@ -78,6 +81,14 @@ public class UserServiceImpl extends BaseEntityService implements UserService { | @@ -78,6 +81,14 @@ public class UserServiceImpl extends BaseEntityService implements UserService { | ||
78 | } | 81 | } |
79 | 82 | ||
80 | @Override | 83 | @Override |
84 | + public ListenableFuture<User> findUserByIdAsync(UserId userId) { | ||
85 | + log.trace("Executing findUserByIdAsync [{}]", userId); | ||
86 | + validateId(userId, "Incorrect userId " + userId); | ||
87 | + ListenableFuture<UserEntity> userEntity = userDao.findByIdAsync(userId.getId()); | ||
88 | + return Futures.transform(userEntity, (Function<? super UserEntity, ? extends User>) input -> getData(input)); | ||
89 | + } | ||
90 | + | ||
91 | + @Override | ||
81 | public User saveUser(User user) { | 92 | public User saveUser(User user) { |
82 | log.trace("Executing saveUser [{}]", user); | 93 | log.trace("Executing saveUser [{}]", user); |
83 | userValidator.validate(user); | 94 | userValidator.validate(user); |
@@ -25,6 +25,7 @@ function EntityRelationService($http, $q) { | @@ -25,6 +25,7 @@ function EntityRelationService($http, $q) { | ||
25 | deleteRelation: deleteRelation, | 25 | deleteRelation: deleteRelation, |
26 | deleteRelations: deleteRelations, | 26 | deleteRelations: deleteRelations, |
27 | findByFrom: findByFrom, | 27 | findByFrom: findByFrom, |
28 | + findInfoByFrom: findInfoByFrom, | ||
28 | findByFromAndType: findByFromAndType, | 29 | findByFromAndType: findByFromAndType, |
29 | findByTo: findByTo, | 30 | findByTo: findByTo, |
30 | findByToAndType: findByToAndType, | 31 | findByToAndType: findByToAndType, |
@@ -84,6 +85,18 @@ function EntityRelationService($http, $q) { | @@ -84,6 +85,18 @@ function EntityRelationService($http, $q) { | ||
84 | return deferred.promise; | 85 | return deferred.promise; |
85 | } | 86 | } |
86 | 87 | ||
88 | + function findInfoByFrom(fromId, fromType) { | ||
89 | + var deferred = $q.defer(); | ||
90 | + var url = '/api/relations/info?fromId=' + fromId; | ||
91 | + url += '&fromType=' + fromType; | ||
92 | + $http.get(url, null).then(function success(response) { | ||
93 | + deferred.resolve(response.data); | ||
94 | + }, function fail() { | ||
95 | + deferred.reject(); | ||
96 | + }); | ||
97 | + return deferred.promise; | ||
98 | + } | ||
99 | + | ||
87 | function findByFromAndType(fromId, fromType, relationType) { | 100 | function findByFromAndType(fromId, fromType, relationType) { |
88 | var deferred = $q.defer(); | 101 | var deferred = $q.defer(); |
89 | var url = '/api/relations?fromId=' + fromId; | 102 | var url = '/api/relations?fromId=' + fromId; |
@@ -20,14 +20,13 @@ export default angular.module('thingsboard.api.entity', [thingsboardTypes]) | @@ -20,14 +20,13 @@ export default angular.module('thingsboard.api.entity', [thingsboardTypes]) | ||
20 | .name; | 20 | .name; |
21 | 21 | ||
22 | /*@ngInject*/ | 22 | /*@ngInject*/ |
23 | -function EntityService($http, $q, $filter, $translate, userService, deviceService, | 23 | +function EntityService($http, $q, $filter, $translate, $log, userService, deviceService, |
24 | assetService, tenantService, customerService, | 24 | assetService, tenantService, customerService, |
25 | - ruleService, pluginService, entityRelationService, attributeService, types, utils) { | 25 | + ruleService, pluginService, dashboardService, entityRelationService, attributeService, types, utils) { |
26 | var service = { | 26 | var service = { |
27 | getEntity: getEntity, | 27 | getEntity: getEntity, |
28 | getEntities: getEntities, | 28 | getEntities: getEntities, |
29 | getEntitiesByNameFilter: getEntitiesByNameFilter, | 29 | getEntitiesByNameFilter: getEntitiesByNameFilter, |
30 | - entityName: entityName, | ||
31 | processEntityAliases: processEntityAliases, | 30 | processEntityAliases: processEntityAliases, |
32 | getEntityKeys: getEntityKeys, | 31 | getEntityKeys: getEntityKeys, |
33 | checkEntityAlias: checkEntityAlias, | 32 | checkEntityAlias: checkEntityAlias, |
@@ -63,6 +62,15 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | @@ -63,6 +62,15 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | ||
63 | case types.entityType.plugin: | 62 | case types.entityType.plugin: |
64 | promise = pluginService.getPlugin(entityId); | 63 | promise = pluginService.getPlugin(entityId); |
65 | break; | 64 | break; |
65 | + case types.entityType.dashboard: | ||
66 | + promise = dashboardService.getDashboardInfo(entityId); | ||
67 | + break; | ||
68 | + case types.entityType.user: | ||
69 | + promise = userService.getUser(entityId); | ||
70 | + break; | ||
71 | + case types.entityType.alarm: | ||
72 | + $log.error('Get Alarm Entity is not implemented!'); | ||
73 | + break; | ||
66 | } | 74 | } |
67 | return promise; | 75 | return promise; |
68 | } | 76 | } |
@@ -134,6 +142,15 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | @@ -134,6 +142,15 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | ||
134 | case types.entityType.plugin: | 142 | case types.entityType.plugin: |
135 | promise = getEntitiesByIdsPromise(pluginService.getPlugin, entityIds); | 143 | promise = getEntitiesByIdsPromise(pluginService.getPlugin, entityIds); |
136 | break; | 144 | break; |
145 | + case types.entityType.dashboard: | ||
146 | + promise = getEntitiesByIdsPromise(dashboardService.getDashboardInfo, entityIds); | ||
147 | + break; | ||
148 | + case types.entityType.user: | ||
149 | + promise = getEntitiesByIdsPromise(userService.getUser, entityIds); | ||
150 | + break; | ||
151 | + case types.entityType.alarm: | ||
152 | + $log.error('Get Alarm Entity is not implemented!'); | ||
153 | + break; | ||
137 | } | 154 | } |
138 | return promise; | 155 | return promise; |
139 | } | 156 | } |
@@ -141,34 +158,38 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | @@ -141,34 +158,38 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | ||
141 | function getEntities(entityType, entityIds, config) { | 158 | function getEntities(entityType, entityIds, config) { |
142 | var deferred = $q.defer(); | 159 | var deferred = $q.defer(); |
143 | var promise = getEntitiesPromise(entityType, entityIds, config); | 160 | var promise = getEntitiesPromise(entityType, entityIds, config); |
144 | - promise.then( | ||
145 | - function success(result) { | ||
146 | - deferred.resolve(result); | ||
147 | - }, | ||
148 | - function fail() { | ||
149 | - deferred.reject(); | ||
150 | - } | ||
151 | - ); | 161 | + if (promise) { |
162 | + promise.then( | ||
163 | + function success(result) { | ||
164 | + deferred.resolve(result); | ||
165 | + }, | ||
166 | + function fail() { | ||
167 | + deferred.reject(); | ||
168 | + } | ||
169 | + ); | ||
170 | + } else { | ||
171 | + deferred.reject(); | ||
172 | + } | ||
152 | return deferred.promise; | 173 | return deferred.promise; |
153 | } | 174 | } |
154 | 175 | ||
155 | - function getEntitiesByPageLinkPromise(entityType, pageLink, config) { | 176 | + function getEntitiesByPageLinkPromise(entityType, pageLink, config, subType) { |
156 | var promise; | 177 | var promise; |
157 | var user = userService.getCurrentUser(); | 178 | var user = userService.getCurrentUser(); |
158 | var customerId = user.customerId; | 179 | var customerId = user.customerId; |
159 | switch (entityType) { | 180 | switch (entityType) { |
160 | case types.entityType.device: | 181 | case types.entityType.device: |
161 | if (user.authority === 'CUSTOMER_USER') { | 182 | if (user.authority === 'CUSTOMER_USER') { |
162 | - promise = deviceService.getCustomerDevices(customerId, pageLink, false, config); | 183 | + promise = deviceService.getCustomerDevices(customerId, pageLink, false, config, subType); |
163 | } else { | 184 | } else { |
164 | - promise = deviceService.getTenantDevices(pageLink, false, config); | 185 | + promise = deviceService.getTenantDevices(pageLink, false, config, subType); |
165 | } | 186 | } |
166 | break; | 187 | break; |
167 | case types.entityType.asset: | 188 | case types.entityType.asset: |
168 | if (user.authority === 'CUSTOMER_USER') { | 189 | if (user.authority === 'CUSTOMER_USER') { |
169 | - promise = assetService.getCustomerAssets(customerId, pageLink, false, config); | 190 | + promise = assetService.getCustomerAssets(customerId, pageLink, false, config, subType); |
170 | } else { | 191 | } else { |
171 | - promise = assetService.getTenantAssets(pageLink, false, config); | 192 | + promise = assetService.getTenantAssets(pageLink, false, config, subType); |
172 | } | 193 | } |
173 | break; | 194 | break; |
174 | case types.entityType.tenant: | 195 | case types.entityType.tenant: |
@@ -183,48 +204,48 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | @@ -183,48 +204,48 @@ function EntityService($http, $q, $filter, $translate, userService, deviceServic | ||
183 | case types.entityType.plugin: | 204 | case types.entityType.plugin: |
184 | promise = pluginService.getAllPlugins(pageLink); | 205 | promise = pluginService.getAllPlugins(pageLink); |
185 | break; | 206 | break; |
207 | + case types.entityType.dashboard: | ||
208 | + if (user.authority === 'CUSTOMER_USER') { | ||
209 | + promise = dashboardService.getCustomerDashboards(customerId, pageLink); | ||
210 | + } else { | ||
211 | + promise = dashboardService.getTenantDashboards(pageLink); | ||
212 | + } | ||
213 | + break; | ||
214 | + case types.entityType.user: | ||
215 | + $log.error('Get User Entities is not implemented!'); | ||
216 | + break; | ||
217 | + case types.entityType.alarm: | ||
218 | + $log.error('Get Alarm Entities is not implemented!'); | ||
219 | + break; | ||
186 | } | 220 | } |
187 | return promise; | 221 | return promise; |
188 | } | 222 | } |
189 | 223 | ||
190 | - function getEntitiesByNameFilter(entityType, entityNameFilter, limit, config) { | 224 | + function getEntitiesByNameFilter(entityType, entityNameFilter, limit, config, subType) { |
191 | var deferred = $q.defer(); | 225 | var deferred = $q.defer(); |
192 | var pageLink = {limit: limit, textSearch: entityNameFilter}; | 226 | var pageLink = {limit: limit, textSearch: entityNameFilter}; |
193 | - var promise = getEntitiesByPageLinkPromise(entityType, pageLink, config); | ||
194 | - promise.then( | ||
195 | - function success(result) { | ||
196 | - if (result.data && result.data.length > 0) { | ||
197 | - deferred.resolve(result.data); | ||
198 | - } else { | 227 | + var promise = getEntitiesByPageLinkPromise(entityType, pageLink, config, subType); |
228 | + if (promise) { | ||
229 | + promise.then( | ||
230 | + function success(result) { | ||
231 | + if (result.data && result.data.length > 0) { | ||
232 | + deferred.resolve(result.data); | ||
233 | + } else { | ||
234 | + deferred.resolve(null); | ||
235 | + } | ||
236 | + }, | ||
237 | + function fail() { | ||
199 | deferred.resolve(null); | 238 | deferred.resolve(null); |
200 | } | 239 | } |
201 | - }, | ||
202 | - function fail() { | ||
203 | - deferred.resolve(null); | ||
204 | - } | ||
205 | - ); | ||
206 | - return deferred.promise; | ||
207 | - } | ||
208 | - | ||
209 | - function entityName(entityType, entity) { | ||
210 | - var name = ''; | ||
211 | - switch (entityType) { | ||
212 | - case types.entityType.device: | ||
213 | - case types.entityType.asset: | ||
214 | - case types.entityType.rule: | ||
215 | - case types.entityType.plugin: | ||
216 | - name = entity.name; | ||
217 | - break; | ||
218 | - case types.entityType.tenant: | ||
219 | - case types.entityType.customer: | ||
220 | - name = entity.title; | ||
221 | - break; | 240 | + ); |
241 | + } else { | ||
242 | + deferred.resolve(null); | ||
222 | } | 243 | } |
223 | - return name; | 244 | + return deferred.promise; |
224 | } | 245 | } |
225 | 246 | ||
226 | function entityToEntityInfo(entityType, entity) { | 247 | function entityToEntityInfo(entityType, entity) { |
227 | - return { name: entityName(entityType, entity), entityType: entityType, id: entity.id.id }; | 248 | + return { name: entity.name, entityType: entityType, id: entity.id.id }; |
228 | } | 249 | } |
229 | 250 | ||
230 | function entitiesToEntitiesInfo(entityType, entities) { | 251 | function entitiesToEntitiesInfo(entityType, entities) { |
@@ -55,4 +55,10 @@ | @@ -55,4 +55,10 @@ | ||
55 | default-event-type="{{vm.types.eventType.alarm.value}}"> | 55 | default-event-type="{{vm.types.eventType.alarm.value}}"> |
56 | </tb-event-table> | 56 | </tb-event-table> |
57 | </md-tab> | 57 | </md-tab> |
58 | + <md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" label="{{ 'relation.relations' | translate }}"> | ||
59 | + <tb-relation-table flex | ||
60 | + entity-id="vm.grid.operatingItem().id.id" | ||
61 | + entity-type="{{vm.types.entityType.asset}}"> | ||
62 | + </tb-relation-table> | ||
63 | + </md-tab> | ||
58 | </tb-grid> | 64 | </tb-grid> |
@@ -98,7 +98,10 @@ export default angular.module('thingsboard.types', []) | @@ -98,7 +98,10 @@ export default angular.module('thingsboard.types', []) | ||
98 | rule: "RULE", | 98 | rule: "RULE", |
99 | plugin: "PLUGIN", | 99 | plugin: "PLUGIN", |
100 | tenant: "TENANT", | 100 | tenant: "TENANT", |
101 | - customer: "CUSTOMER" | 101 | + customer: "CUSTOMER", |
102 | + user: "USER", | ||
103 | + dashboard: "DASHBOARD", | ||
104 | + alarm: "ALARM" | ||
102 | }, | 105 | }, |
103 | entitySearchDirection: { | 106 | entitySearchDirection: { |
104 | from: "FROM", | 107 | from: "FROM", |
@@ -108,7 +108,8 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | @@ -108,7 +108,8 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | ||
108 | guid: guid, | 108 | guid: guid, |
109 | isLocalUrl: isLocalUrl, | 109 | isLocalUrl: isLocalUrl, |
110 | validateDatasources: validateDatasources, | 110 | validateDatasources: validateDatasources, |
111 | - createKey: createKey | 111 | + createKey: createKey, |
112 | + entityTypeName: entityTypeName | ||
112 | } | 113 | } |
113 | 114 | ||
114 | return service; | 115 | return service; |
@@ -346,4 +347,27 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | @@ -346,4 +347,27 @@ function Utils($mdColorPalette, $rootScope, $window, types) { | ||
346 | return dataKey; | 347 | return dataKey; |
347 | } | 348 | } |
348 | 349 | ||
350 | + function entityTypeName (type) { | ||
351 | + switch (type) { | ||
352 | + case types.entityType.device: | ||
353 | + return 'entity.type-device'; | ||
354 | + case types.entityType.asset: | ||
355 | + return 'entity.type-asset'; | ||
356 | + case types.entityType.rule: | ||
357 | + return 'entity.type-rule'; | ||
358 | + case types.entityType.plugin: | ||
359 | + return 'entity.type-plugin'; | ||
360 | + case types.entityType.tenant: | ||
361 | + return 'entity.type-tenant'; | ||
362 | + case types.entityType.customer: | ||
363 | + return 'entity.type-customer'; | ||
364 | + case types.entityType.user: | ||
365 | + return 'entity.type-user'; | ||
366 | + case types.entityType.dashboard: | ||
367 | + return 'entity.type-dashboard'; | ||
368 | + case types.entityType.alarm: | ||
369 | + return 'entity.type-alarm'; | ||
370 | + } | ||
371 | + } | ||
372 | + | ||
349 | } | 373 | } |
@@ -34,7 +34,7 @@ | @@ -34,7 +34,7 @@ | ||
34 | </md-item-template> | 34 | </md-item-template> |
35 | <md-not-found> | 35 | <md-not-found> |
36 | <div class="tb-not-found"> | 36 | <div class="tb-not-found"> |
37 | - <span translate translate-values='{ dashboard: dashboardSearchText }'>dashboard.no-dashboards-matching</span> | 37 | + <span translate translate-values='{ entity: dashboardSearchText }'>dashboard.no-dashboards-matching</span> |
38 | </div> | 38 | </div> |
39 | </md-not-found> | 39 | </md-not-found> |
40 | <div ng-messages="theForm.dashboard.$error"> | 40 | <div ng-messages="theForm.dashboard.$error"> |
@@ -34,7 +34,7 @@ | @@ -34,7 +34,7 @@ | ||
34 | </md-item-template> | 34 | </md-item-template> |
35 | <md-not-found> | 35 | <md-not-found> |
36 | <div class="tb-not-found"> | 36 | <div class="tb-not-found"> |
37 | - <span translate translate-values='{ plugin: pluginSearchText }'>plugin.no-plugins-matching</span> | 37 | + <span translate translate-values='{ entity: pluginSearchText }'>plugin.no-plugins-matching</span> |
38 | </div> | 38 | </div> |
39 | </md-not-found> | 39 | </md-not-found> |
40 | </md-autocomplete> | 40 | </md-autocomplete> |
@@ -109,7 +109,7 @@ export default function EntityStateController($scope, $location, $state, $stateP | @@ -109,7 +109,7 @@ export default function EntityStateController($scope, $location, $state, $stateP | ||
109 | if (params && params.entityId && params.entityId.id && params.entityId.entityType) { | 109 | if (params && params.entityId && params.entityId.id && params.entityId.entityType) { |
110 | entityService.getEntity(params.entityId.entityType, params.entityId.id, {ignoreLoading: true, ignoreErrors: true}).then( | 110 | entityService.getEntity(params.entityId.entityType, params.entityId.id, {ignoreLoading: true, ignoreErrors: true}).then( |
111 | function success(entity) { | 111 | function success(entity) { |
112 | - var entityName = entityService.entityName(params.entityId.entityType, entity); | 112 | + var entityName = entity.name; |
113 | deferred.resolve(entityName); | 113 | deferred.resolve(entityName); |
114 | }, | 114 | }, |
115 | function fail() { | 115 | function fail() { |
@@ -128,9 +128,9 @@ | @@ -128,9 +128,9 @@ | ||
128 | <table md-table md-row-select multiple="" ng-model="selectedAttributes" md-progress="attributesDeferred.promise"> | 128 | <table md-table md-row-select multiple="" ng-model="selectedAttributes" md-progress="attributesDeferred.promise"> |
129 | <thead md-head md-order="query.order" md-on-reorder="onReorder"> | 129 | <thead md-head md-order="query.order" md-on-reorder="onReorder"> |
130 | <tr md-row> | 130 | <tr md-row> |
131 | - <th md-column md-order-by="lastUpdateTs"><span>Last update time</span></th> | ||
132 | - <th md-column md-order-by="key"><span>Key</span></th> | ||
133 | - <th md-column>Value</th> | 131 | + <th md-column md-order-by="lastUpdateTs"><span translate>attribute.last-update-time</span></th> |
132 | + <th md-column md-order-by="key"><span translate>attribute.key</span></th> | ||
133 | + <th md-column><span translate>attribute.value</span></th> | ||
134 | </tr> | 134 | </tr> |
135 | </thead> | 135 | </thead> |
136 | <tbody md-body> | 136 | <tbody md-body> |
@@ -110,7 +110,7 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | @@ -110,7 +110,7 @@ export default function EntityAliasesController(utils, entityService, toast, $sc | ||
110 | entityAlias.changed = false; | 110 | entityAlias.changed = false; |
111 | } | 111 | } |
112 | if (!entityAlias.changed && entity && entityAlias.entityType) { | 112 | if (!entityAlias.changed && entity && entityAlias.entityType) { |
113 | - entityAlias.alias = entityService.entityName(entityAlias.entityType, entity); | 113 | + entityAlias.alias = entity.name; |
114 | } | 114 | } |
115 | } | 115 | } |
116 | } | 116 | } |
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import './entity-autocomplete.scss'; | ||
17 | + | ||
18 | +/* eslint-disable import/no-unresolved, import/default */ | ||
19 | + | ||
20 | +import entityAutocompleteTemplate from './entity-autocomplete.tpl.html'; | ||
21 | + | ||
22 | +/* eslint-enable import/no-unresolved, import/default */ | ||
23 | + | ||
24 | +/*@ngInject*/ | ||
25 | +export default function EntityAutocomplete($compile, $templateCache, $q, $filter, entityService, types) { | ||
26 | + | ||
27 | + var linker = function (scope, element, attrs, ngModelCtrl) { | ||
28 | + var template = $templateCache.get(entityAutocompleteTemplate); | ||
29 | + element.html(template); | ||
30 | + | ||
31 | + scope.tbRequired = angular.isDefined(scope.tbRequired) ? scope.tbRequired : false; | ||
32 | + scope.entity = null; | ||
33 | + scope.entitySearchText = ''; | ||
34 | + | ||
35 | + scope.fetchEntities = function(searchText) { | ||
36 | + var deferred = $q.defer(); | ||
37 | + entityService.getEntitiesByNameFilter(scope.entityType, searchText, 50, null, scope.entitySubtype).then(function success(result) { | ||
38 | + if (result) { | ||
39 | + deferred.resolve(result); | ||
40 | + } else { | ||
41 | + deferred.resolve([]); | ||
42 | + } | ||
43 | + }, function fail() { | ||
44 | + deferred.reject(); | ||
45 | + }); | ||
46 | + return deferred.promise; | ||
47 | + } | ||
48 | + | ||
49 | + scope.entitySearchTextChanged = function() { | ||
50 | + } | ||
51 | + | ||
52 | + scope.updateView = function () { | ||
53 | + if (!scope.disabled) { | ||
54 | + ngModelCtrl.$setViewValue(scope.entity ? scope.entity.id.id : null); | ||
55 | + } | ||
56 | + } | ||
57 | + | ||
58 | + ngModelCtrl.$render = function () { | ||
59 | + if (ngModelCtrl.$viewValue) { | ||
60 | + entityService.getEntity(scope.entityType, ngModelCtrl.$viewValue).then( | ||
61 | + function success(entity) { | ||
62 | + scope.entity = entity; | ||
63 | + }, | ||
64 | + function fail() { | ||
65 | + scope.entity = null; | ||
66 | + } | ||
67 | + ); | ||
68 | + } else { | ||
69 | + scope.entity = null; | ||
70 | + } | ||
71 | + } | ||
72 | + | ||
73 | + scope.$watch('entityType', function () { | ||
74 | + load(); | ||
75 | + }); | ||
76 | + | ||
77 | + scope.$watch('entitySubtype', function () { | ||
78 | + if (scope.entity && scope.entity.type != scope.entitySubtype) { | ||
79 | + scope.entity = null; | ||
80 | + scope.updateView(); | ||
81 | + } | ||
82 | + }); | ||
83 | + | ||
84 | + scope.$watch('entity', function () { | ||
85 | + scope.updateView(); | ||
86 | + }); | ||
87 | + | ||
88 | + scope.$watch('disabled', function () { | ||
89 | + scope.updateView(); | ||
90 | + }); | ||
91 | + | ||
92 | + | ||
93 | + function load() { | ||
94 | + switch (scope.entityType) { | ||
95 | + case types.entityType.asset: | ||
96 | + scope.selectEntityText = 'asset.select-asset'; | ||
97 | + scope.entityText = 'asset.asset'; | ||
98 | + scope.noEntitiesMatchingText = 'asset.no-assets-matching'; | ||
99 | + scope.entityRequiredText = 'asset.asset-required' | ||
100 | + break; | ||
101 | + case types.entityType.device: | ||
102 | + scope.selectEntityText = 'device.select-device'; | ||
103 | + scope.entityText = 'device.device'; | ||
104 | + scope.noEntitiesMatchingText = 'device.no-devices-matching'; | ||
105 | + scope.entityRequiredText = 'device.device-required' | ||
106 | + break; | ||
107 | + case types.entityType.rule: | ||
108 | + scope.selectEntityText = 'rule.select-rule'; | ||
109 | + scope.entityText = 'rule.rule'; | ||
110 | + scope.noEntitiesMatchingText = 'rule.no-rules-matching'; | ||
111 | + scope.entityRequiredText = 'rule.rule-required' | ||
112 | + break; | ||
113 | + case types.entityType.plugin: | ||
114 | + scope.selectEntityText = 'plugin.select-plugin'; | ||
115 | + scope.entityText = 'plugin.plugin'; | ||
116 | + scope.noEntitiesMatchingText = 'plugin.no-plugins-matching'; | ||
117 | + scope.entityRequiredText = 'plugin.plugin-required' | ||
118 | + break; | ||
119 | + case types.entityType.tenant: | ||
120 | + scope.selectEntityText = 'tenant.select-tenant'; | ||
121 | + scope.entityText = 'tenant.tenant'; | ||
122 | + scope.noEntitiesMatchingText = 'tenant.no-tenants-matching'; | ||
123 | + scope.entityRequiredText = 'tenant.tenant-required' | ||
124 | + break; | ||
125 | + case types.entityType.customer: | ||
126 | + scope.selectEntityText = 'customer.select-customer'; | ||
127 | + scope.entityText = 'customer.customer'; | ||
128 | + scope.noEntitiesMatchingText = 'customer.no-customers-matching'; | ||
129 | + scope.entityRequiredText = 'customer.customer-required' | ||
130 | + break; | ||
131 | + case types.entityType.user: | ||
132 | + scope.selectEntityText = 'user.select-user'; | ||
133 | + scope.entityText = 'user.user'; | ||
134 | + scope.noEntitiesMatchingText = 'user.no-users-matching'; | ||
135 | + scope.entityRequiredText = 'user.user-required' | ||
136 | + break; | ||
137 | + case types.entityType.dashboard: | ||
138 | + scope.selectEntityText = 'dashboard.select-dashboard'; | ||
139 | + scope.entityText = 'dashboard.dashboard'; | ||
140 | + scope.noEntitiesMatchingText = 'dashboard.no-dashboards-matching'; | ||
141 | + scope.entityRequiredText = 'dashboard.dashboard-required' | ||
142 | + break; | ||
143 | + case types.entityType.alarm: | ||
144 | + scope.selectEntityText = 'alarm.select-alarm'; | ||
145 | + scope.entityText = 'alarm.alarm'; | ||
146 | + scope.noEntitiesMatchingText = 'alarm.no-alarms-matching'; | ||
147 | + scope.entityRequiredText = 'alarm.alarm-required' | ||
148 | + break; | ||
149 | + } | ||
150 | + if (scope.entity && scope.entity.id.entityType != scope.entityType) { | ||
151 | + scope.entity = null; | ||
152 | + scope.updateView(); | ||
153 | + } | ||
154 | + } | ||
155 | + | ||
156 | + $compile(element.contents())(scope); | ||
157 | + } | ||
158 | + | ||
159 | + return { | ||
160 | + restrict: "E", | ||
161 | + require: "^ngModel", | ||
162 | + link: linker, | ||
163 | + scope: { | ||
164 | + theForm: '=?', | ||
165 | + tbRequired: '=?', | ||
166 | + disabled:'=ngDisabled', | ||
167 | + entityType: '=', | ||
168 | + entitySubtype: '=?' | ||
169 | + } | ||
170 | + }; | ||
171 | +} |
ui/src/app/entity/entity-autocomplete.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +.tb-entity-autocomplete { | ||
17 | + .tb-entity-item { | ||
18 | + display: block; | ||
19 | + height: 48px; | ||
20 | + } | ||
21 | + li { | ||
22 | + height: auto !important; | ||
23 | + white-space: normal !important; | ||
24 | + } | ||
25 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 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-autocomplete ng-required="tbRequired" | ||
19 | + ng-disabled="disabled" | ||
20 | + md-no-cache="true" | ||
21 | + md-input-name="entity" | ||
22 | + ng-model="entity" | ||
23 | + md-selected-item="entity" | ||
24 | + md-search-text="entitySearchText" | ||
25 | + md-search-text-change="entitySearchTextChanged()" | ||
26 | + md-items="item in fetchEntities(entitySearchText)" | ||
27 | + md-item-text="item.name" | ||
28 | + md-min-length="0" | ||
29 | + md-floating-label="{{ entityText | translate }}" | ||
30 | + md-select-on-match="true" | ||
31 | + md-menu-class="tb-entity-autocomplete"> | ||
32 | + <md-item-template> | ||
33 | + <div class="tb-entity-item"> | ||
34 | + <span md-highlight-text="entitySearchText" md-highlight-flags="^i">{{item.name}}</span> | ||
35 | + </div> | ||
36 | + </md-item-template> | ||
37 | + <md-not-found> | ||
38 | + <div class="tb-not-found"> | ||
39 | + <span translate translate-values='{ entity: entitySearchText }'>{{ noEntitiesMatchingText }}</span> | ||
40 | + </div> | ||
41 | + </md-not-found> | ||
42 | + <div ng-messages="theForm.entity.$error"> | ||
43 | + <div translate ng-message="required">{{ entityRequiredText }}</div> | ||
44 | + </div> | ||
45 | +</md-autocomplete> |
@@ -32,14 +32,6 @@ export default function EntityFilterDirective($compile, $templateCache, $q, enti | @@ -32,14 +32,6 @@ export default function EntityFilterDirective($compile, $templateCache, $q, enti | ||
32 | 32 | ||
33 | scope.ngModelCtrl = ngModelCtrl; | 33 | scope.ngModelCtrl = ngModelCtrl; |
34 | 34 | ||
35 | - scope.itemName = function(item) { | ||
36 | - if (item) { | ||
37 | - return entityService.entityName(scope.entityType, item); | ||
38 | - } else { | ||
39 | - return ''; | ||
40 | - } | ||
41 | - } | ||
42 | - | ||
43 | scope.fetchEntities = function(searchText, limit) { | 35 | scope.fetchEntities = function(searchText, limit) { |
44 | var deferred = $q.defer(); | 36 | var deferred = $q.defer(); |
45 | entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit).then(function success(result) { | 37 | entityService.getEntitiesByNameFilter(scope.entityType, searchText, limit).then(function success(result) { |
@@ -33,7 +33,7 @@ | @@ -33,7 +33,7 @@ | ||
33 | md-min-length="0" | 33 | md-min-length="0" |
34 | placeholder="{{ 'entity.entity-list' | translate }}"> | 34 | placeholder="{{ 'entity.entity-list' | translate }}"> |
35 | <md-item-template> | 35 | <md-item-template> |
36 | - <span md-highlight-text="entitySearchText" md-highlight-flags="^i">{{itemName(item)}}</span> | 36 | + <span md-highlight-text="entitySearchText" md-highlight-flags="^i">{{item.name}}</span> |
37 | </md-item-template> | 37 | </md-item-template> |
38 | <md-not-found> | 38 | <md-not-found> |
39 | <span translate translate-values='{ entity: entitySearchText }'>entity.no-entities-matching</span> | 39 | <span translate translate-values='{ entity: entitySearchText }'>entity.no-entities-matching</span> |
ui/src/app/entity/entity-select.directive.js
0 → 100644
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import './entity-select.scss'; | ||
17 | + | ||
18 | +/* eslint-disable import/no-unresolved, import/default */ | ||
19 | + | ||
20 | +import entitySelectTemplate from './entity-select.tpl.html'; | ||
21 | + | ||
22 | +/* eslint-enable import/no-unresolved, import/default */ | ||
23 | + | ||
24 | +/*@ngInject*/ | ||
25 | +export default function EntitySelect($compile, $templateCache) { | ||
26 | + | ||
27 | + var linker = function (scope, element, attrs, ngModelCtrl) { | ||
28 | + var template = $templateCache.get(entitySelectTemplate); | ||
29 | + element.html(template); | ||
30 | + | ||
31 | + scope.tbRequired = angular.isDefined(scope.tbRequired) ? scope.tbRequired : false; | ||
32 | + scope.model = null; | ||
33 | + | ||
34 | + scope.updateView = function () { | ||
35 | + if (!scope.disabled) { | ||
36 | + var value = ngModelCtrl.$viewValue; | ||
37 | + if (scope.model && scope.model.entityType && scope.model.entityId) { | ||
38 | + if (!value) { | ||
39 | + value = {}; | ||
40 | + } | ||
41 | + value.entityType = scope.model.entityType; | ||
42 | + value.id = scope.model.entityId; | ||
43 | + ngModelCtrl.$setViewValue(value); | ||
44 | + } else { | ||
45 | + ngModelCtrl.$setViewValue(null); | ||
46 | + } | ||
47 | + } | ||
48 | + } | ||
49 | + | ||
50 | + ngModelCtrl.$render = function () { | ||
51 | + if (ngModelCtrl.$viewValue) { | ||
52 | + var value = ngModelCtrl.$viewValue; | ||
53 | + scope.model = {}; | ||
54 | + scope.model.entityType = value.entityType; | ||
55 | + scope.model.entityId = value.id; | ||
56 | + } else { | ||
57 | + scope.model = null; | ||
58 | + } | ||
59 | + } | ||
60 | + | ||
61 | + scope.$watch('model.entityType', function () { | ||
62 | + scope.updateView(); | ||
63 | + }); | ||
64 | + | ||
65 | + scope.$watch('model.entityId', function () { | ||
66 | + scope.updateView(); | ||
67 | + }); | ||
68 | + | ||
69 | + scope.$watch('disabled', function () { | ||
70 | + scope.updateView(); | ||
71 | + }); | ||
72 | + | ||
73 | + $compile(element.contents())(scope); | ||
74 | + } | ||
75 | + | ||
76 | + return { | ||
77 | + restrict: "E", | ||
78 | + require: "^ngModel", | ||
79 | + link: linker, | ||
80 | + scope: { | ||
81 | + theForm: '=?', | ||
82 | + tbRequired: '=?', | ||
83 | + disabled:'=ngDisabled' | ||
84 | + } | ||
85 | + }; | ||
86 | +} |
ui/src/app/entity/entity-select.scss
0 → 100644
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | + | ||
17 | +.tb-entity-select { | ||
18 | + | ||
19 | +} |
ui/src/app/entity/entity-select.tpl.html
0 → 100644
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 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 layout='row' class="tb-entity-select"> | ||
19 | + <tb-entity-type-select style="min-width: 100px;" | ||
20 | + ng-model="model.entityType"> | ||
21 | + </tb-entity-type-select> | ||
22 | + <tb-entity-autocomplete flex | ||
23 | + the-form="theForm" | ||
24 | + ng-disabled="disabled" | ||
25 | + tb-required="tbRequired" | ||
26 | + entity-type="model.entityType" | ||
27 | + ng-model="model.entityId"> | ||
28 | + </tb-entity-autocomplete> | ||
29 | +</div> |
@@ -23,7 +23,7 @@ import entityTypeSelectTemplate from './entity-type-select.tpl.html'; | @@ -23,7 +23,7 @@ import entityTypeSelectTemplate from './entity-type-select.tpl.html'; | ||
23 | /* eslint-enable import/no-unresolved, import/default */ | 23 | /* eslint-enable import/no-unresolved, import/default */ |
24 | 24 | ||
25 | /*@ngInject*/ | 25 | /*@ngInject*/ |
26 | -export default function EntityTypeSelect($compile, $templateCache, userService, types) { | 26 | +export default function EntityTypeSelect($compile, $templateCache, utils, userService, types) { |
27 | 27 | ||
28 | var linker = function (scope, element, attrs, ngModelCtrl) { | 28 | var linker = function (scope, element, attrs, ngModelCtrl) { |
29 | var template = $templateCache.get(entityTypeSelectTemplate); | 29 | var template = $templateCache.get(entityTypeSelectTemplate); |
@@ -51,10 +51,12 @@ export default function EntityTypeSelect($compile, $templateCache, userService, | @@ -51,10 +51,12 @@ export default function EntityTypeSelect($compile, $templateCache, userService, | ||
51 | scope.entityTypes.customer = types.entityType.customer; | 51 | scope.entityTypes.customer = types.entityType.customer; |
52 | scope.entityTypes.rule = types.entityType.rule; | 52 | scope.entityTypes.rule = types.entityType.rule; |
53 | scope.entityTypes.plugin = types.entityType.plugin; | 53 | scope.entityTypes.plugin = types.entityType.plugin; |
54 | + scope.entityTypes.dashboard = types.entityType.dashboard; | ||
54 | break; | 55 | break; |
55 | case 'CUSTOMER_USER': | 56 | case 'CUSTOMER_USER': |
56 | scope.entityTypes.device = types.entityType.device; | 57 | scope.entityTypes.device = types.entityType.device; |
57 | scope.entityTypes.asset = types.entityType.asset; | 58 | scope.entityTypes.asset = types.entityType.asset; |
59 | + scope.entityTypes.dashboard = types.entityType.dashboard; | ||
58 | break; | 60 | break; |
59 | } | 61 | } |
60 | 62 | ||
@@ -67,20 +69,7 @@ export default function EntityTypeSelect($compile, $templateCache, userService, | @@ -67,20 +69,7 @@ export default function EntityTypeSelect($compile, $templateCache, userService, | ||
67 | } | 69 | } |
68 | 70 | ||
69 | scope.typeName = function(type) { | 71 | scope.typeName = function(type) { |
70 | - switch (type) { | ||
71 | - case types.entityType.device: | ||
72 | - return 'entity.type-device'; | ||
73 | - case types.entityType.asset: | ||
74 | - return 'entity.type-asset'; | ||
75 | - case types.entityType.rule: | ||
76 | - return 'entity.type-rule'; | ||
77 | - case types.entityType.plugin: | ||
78 | - return 'entity.type-plugin'; | ||
79 | - case types.entityType.tenant: | ||
80 | - return 'entity.type-tenant'; | ||
81 | - case types.entityType.customer: | ||
82 | - return 'entity.type-customer'; | ||
83 | - } | 72 | + return utils.entityTypeName(type); |
84 | } | 73 | } |
85 | 74 | ||
86 | scope.updateValidity = function () { | 75 | scope.updateValidity = function () { |
@@ -18,12 +18,15 @@ import EntityAliasesController from './entity-aliases.controller'; | @@ -18,12 +18,15 @@ import EntityAliasesController from './entity-aliases.controller'; | ||
18 | import EntityTypeSelectDirective from './entity-type-select.directive'; | 18 | import EntityTypeSelectDirective from './entity-type-select.directive'; |
19 | import EntitySubtypeSelectDirective from './entity-subtype-select.directive'; | 19 | import EntitySubtypeSelectDirective from './entity-subtype-select.directive'; |
20 | import EntitySubtypeAutocompleteDirective from './entity-subtype-autocomplete.directive'; | 20 | import EntitySubtypeAutocompleteDirective from './entity-subtype-autocomplete.directive'; |
21 | +import EntityAutocompleteDirective from './entity-autocomplete.directive'; | ||
22 | +import EntitySelectDirective from './entity-select.directive'; | ||
21 | import EntityFilterDirective from './entity-filter.directive'; | 23 | import EntityFilterDirective from './entity-filter.directive'; |
22 | import AliasesEntitySelectPanelController from './aliases-entity-select-panel.controller'; | 24 | import AliasesEntitySelectPanelController from './aliases-entity-select-panel.controller'; |
23 | import AliasesEntitySelectDirective from './aliases-entity-select.directive'; | 25 | import AliasesEntitySelectDirective from './aliases-entity-select.directive'; |
24 | import AddAttributeDialogController from './attribute/add-attribute-dialog.controller'; | 26 | import AddAttributeDialogController from './attribute/add-attribute-dialog.controller'; |
25 | import AddWidgetToDashboardDialogController from './attribute/add-widget-to-dashboard-dialog.controller'; | 27 | import AddWidgetToDashboardDialogController from './attribute/add-widget-to-dashboard-dialog.controller'; |
26 | import AttributeTableDirective from './attribute/attribute-table.directive'; | 28 | import AttributeTableDirective from './attribute/attribute-table.directive'; |
29 | +import RelationTableDirective from './relation/relation-table.directive'; | ||
27 | 30 | ||
28 | export default angular.module('thingsboard.entity', []) | 31 | export default angular.module('thingsboard.entity', []) |
29 | .controller('EntityAliasesController', EntityAliasesController) | 32 | .controller('EntityAliasesController', EntityAliasesController) |
@@ -33,7 +36,10 @@ export default angular.module('thingsboard.entity', []) | @@ -33,7 +36,10 @@ export default angular.module('thingsboard.entity', []) | ||
33 | .directive('tbEntityTypeSelect', EntityTypeSelectDirective) | 36 | .directive('tbEntityTypeSelect', EntityTypeSelectDirective) |
34 | .directive('tbEntitySubtypeSelect', EntitySubtypeSelectDirective) | 37 | .directive('tbEntitySubtypeSelect', EntitySubtypeSelectDirective) |
35 | .directive('tbEntitySubtypeAutocomplete', EntitySubtypeAutocompleteDirective) | 38 | .directive('tbEntitySubtypeAutocomplete', EntitySubtypeAutocompleteDirective) |
39 | + .directive('tbEntityAutocomplete', EntityAutocompleteDirective) | ||
40 | + .directive('tbEntitySelect', EntitySelectDirective) | ||
36 | .directive('tbEntityFilter', EntityFilterDirective) | 41 | .directive('tbEntityFilter', EntityFilterDirective) |
37 | .directive('tbAliasesEntitySelect', AliasesEntitySelectDirective) | 42 | .directive('tbAliasesEntitySelect', AliasesEntitySelectDirective) |
38 | .directive('tbAttributeTable', AttributeTableDirective) | 43 | .directive('tbAttributeTable', AttributeTableDirective) |
44 | + .directive('tbRelationTable', RelationTableDirective) | ||
39 | .name; | 45 | .name; |
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +/*@ngInject*/ | ||
17 | +export default function AddRelationDialogController($scope, $mdDialog, types, entityRelationService, from) { | ||
18 | + | ||
19 | + var vm = this; | ||
20 | + | ||
21 | + vm.types = types; | ||
22 | + | ||
23 | + vm.relation = {}; | ||
24 | + vm.relation.from = from; | ||
25 | + vm.relation.type = types.entityRelationType.contains; | ||
26 | + | ||
27 | + vm.add = add; | ||
28 | + vm.cancel = cancel; | ||
29 | + | ||
30 | + function cancel() { | ||
31 | + $mdDialog.cancel(); | ||
32 | + } | ||
33 | + | ||
34 | + function add() { | ||
35 | + $scope.theForm.$setPristine(); | ||
36 | + entityRelationService.saveRelation(vm.relation).then( | ||
37 | + function success() { | ||
38 | + $mdDialog.hide(); | ||
39 | + } | ||
40 | + ); | ||
41 | + } | ||
42 | + | ||
43 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 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="{{ 'relation.add' | translate }}" style="min-width: 400px;"> | ||
19 | + <form name="theForm" ng-submit="vm.add()"> | ||
20 | + <md-toolbar> | ||
21 | + <div class="md-toolbar-tools"> | ||
22 | + <h2 translate>relation.add</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="!loading" ng-show="loading"></md-progress-linear> | ||
30 | + <span style="min-height: 5px;" flex="" ng-show="!loading"></span> | ||
31 | + <md-dialog-content> | ||
32 | + <div class="md-dialog-content"> | ||
33 | + <md-content class="md-padding" layout="column"> | ||
34 | + <fieldset ng-disabled="loading"> | ||
35 | + <md-input-container class="md-block"> | ||
36 | + <label translate>relation.relation-type</label> | ||
37 | + <md-select required ng-model="vm.relation.type" ng-disabled="loading"> | ||
38 | + <md-option ng-repeat="type in vm.types.entityRelationType" ng-value="type"> | ||
39 | + <span>{{('relation.relation-types.' + type) | translate}}</span> | ||
40 | + </md-option> | ||
41 | + </md-select> | ||
42 | + </md-input-container> | ||
43 | + <span class="tb-small">{{'entity.entity' | translate }}</span> | ||
44 | + <tb-entity-select flex | ||
45 | + the-form="theForm" | ||
46 | + tb-required="true" | ||
47 | + ng-model="vm.relation.to"> | ||
48 | + </tb-entity-select> | ||
49 | + </fieldset> | ||
50 | + </md-content> | ||
51 | + </div> | ||
52 | + </md-dialog-content> | ||
53 | + <md-dialog-actions layout="row"> | ||
54 | + <span flex></span> | ||
55 | + <md-button ng-disabled="loading || theForm.$invalid || !theForm.$dirty" type="submit" | ||
56 | + class="md-raised md-primary"> | ||
57 | + {{ 'action.add' | translate }} | ||
58 | + </md-button> | ||
59 | + <md-button ng-disabled="loading" ng-click="vm.cancel()" style="margin-right:20px;">{{ 'action.cancel' | | ||
60 | + translate }} | ||
61 | + </md-button> | ||
62 | + </md-dialog-actions> | ||
63 | + </form> | ||
64 | +</md-dialog> |
1 | +/* | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +import 'angular-material-data-table/dist/md-data-table.min.css'; | ||
17 | +import './relation-table.scss'; | ||
18 | + | ||
19 | +/* eslint-disable import/no-unresolved, import/default */ | ||
20 | + | ||
21 | +import relationTableTemplate from './relation-table.tpl.html'; | ||
22 | +import addRelationTemplate from './add-relation-dialog.tpl.html'; | ||
23 | + | ||
24 | +/* eslint-enable import/no-unresolved, import/default */ | ||
25 | + | ||
26 | +import AddRelationController from './add-relation-dialog.controller'; | ||
27 | + | ||
28 | +/*@ngInject*/ | ||
29 | +export default function RelationTable() { | ||
30 | + return { | ||
31 | + restrict: "E", | ||
32 | + scope: true, | ||
33 | + bindToController: { | ||
34 | + entityId: '=', | ||
35 | + entityType: '@' | ||
36 | + }, | ||
37 | + controller: RelationTableController, | ||
38 | + controllerAs: 'vm', | ||
39 | + templateUrl: relationTableTemplate | ||
40 | + }; | ||
41 | +} | ||
42 | + | ||
43 | +/*@ngInject*/ | ||
44 | +function RelationTableController($scope, $q, $mdDialog, $document, $translate, $filter, utils, types, entityRelationService) { | ||
45 | + | ||
46 | + let vm = this; | ||
47 | + | ||
48 | + vm.relations = []; | ||
49 | + vm.relationsCount = 0; | ||
50 | + vm.allRelations = []; | ||
51 | + vm.selectedRelations = []; | ||
52 | + | ||
53 | + vm.query = { | ||
54 | + order: 'typeName', | ||
55 | + limit: 5, | ||
56 | + page: 1, | ||
57 | + search: null | ||
58 | + }; | ||
59 | + | ||
60 | + vm.enterFilterMode = enterFilterMode; | ||
61 | + vm.exitFilterMode = exitFilterMode; | ||
62 | + vm.onReorder = onReorder; | ||
63 | + vm.onPaginate = onPaginate; | ||
64 | + vm.addRelation = addRelation; | ||
65 | + vm.editRelation = editRelation; | ||
66 | + vm.deleteRelation = deleteRelation; | ||
67 | + vm.deleteRelations = deleteRelations; | ||
68 | + vm.reloadRelations = reloadRelations; | ||
69 | + vm.updateRelations = updateRelations; | ||
70 | + | ||
71 | + | ||
72 | + $scope.$watch("vm.entityId", function(newVal, prevVal) { | ||
73 | + if (newVal && !angular.equals(newVal, prevVal)) { | ||
74 | + reloadRelations(); | ||
75 | + } | ||
76 | + }); | ||
77 | + | ||
78 | + $scope.$watch("vm.query.search", function(newVal, prevVal) { | ||
79 | + if (!angular.equals(newVal, prevVal) && vm.query.search != null) { | ||
80 | + updateRelations(); | ||
81 | + } | ||
82 | + }); | ||
83 | + | ||
84 | + function enterFilterMode () { | ||
85 | + vm.query.search = ''; | ||
86 | + } | ||
87 | + | ||
88 | + function exitFilterMode () { | ||
89 | + vm.query.search = null; | ||
90 | + updateRelations(); | ||
91 | + } | ||
92 | + | ||
93 | + function onReorder () { | ||
94 | + updateRelations(); | ||
95 | + } | ||
96 | + | ||
97 | + function onPaginate () { | ||
98 | + updateRelations(); | ||
99 | + } | ||
100 | + | ||
101 | + function addRelation($event) { | ||
102 | + if ($event) { | ||
103 | + $event.stopPropagation(); | ||
104 | + } | ||
105 | + var from = { | ||
106 | + id: vm.entityId, | ||
107 | + entityType: vm.entityType | ||
108 | + }; | ||
109 | + $mdDialog.show({ | ||
110 | + controller: AddRelationController, | ||
111 | + controllerAs: 'vm', | ||
112 | + templateUrl: addRelationTemplate, | ||
113 | + parent: angular.element($document[0].body), | ||
114 | + locals: { from: from }, | ||
115 | + fullscreen: true, | ||
116 | + targetEvent: $event | ||
117 | + }).then(function () { | ||
118 | + reloadRelations(); | ||
119 | + }, function () { | ||
120 | + }); | ||
121 | + } | ||
122 | + | ||
123 | + function editRelation($event, /*relation*/) { | ||
124 | + if ($event) { | ||
125 | + $event.stopPropagation(); | ||
126 | + } | ||
127 | + //TODO: | ||
128 | + } | ||
129 | + | ||
130 | + function deleteRelation($event, /*relation*/) { | ||
131 | + if ($event) { | ||
132 | + $event.stopPropagation(); | ||
133 | + } | ||
134 | + //TODO: | ||
135 | + } | ||
136 | + | ||
137 | + function deleteRelations($event) { | ||
138 | + if ($event) { | ||
139 | + $event.stopPropagation(); | ||
140 | + } | ||
141 | + //TODO: | ||
142 | + } | ||
143 | + | ||
144 | + function reloadRelations () { | ||
145 | + vm.allRelations.length = 0; | ||
146 | + vm.relations.length = 0; | ||
147 | + vm.relationsPromise = entityRelationService.findInfoByFrom(vm.entityId, vm.entityType); | ||
148 | + vm.relationsPromise.then( | ||
149 | + function success(allRelations) { | ||
150 | + allRelations.forEach(function(relation) { | ||
151 | + relation.typeName = $translate.instant('relation.relation-type.' + relation.type); | ||
152 | + relation.toEntityTypeName = $translate.instant(utils.entityTypeName(relation.to.entityType)); | ||
153 | + }); | ||
154 | + vm.allRelations = allRelations; | ||
155 | + vm.selectedRelations = []; | ||
156 | + vm.updateRelations(); | ||
157 | + vm.relationsPromise = null; | ||
158 | + }, | ||
159 | + function fail() { | ||
160 | + vm.allRelations = []; | ||
161 | + vm.selectedRelations = []; | ||
162 | + vm.updateRelations(); | ||
163 | + vm.relationsPromise = null; | ||
164 | + } | ||
165 | + ) | ||
166 | + } | ||
167 | + | ||
168 | + function updateRelations () { | ||
169 | + vm.selectedRelations = []; | ||
170 | + var result = $filter('orderBy')(vm.allRelations, vm.query.order); | ||
171 | + if (vm.query.search != null) { | ||
172 | + result = $filter('filter')(result, {$: vm.query.search}); | ||
173 | + } | ||
174 | + vm.relationsCount = result.length; | ||
175 | + var startIndex = vm.query.limit * (vm.query.page - 1); | ||
176 | + vm.relations = result.slice(startIndex, startIndex + vm.query.limit); | ||
177 | + } | ||
178 | + | ||
179 | +} |
1 | +/** | ||
2 | + * Copyright © 2016-2017 The Thingsboard Authors | ||
3 | + * | ||
4 | + * Licensed under the Apache License, Version 2.0 (the "License"); | ||
5 | + * you may not use this file except in compliance with the License. | ||
6 | + * You may obtain a copy of the License at | ||
7 | + * | ||
8 | + * http://www.apache.org/licenses/LICENSE-2.0 | ||
9 | + * | ||
10 | + * Unless required by applicable law or agreed to in writing, software | ||
11 | + * distributed under the License is distributed on an "AS IS" BASIS, | ||
12 | + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
13 | + * See the License for the specific language governing permissions and | ||
14 | + * limitations under the License. | ||
15 | + */ | ||
16 | +@import '../../../scss/constants'; | ||
17 | + | ||
18 | +$md-light: rgba(255, 255, 255, 100%); | ||
19 | + | ||
20 | +.tb-relation-table { | ||
21 | + md-toolbar.md-table-toolbar.alternate { | ||
22 | + .md-toolbar-tools { | ||
23 | + md-icon { | ||
24 | + color: $md-light; | ||
25 | + } | ||
26 | + } | ||
27 | + } | ||
28 | +} |
1 | +<!-- | ||
2 | + | ||
3 | + Copyright © 2016-2017 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-content flex class="md-padding tb-absolute-fill tb-relation-table tb-data-table" layout="column"> | ||
19 | + <div layout="column" class="md-whiteframe-z1"> | ||
20 | + <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedRelations.length | ||
21 | + && vm.query.search === null"> | ||
22 | + <div class="md-toolbar-tools"> | ||
23 | + <span translate>relation.entity-relations</span> | ||
24 | + <span flex></span> | ||
25 | + <md-button class="md-icon-button" ng-click="vm.addRelation($event)"> | ||
26 | + <md-icon>add</md-icon> | ||
27 | + <md-tooltip md-direction="top"> | ||
28 | + {{ 'action.add' | translate }} | ||
29 | + </md-tooltip> | ||
30 | + </md-button> | ||
31 | + <md-button class="md-icon-button" ng-click="vm.enterFilterMode()"> | ||
32 | + <md-icon>search</md-icon> | ||
33 | + <md-tooltip md-direction="top"> | ||
34 | + {{ 'action.search' | translate }} | ||
35 | + </md-tooltip> | ||
36 | + </md-button> | ||
37 | + <md-button class="md-icon-button" ng-click="vm.reloadRelations()"> | ||
38 | + <md-icon>refresh</md-icon> | ||
39 | + <md-tooltip md-direction="top"> | ||
40 | + {{ 'action.refresh' | translate }} | ||
41 | + </md-tooltip> | ||
42 | + </md-button> | ||
43 | + </div> | ||
44 | + </md-toolbar> | ||
45 | + <md-toolbar class="md-table-toolbar md-default" ng-show="!vm.selectedRelations.length | ||
46 | + && vm.query.search != null"> | ||
47 | + <div class="md-toolbar-tools"> | ||
48 | + <md-button class="md-icon-button" aria-label="{{ 'action.search' | translate }}"> | ||
49 | + <md-icon aria-label="{{ 'action.search' | translate }}" class="material-icons">search</md-icon> | ||
50 | + <md-tooltip md-direction="top"> | ||
51 | + {{ 'action.search' | translate }} | ||
52 | + </md-tooltip> | ||
53 | + </md-button> | ||
54 | + <md-input-container flex> | ||
55 | + <label> </label> | ||
56 | + <input ng-model="vm.query.search" placeholder="{{ 'common.enter-search' | translate }}"/> | ||
57 | + </md-input-container> | ||
58 | + <md-button class="md-icon-button" aria-label="{{ 'action.back' | translate }}" ng-click="vm.exitFilterMode()"> | ||
59 | + <md-icon aria-label="{{ 'action.close' | translate }}" class="material-icons">close</md-icon> | ||
60 | + <md-tooltip md-direction="top"> | ||
61 | + {{ 'action.close' | translate }} | ||
62 | + </md-tooltip> | ||
63 | + </md-button> | ||
64 | + </div> | ||
65 | + </md-toolbar> | ||
66 | + <md-toolbar class="md-table-toolbar alternate" ng-show="vm.selectedRelations.length"> | ||
67 | + <div class="md-toolbar-tools"> | ||
68 | + <span translate | ||
69 | + translate-values="{count: selectedRelations.length}" | ||
70 | + translate-interpolation="messageformat">relation.selected-relations</span> | ||
71 | + <span flex></span> | ||
72 | + <md-button class="md-icon-button" ng-click="vm.deleteRelations($event)"> | ||
73 | + <md-icon>delete</md-icon> | ||
74 | + <md-tooltip md-direction="top"> | ||
75 | + {{ 'action.delete' | translate }} | ||
76 | + </md-tooltip> | ||
77 | + </md-button> | ||
78 | + </div> | ||
79 | + </md-toolbar> | ||
80 | + <md-table-container> | ||
81 | + <table md-table md-row-select multiple="" ng-model="vm.selectedRelations" md-progress="vm.relationsDeferred.promise"> | ||
82 | + <thead md-head md-order="vm.query.order" md-on-reorder="vm.onReorder"> | ||
83 | + <tr md-row> | ||
84 | + <th md-column md-order-by="typeName"><span translate>relation.type</span></th> | ||
85 | + <th md-column md-order-by="toEntityTypeName"><span translate>relation.to-entity-type</span></th> | ||
86 | + <th md-column md-order-by="toName"><span translate>relation.to-entity-name</span></th> | ||
87 | + <th md-column><span> </span></th> | ||
88 | + </tr> | ||
89 | + </thead> | ||
90 | + <tbody md-body> | ||
91 | + <tr md-row md-select="relation" md-select-id="relation" md-auto-select ng-repeat="relation in vm.relations"> | ||
92 | + <td md-cell>{{ relation.typeName }}</td> | ||
93 | + <td md-cell>{{ relation.toEntityTypeName }}</td> | ||
94 | + <td md-cell>{{ relation.toName }}</td> | ||
95 | + <td md-cell class="tb-action-cell"> | ||
96 | + <md-button class="md-icon-button" aria-label="{{ 'action.edit' | translate }}" | ||
97 | + ng-click="vm.editRelation($event, relation)"> | ||
98 | + <md-icon aria-label="{{ 'action.edit' | translate }}" class="material-icons">edit</md-icon> | ||
99 | + <md-tooltip md-direction="top"> | ||
100 | + {{ 'relation.edit' | translate }} | ||
101 | + </md-tooltip> | ||
102 | + </md-button> | ||
103 | + <md-button class="md-icon-button" aria-label="{{ 'action.delete' | translate }}" ng-click="vm.deleteRelation($event, relation)"> | ||
104 | + <md-icon aria-label="{{ 'action.delete' | translate }}" class="material-icons">delete</md-icon> | ||
105 | + <md-tooltip md-direction="top"> | ||
106 | + {{ 'relation.delete' | translate }} | ||
107 | + </md-tooltip> | ||
108 | + </md-button> | ||
109 | + </td> | ||
110 | + </tr> | ||
111 | + </tbody> | ||
112 | + </table> | ||
113 | + </md-table-container> | ||
114 | + <md-table-pagination md-limit="vm.query.limit" md-limit-options="[5, 10, 15]" | ||
115 | + md-page="vm.query.page" md-total="{{vm.relationsCount}}" | ||
116 | + md-on-paginate="onPaginate" md-page-select> | ||
117 | + </md-table-pagination> | ||
118 | + </div> | ||
119 | +</md-content> |
@@ -235,7 +235,7 @@ | @@ -235,7 +235,7 @@ | ||
235 | "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", | 235 | "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", |
236 | "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", | 236 | "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", |
237 | "select-dashboard": "Seleccionar panel", | 237 | "select-dashboard": "Seleccionar panel", |
238 | - "no-dashboards-matching": "Panel '{{dashboard}}' no encontrado.", | 238 | + "no-dashboards-matching": "Panel '{{entity}}' no encontrado.", |
239 | "dashboard-required": "Panel requerido.", | 239 | "dashboard-required": "Panel requerido.", |
240 | "select-existing": "Seleccionar paneles existentes", | 240 | "select-existing": "Seleccionar paneles existentes", |
241 | "create-new": "Crear nuevo panel", | 241 | "create-new": "Crear nuevo panel", |
@@ -330,7 +330,7 @@ | @@ -330,7 +330,7 @@ | ||
330 | "create-new-key": "Crear nueva clave!", | 330 | "create-new-key": "Crear nueva clave!", |
331 | "duplicate-alias-error": "Alias duplicado '{{alias}}'.<br> El alias de los dispositivos deben ser únicos dentro del panel.", | 331 | "duplicate-alias-error": "Alias duplicado '{{alias}}'.<br> El alias de los dispositivos deben ser únicos dentro del panel.", |
332 | "configure-alias": "Configurar alias '{{alias}}'", | 332 | "configure-alias": "Configurar alias '{{alias}}'", |
333 | - "no-devices-matching": "No se encontró dispositivo '{{device}}'", | 333 | + "no-devices-matching": "No se encontró dispositivo '{{entity}}'", |
334 | "alias": "Alias", | 334 | "alias": "Alias", |
335 | "alias-required": "Alias de dispositivo requerido.", | 335 | "alias-required": "Alias de dispositivo requerido.", |
336 | "remove-alias": "Eliminar alias", | 336 | "remove-alias": "Eliminar alias", |
@@ -529,7 +529,7 @@ | @@ -529,7 +529,7 @@ | ||
529 | "system": "Sistema", | 529 | "system": "Sistema", |
530 | "select-plugin": "plugin", | 530 | "select-plugin": "plugin", |
531 | "plugin": "Plugin", | 531 | "plugin": "Plugin", |
532 | - "no-plugins-matching": "No se encontraron plugins: '{{plugin}}'", | 532 | + "no-plugins-matching": "No se encontraron plugins: '{{entity}}'", |
533 | "plugin-required": "Plugin requerido.", | 533 | "plugin-required": "Plugin requerido.", |
534 | "plugin-require-match": "Por favor, elija un plugin existente.", | 534 | "plugin-require-match": "Por favor, elija un plugin existente.", |
535 | "events": "Eventos", | 535 | "events": "Eventos", |
@@ -218,7 +218,7 @@ export default function addLocaleKorean(locales) { | @@ -218,7 +218,7 @@ export default function addLocaleKorean(locales) { | ||
218 | "unassign-dashboards-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }의 할당을 취소하시겠습니까?", | 218 | "unassign-dashboards-title": "{ count, select, 1 {대시보드 1개} other {대시보드 #개} }의 할당을 취소하시겠습니까?", |
219 | "unassign-dashboards-text": "선택된 대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", | 219 | "unassign-dashboards-text": "선택된 대시보드가 할당 해제되고 커스터머는 액세스 할 수 없게됩니다.", |
220 | "select-dashboard": "대시보드 선택", | 220 | "select-dashboard": "대시보드 선택", |
221 | - "no-dashboards-matching": "'{{dashboard}}'와 일치하는 대시보드가 없습니다.", | 221 | + "no-dashboards-matching": "'{{entity}}'와 일치하는 대시보드가 없습니다.", |
222 | "dashboard-required": "대시보드를 입력하세요.", | 222 | "dashboard-required": "대시보드를 입력하세요.", |
223 | "select-existing": "기존 대시보드 선택", | 223 | "select-existing": "기존 대시보드 선택", |
224 | "create-new": "대시보드 생성", | 224 | "create-new": "대시보드 생성", |
@@ -305,7 +305,7 @@ export default function addLocaleKorean(locales) { | @@ -305,7 +305,7 @@ export default function addLocaleKorean(locales) { | ||
305 | "create-new-key": "새로 만들기!", | 305 | "create-new-key": "새로 만들기!", |
306 | "duplicate-alias-error": "중복된 '{{alias}}' 앨리어스가 있습니다.<br> 디바이스 앨리어스는 대시보드 내에서 고유해야 합니다.", | 306 | "duplicate-alias-error": "중복된 '{{alias}}' 앨리어스가 있습니다.<br> 디바이스 앨리어스는 대시보드 내에서 고유해야 합니다.", |
307 | "configure-alias": "'{{alias}}' 앨리어스 구성", | 307 | "configure-alias": "'{{alias}}' 앨리어스 구성", |
308 | - "no-devices-matching": "'{{device}}'와 일치하는 디바이스를 찾을 수 없습니다.", | 308 | + "no-devices-matching": "'{{entity}}'와 일치하는 디바이스를 찾을 수 없습니다.", |
309 | "alias": "앨리어스", | 309 | "alias": "앨리어스", |
310 | "alias-required": "디바이스 앨리어스를 입력하세요.", | 310 | "alias-required": "디바이스 앨리어스를 입력하세요.", |
311 | "remove-alias": "디바이스 앨리어스 삭제", | 311 | "remove-alias": "디바이스 앨리어스 삭제", |
@@ -496,7 +496,7 @@ export default function addLocaleKorean(locales) { | @@ -496,7 +496,7 @@ export default function addLocaleKorean(locales) { | ||
496 | "system": "시스템", | 496 | "system": "시스템", |
497 | "select-plugin": "플러그인 선택", | 497 | "select-plugin": "플러그인 선택", |
498 | "plugin": "플러그인", | 498 | "plugin": "플러그인", |
499 | - "no-plugins-matching": "'{{plugin}}'과 일치하는 플러그인을 찾을 수 없습니다.", | 499 | + "no-plugins-matching": "'{{entity}}'과 일치하는 플러그인을 찾을 수 없습니다.", |
500 | "plugin-required": "플러그인을 입력하세요.", | 500 | "plugin-required": "플러그인을 입력하세요.", |
501 | "plugin-require-match": "기존의 플러그인을 선택해주세요.", | 501 | "plugin-require-match": "기존의 플러그인을 선택해주세요.", |
502 | "events": "이벤트", | 502 | "events": "이벤트", |
@@ -235,7 +235,7 @@ export default function addLocaleRussian(locales) { | @@ -235,7 +235,7 @@ export default function addLocaleRussian(locales) { | ||
235 | "socialshare-text": "'{{dashboardTitle}}' сделано ThingsBoard", | 235 | "socialshare-text": "'{{dashboardTitle}}' сделано ThingsBoard", |
236 | "socialshare-title": "'{{dashboardTitle}}' сделано ThingsBoard", | 236 | "socialshare-title": "'{{dashboardTitle}}' сделано ThingsBoard", |
237 | "select-dashboard": "Выберите дашборд", | 237 | "select-dashboard": "Выберите дашборд", |
238 | - "no-dashboards-matching": "Дашборд '{{dashboard}}' не найден.", | 238 | + "no-dashboards-matching": "Дашборд '{{entity}}' не найден.", |
239 | "dashboard-required": "Дашборд обязателен.", | 239 | "dashboard-required": "Дашборд обязателен.", |
240 | "select-existing": "Выберите существующий дашборд", | 240 | "select-existing": "Выберите существующий дашборд", |
241 | "create-new": "Создать новый дашборд", | 241 | "create-new": "Создать новый дашборд", |
@@ -330,7 +330,7 @@ export default function addLocaleRussian(locales) { | @@ -330,7 +330,7 @@ export default function addLocaleRussian(locales) { | ||
330 | "create-new-key": "Создать новый!", | 330 | "create-new-key": "Создать новый!", |
331 | "duplicate-alias-error": "Найден дублирующийся псевдоним '{{alias}}'.<br>В рамках дашборда псевдонимы устройств должны быть уникальными.", | 331 | "duplicate-alias-error": "Найден дублирующийся псевдоним '{{alias}}'.<br>В рамках дашборда псевдонимы устройств должны быть уникальными.", |
332 | "configure-alias": "Конфигурировать '{{alias}}' псевдоним", | 332 | "configure-alias": "Конфигурировать '{{alias}}' псевдоним", |
333 | - "no-devices-matching": "Устройство '{{device}}' не найдено.", | 333 | + "no-devices-matching": "Устройство '{{entity}}' не найдено.", |
334 | "alias": "Псевдоним", | 334 | "alias": "Псевдоним", |
335 | "alias-required": "Псевдоним устройства обязателен.", | 335 | "alias-required": "Псевдоним устройства обязателен.", |
336 | "remove-alias": "Удалить псевдоним устройства", | 336 | "remove-alias": "Удалить псевдоним устройства", |
@@ -529,7 +529,7 @@ export default function addLocaleRussian(locales) { | @@ -529,7 +529,7 @@ export default function addLocaleRussian(locales) { | ||
529 | "system": "Системный", | 529 | "system": "Системный", |
530 | "select-plugin": "Выберите плагин", | 530 | "select-plugin": "Выберите плагин", |
531 | "plugin": "Плагин", | 531 | "plugin": "Плагин", |
532 | - "no-plugins-matching": "Плагин '{{plugin}}' не найден.", | 532 | + "no-plugins-matching": "Плагин '{{entity}}' не найден.", |
533 | "plugin-required": "Плагин обязателен.", | 533 | "plugin-required": "Плагин обязателен.", |
534 | "plugin-require-match": "Пожалуйста, выберите существующий плагин.", | 534 | "plugin-require-match": "Пожалуйста, выберите существующий плагин.", |
535 | "events": "События", | 535 | "events": "События", |
@@ -235,7 +235,7 @@ export default function addLocaleChinese(locales) { | @@ -235,7 +235,7 @@ export default function addLocaleChinese(locales) { | ||
235 | "socialshare-text" : "'{{dashboardTitle}}' 由ThingsBoard提供支持", | 235 | "socialshare-text" : "'{{dashboardTitle}}' 由ThingsBoard提供支持", |
236 | "socialshare-title" : "'{{dashboardTitle}}' 由ThingsBoard提供支持", | 236 | "socialshare-title" : "'{{dashboardTitle}}' 由ThingsBoard提供支持", |
237 | "select-dashboard" : "选择仪表板", | 237 | "select-dashboard" : "选择仪表板", |
238 | - "no-dashboards-matching" : "找不到符合 '{{dashboard}}' 的仪表板。", | 238 | + "no-dashboards-matching" : "找不到符合 '{{entity}}' 的仪表板。", |
239 | "dashboard-required" : "仪表板是必需的。", | 239 | "dashboard-required" : "仪表板是必需的。", |
240 | "select-existing" : "选择现有仪表板", | 240 | "select-existing" : "选择现有仪表板", |
241 | "create-new" : "创建新的仪表板", | 241 | "create-new" : "创建新的仪表板", |
@@ -330,7 +330,7 @@ export default function addLocaleChinese(locales) { | @@ -330,7 +330,7 @@ export default function addLocaleChinese(locales) { | ||
330 | "create-new-key": "创建一个新的!", | 330 | "create-new-key": "创建一个新的!", |
331 | "duplicate-alias-error" : "找到重复别名 '{{alias}}'。 <br> 设备别名必须是唯一的。", | 331 | "duplicate-alias-error" : "找到重复别名 '{{alias}}'。 <br> 设备别名必须是唯一的。", |
332 | "configure-alias" : "配置 '{{alias}}' 别名", | 332 | "configure-alias" : "配置 '{{alias}}' 别名", |
333 | - "no-devices-matching" : "找不到与 '{{device}}' 匹配的设备。", | 333 | + "no-devices-matching" : "找不到与 '{{entity}}' 匹配的设备。", |
334 | "alias" : "别名", | 334 | "alias" : "别名", |
335 | "alias-required" : "需要设备别名。", | 335 | "alias-required" : "需要设备别名。", |
336 | "remove-alias": "删除设备别名", | 336 | "remove-alias": "删除设备别名", |
@@ -529,7 +529,7 @@ export default function addLocaleChinese(locales) { | @@ -529,7 +529,7 @@ export default function addLocaleChinese(locales) { | ||
529 | "system" : "系统", | 529 | "system" : "系统", |
530 | "select-plugin" : "选择插件", | 530 | "select-plugin" : "选择插件", |
531 | "plugin" : "插件", | 531 | "plugin" : "插件", |
532 | - "no-plugins-matching" : "没有找到匹配'{{plugin}}'的插件。", | 532 | + "no-plugins-matching" : "没有找到匹配'{{entity}}'的插件。", |
533 | "plugin-required" : "插件是必需的。", | 533 | "plugin-required" : "插件是必需的。", |
534 | "plugin-require-match" : "请选择一个现有的插件。", | 534 | "plugin-require-match" : "请选择一个现有的插件。", |
535 | "events" : "事件", | 535 | "events" : "事件", |
@@ -106,6 +106,12 @@ export default angular.module('thingsboard.locale', []) | @@ -106,6 +106,12 @@ export default angular.module('thingsboard.locale', []) | ||
106 | "enable-tls": "Enable TLS", | 106 | "enable-tls": "Enable TLS", |
107 | "send-test-mail": "Send test mail" | 107 | "send-test-mail": "Send test mail" |
108 | }, | 108 | }, |
109 | + "alarm": { | ||
110 | + "alarm": "Alarm", | ||
111 | + "select-alarm": "Select alarm", | ||
112 | + "no-alarms-matching": "No alarms matching '{{entity}}' were found.", | ||
113 | + "alarm-required": "Alarm is required" | ||
114 | + }, | ||
109 | "asset": { | 115 | "asset": { |
110 | "asset": "Asset", | 116 | "asset": "Asset", |
111 | "assets": "Assets", | 117 | "assets": "Assets", |
@@ -157,7 +163,10 @@ export default angular.module('thingsboard.locale', []) | @@ -157,7 +163,10 @@ export default angular.module('thingsboard.locale', []) | ||
157 | "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", | 163 | "unassign-assets-title": "Are you sure you want to unassign { count, select, 1 {1 asset} other {# assets} }?", |
158 | "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", | 164 | "unassign-assets-text": "After the confirmation all selected assets will be unassigned and won't be accessible by the customer.", |
159 | "copyId": "Copy asset Id", | 165 | "copyId": "Copy asset Id", |
160 | - "idCopiedMessage": "Asset Id has been copied to clipboard" | 166 | + "idCopiedMessage": "Asset Id has been copied to clipboard", |
167 | + "select-asset": "Select asset", | ||
168 | + "no-assets-matching": "No assets matching '{{entity}}' were found.", | ||
169 | + "asset-required": "Asset is required" | ||
161 | }, | 170 | }, |
162 | "attribute": { | 171 | "attribute": { |
163 | "attributes": "Attributes", | 172 | "attributes": "Attributes", |
@@ -169,6 +178,7 @@ export default angular.module('thingsboard.locale', []) | @@ -169,6 +178,7 @@ export default angular.module('thingsboard.locale', []) | ||
169 | "scope-shared": "Shared attributes", | 178 | "scope-shared": "Shared attributes", |
170 | "add": "Add attribute", | 179 | "add": "Add attribute", |
171 | "key": "Key", | 180 | "key": "Key", |
181 | + "last-update-time": "Last update time", | ||
172 | "key-required": "Attribute key is required.", | 182 | "key-required": "Attribute key is required.", |
173 | "value": "Value", | 183 | "value": "Value", |
174 | "value-required": "Attribute value is required.", | 184 | "value-required": "Attribute value is required.", |
@@ -210,6 +220,7 @@ export default angular.module('thingsboard.locale', []) | @@ -210,6 +220,7 @@ export default angular.module('thingsboard.locale', []) | ||
210 | "enter-search": "Enter search" | 220 | "enter-search": "Enter search" |
211 | }, | 221 | }, |
212 | "customer": { | 222 | "customer": { |
223 | + "customer": "Customer", | ||
213 | "customers": "Customers", | 224 | "customers": "Customers", |
214 | "management": "Customer management", | 225 | "management": "Customer management", |
215 | "dashboard": "Customer Dashboard", | 226 | "dashboard": "Customer Dashboard", |
@@ -246,7 +257,10 @@ export default angular.module('thingsboard.locale', []) | @@ -246,7 +257,10 @@ export default angular.module('thingsboard.locale', []) | ||
246 | "details": "Details", | 257 | "details": "Details", |
247 | "events": "Events", | 258 | "events": "Events", |
248 | "copyId": "Copy customer Id", | 259 | "copyId": "Copy customer Id", |
249 | - "idCopiedMessage": "Customer Id has been copied to clipboard" | 260 | + "idCopiedMessage": "Customer Id has been copied to clipboard", |
261 | + "select-customer": "Select customer", | ||
262 | + "no-customers-matching": "No customers matching '{{entity}}' were found.", | ||
263 | + "customer-required": "Customer is required" | ||
250 | }, | 264 | }, |
251 | "datetime": { | 265 | "datetime": { |
252 | "date-from": "Date from", | 266 | "date-from": "Date from", |
@@ -304,7 +318,7 @@ export default angular.module('thingsboard.locale', []) | @@ -304,7 +318,7 @@ export default angular.module('thingsboard.locale', []) | ||
304 | "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", | 318 | "socialshare-text": "'{{dashboardTitle}}' powered by ThingsBoard", |
305 | "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", | 319 | "socialshare-title": "'{{dashboardTitle}}' powered by ThingsBoard", |
306 | "select-dashboard": "Select dashboard", | 320 | "select-dashboard": "Select dashboard", |
307 | - "no-dashboards-matching": "No dashboards matching '{{dashboard}}' were found.", | 321 | + "no-dashboards-matching": "No dashboards matching '{{entity}}' were found.", |
308 | "dashboard-required": "Dashboard is required.", | 322 | "dashboard-required": "Dashboard is required.", |
309 | "select-existing": "Select existing dashboard", | 323 | "select-existing": "Select existing dashboard", |
310 | "create-new": "Create new dashboard", | 324 | "create-new": "Create new dashboard", |
@@ -425,7 +439,7 @@ export default angular.module('thingsboard.locale', []) | @@ -425,7 +439,7 @@ export default angular.module('thingsboard.locale', []) | ||
425 | "create-new-key": "Create a new one!", | 439 | "create-new-key": "Create a new one!", |
426 | "duplicate-alias-error": "Duplicate alias found '{{alias}}'.<br>Device aliases must be unique whithin the dashboard.", | 440 | "duplicate-alias-error": "Duplicate alias found '{{alias}}'.<br>Device aliases must be unique whithin the dashboard.", |
427 | "configure-alias": "Configure '{{alias}}' alias", | 441 | "configure-alias": "Configure '{{alias}}' alias", |
428 | - "no-devices-matching": "No devices matching '{{device}}' were found.", | 442 | + "no-devices-matching": "No devices matching '{{entity}}' were found.", |
429 | "alias": "Alias", | 443 | "alias": "Alias", |
430 | "alias-required": "Device alias is required.", | 444 | "alias-required": "Device alias is required.", |
431 | "remove-alias": "Remove device alias", | 445 | "remove-alias": "Remove device alias", |
@@ -497,7 +511,8 @@ export default angular.module('thingsboard.locale', []) | @@ -497,7 +511,8 @@ export default angular.module('thingsboard.locale', []) | ||
497 | "unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}", | 511 | "unable-delete-device-alias-text": "Device alias '{{deviceAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}", |
498 | "is-gateway": "Is gateway", | 512 | "is-gateway": "Is gateway", |
499 | "public": "Public", | 513 | "public": "Public", |
500 | - "device-public": "Device is public" | 514 | + "device-public": "Device is public", |
515 | + "select-device": "Select device" | ||
501 | }, | 516 | }, |
502 | "dialog": { | 517 | "dialog": { |
503 | "close": "Close dialog" | 518 | "close": "Close dialog" |
@@ -535,6 +550,9 @@ export default angular.module('thingsboard.locale', []) | @@ -535,6 +550,9 @@ export default angular.module('thingsboard.locale', []) | ||
535 | "type-plugin": "Plugin", | 550 | "type-plugin": "Plugin", |
536 | "type-tenant": "Tenant", | 551 | "type-tenant": "Tenant", |
537 | "type-customer": "Customer", | 552 | "type-customer": "Customer", |
553 | + "type-user": "User", | ||
554 | + "type-dashboard": "Dashboard", | ||
555 | + "type-alarm": "Alarm", | ||
538 | "select-entities": "Select entities", | 556 | "select-entities": "Select entities", |
539 | "no-aliases-found": "No aliases found.", | 557 | "no-aliases-found": "No aliases found.", |
540 | "no-alias-matching": "'{{alias}}' not found.", | 558 | "no-alias-matching": "'{{alias}}' not found.", |
@@ -672,7 +690,7 @@ export default angular.module('thingsboard.locale', []) | @@ -672,7 +690,7 @@ export default angular.module('thingsboard.locale', []) | ||
672 | "system": "System", | 690 | "system": "System", |
673 | "select-plugin": "Select plugin", | 691 | "select-plugin": "Select plugin", |
674 | "plugin": "Plugin", | 692 | "plugin": "Plugin", |
675 | - "no-plugins-matching": "No plugins matching '{{plugin}}' were found.", | 693 | + "no-plugins-matching": "No plugins matching '{{entity}}' were found.", |
676 | "plugin-required": "Plugin is required.", | 694 | "plugin-required": "Plugin is required.", |
677 | "plugin-require-match": "Please select an existing plugin.", | 695 | "plugin-require-match": "Please select an existing plugin.", |
678 | "events": "Events", | 696 | "events": "Events", |
@@ -685,6 +703,7 @@ export default angular.module('thingsboard.locale', []) | @@ -685,6 +703,7 @@ export default angular.module('thingsboard.locale', []) | ||
685 | "invalid-plugin-file-error": "Unable to import plugin: Invalid plugin data structure.", | 703 | "invalid-plugin-file-error": "Unable to import plugin: Invalid plugin data structure.", |
686 | "copyId": "Copy plugin Id", | 704 | "copyId": "Copy plugin Id", |
687 | "idCopiedMessage": "Plugin Id has been copied to clipboard" | 705 | "idCopiedMessage": "Plugin Id has been copied to clipboard" |
706 | + | ||
688 | }, | 707 | }, |
689 | "position": { | 708 | "position": { |
690 | "top": "Top", | 709 | "top": "Top", |
@@ -697,7 +716,24 @@ export default angular.module('thingsboard.locale', []) | @@ -697,7 +716,24 @@ export default angular.module('thingsboard.locale', []) | ||
697 | "change-password": "Change Password", | 716 | "change-password": "Change Password", |
698 | "current-password": "Current password" | 717 | "current-password": "Current password" |
699 | }, | 718 | }, |
719 | + "relation": { | ||
720 | + "relations": "Relations", | ||
721 | + "entity-relations": "Entity relations", | ||
722 | + "selected-relations": "{ count, select, 1 {1 relation} other {# relations} } selected", | ||
723 | + "type": "Type", | ||
724 | + "to-entity-type": "Entity type", | ||
725 | + "to-entity-name": "Entity name", | ||
726 | + "edit": "Edit relation", | ||
727 | + "delete": "Delete relation", | ||
728 | + "relation-type": "Relation type", | ||
729 | + "relation-types": { | ||
730 | + "Contains": "Contains", | ||
731 | + "Manages": "Manages" | ||
732 | + }, | ||
733 | + "add": "Add relation" | ||
734 | + }, | ||
700 | "rule": { | 735 | "rule": { |
736 | + "rule": "Rule", | ||
701 | "rules": "Rules", | 737 | "rules": "Rules", |
702 | "delete": "Delete rule", | 738 | "delete": "Delete rule", |
703 | "activate": "Activate rule", | 739 | "activate": "Activate rule", |
@@ -749,12 +785,16 @@ export default angular.module('thingsboard.locale', []) | @@ -749,12 +785,16 @@ export default angular.module('thingsboard.locale', []) | ||
749 | "rule-file": "Rule file", | 785 | "rule-file": "Rule file", |
750 | "invalid-rule-file-error": "Unable to import rule: Invalid rule data structure.", | 786 | "invalid-rule-file-error": "Unable to import rule: Invalid rule data structure.", |
751 | "copyId": "Copy rule Id", | 787 | "copyId": "Copy rule Id", |
752 | - "idCopiedMessage": "Rule Id has been copied to clipboard" | 788 | + "idCopiedMessage": "Rule Id has been copied to clipboard", |
789 | + "select-rule": "Select rule", | ||
790 | + "no-rules-matching": "No rules matching '{{entity}}' were found.", | ||
791 | + "rule-required": "Rule is required" | ||
753 | }, | 792 | }, |
754 | "rule-plugin": { | 793 | "rule-plugin": { |
755 | "management": "Rules and plugins management" | 794 | "management": "Rules and plugins management" |
756 | }, | 795 | }, |
757 | "tenant": { | 796 | "tenant": { |
797 | + "tenant": "Tenant", | ||
758 | "tenants": "Tenants", | 798 | "tenants": "Tenants", |
759 | "management": "Tenant management", | 799 | "management": "Tenant management", |
760 | "add": "Add Tenant", | 800 | "add": "Add Tenant", |
@@ -775,7 +815,10 @@ export default angular.module('thingsboard.locale', []) | @@ -775,7 +815,10 @@ export default angular.module('thingsboard.locale', []) | ||
775 | "details": "Details", | 815 | "details": "Details", |
776 | "events": "Events", | 816 | "events": "Events", |
777 | "copyId": "Copy tenant Id", | 817 | "copyId": "Copy tenant Id", |
778 | - "idCopiedMessage": "Tenant Id has been copied to clipboard" | 818 | + "idCopiedMessage": "Tenant Id has been copied to clipboard", |
819 | + "select-tenant": "Select tenant", | ||
820 | + "no-tenants-matching": "No tenants matching '{{entity}}' were found.", | ||
821 | + "tenant-required": "Tenant is required" | ||
779 | }, | 822 | }, |
780 | "timeinterval": { | 823 | "timeinterval": { |
781 | "seconds-interval": "{ seconds, select, 1 {1 second} other {# seconds} }", | 824 | "seconds-interval": "{ seconds, select, 1 {1 second} other {# seconds} }", |
@@ -803,6 +846,7 @@ export default angular.module('thingsboard.locale', []) | @@ -803,6 +846,7 @@ export default angular.module('thingsboard.locale', []) | ||
803 | "time-period": "Time period" | 846 | "time-period": "Time period" |
804 | }, | 847 | }, |
805 | "user": { | 848 | "user": { |
849 | + "user": "User", | ||
806 | "users": "Users", | 850 | "users": "Users", |
807 | "customer-users": "Customer Users", | 851 | "customer-users": "Customer Users", |
808 | "tenant-admins": "Tenant Admins", | 852 | "tenant-admins": "Tenant Admins", |
@@ -828,7 +872,10 @@ export default angular.module('thingsboard.locale', []) | @@ -828,7 +872,10 @@ export default angular.module('thingsboard.locale', []) | ||
828 | "last-name": "Last Name", | 872 | "last-name": "Last Name", |
829 | "description": "Description", | 873 | "description": "Description", |
830 | "default-dashboard": "Default dashboard", | 874 | "default-dashboard": "Default dashboard", |
831 | - "always-fullscreen": "Always fullscreen" | 875 | + "always-fullscreen": "Always fullscreen", |
876 | + "select-user": "Select user", | ||
877 | + "no-users-matching": "No users matching '{{entity}}' were found.", | ||
878 | + "user-required": "User is required" | ||
832 | }, | 879 | }, |
833 | "value": { | 880 | "value": { |
834 | "type": "Value type", | 881 | "type": "Value type", |
@@ -261,6 +261,45 @@ pre.tb-highlight { | @@ -261,6 +261,45 @@ pre.tb-highlight { | ||
261 | font-size: 16px; | 261 | font-size: 16px; |
262 | } | 262 | } |
263 | 263 | ||
264 | +.tb-data-table { | ||
265 | + md-toolbar { | ||
266 | + z-index: 0; | ||
267 | + } | ||
268 | + span.no-data-found { | ||
269 | + position: relative; | ||
270 | + height: calc(100% - 57px); | ||
271 | + text-transform: uppercase; | ||
272 | + display: flex; | ||
273 | + } | ||
274 | + table.md-table { | ||
275 | + tbody { | ||
276 | + tr { | ||
277 | + td { | ||
278 | + &.tb-action-cell { | ||
279 | + overflow: hidden; | ||
280 | + text-overflow: ellipsis; | ||
281 | + white-space: nowrap; | ||
282 | + min-width: 72px; | ||
283 | + max-width: 72px; | ||
284 | + width: 72px; | ||
285 | + .md-button { | ||
286 | + &.md-icon-button { | ||
287 | + margin: 0; | ||
288 | + padding: 6px; | ||
289 | + width: 36px; | ||
290 | + height: 36px; | ||
291 | + } | ||
292 | + } | ||
293 | + .tb-spacer { | ||
294 | + padding-left: 38px; | ||
295 | + } | ||
296 | + } | ||
297 | + } | ||
298 | + } | ||
299 | + } | ||
300 | + } | ||
301 | +} | ||
302 | + | ||
264 | 303 | ||
265 | /*********************** | 304 | /*********************** |
266 | * Flow | 305 | * Flow |