Browse Source

Fixes for entity view

pull/1070/head
Volodymyr Babak 8 years ago
parent
commit
5bf9528ee8
  1. 52
      application/src/main/java/org/thingsboard/server/controller/EntityViewController.java
  2. 42
      common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java
  3. 2
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java
  4. 8
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java
  5. 43
      dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java
  6. 1
      dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java
  7. 14
      dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java
  8. 6
      dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java
  9. 2
      dao/src/main/resources/cassandra/schema.cql
  10. 4
      ui/src/app/api/entity-view.service.js
  11. 2
      ui/src/app/common/types.constant.js
  12. 10
      ui/src/app/entity-view/entity-view-fieldset.tpl.html
  13. 12
      ui/src/app/entity-view/entity-view.controller.js
  14. 4
      ui/src/app/entity-view/entity-view.directive.js
  15. 10
      ui/src/app/entity-view/entity-view.routes.js
  16. 20
      ui/src/app/entity-view/entity-views.tpl.html
  17. 4
      ui/src/app/entity-view/index.js
  18. 2
      ui/src/app/layout/index.js
  19. 3
      ui/src/app/locale/locale.constant-en_US.json
  20. 52
      ui/src/app/services/menu.service.js

52
application/src/main/java/org/thingsboard/server/controller/EntityViewController.java

@ -19,17 +19,21 @@ import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.http.HttpStatus;
import org.springframework.security.access.prepost.PreAuthorize;
import org.springframework.web.bind.annotation.*;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.audit.ActionType;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.exception.ThingsboardException;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.service.security.model.SecurityUser;
import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
/**
* Created by Victor Basanets on 8/28/2017.
@ -41,7 +45,7 @@ public class EntityViewController extends BaseController {
public static final String ENTITY_VIEW_ID = "entityViewId";
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.GET)
@RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.GET)
@ResponseBody
public EntityView getEntityViewById(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId)
throws ThingsboardException {
@ -56,7 +60,7 @@ public class EntityViewController extends BaseController {
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/entity-view", method = RequestMethod.POST)
@RequestMapping(value = "/entityView", method = RequestMethod.POST)
@ResponseBody
public EntityView saveEntityView(@RequestBody EntityView entityView) throws ThingsboardException {
try {
@ -76,7 +80,7 @@ public class EntityViewController extends BaseController {
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/entity-view/{entityViewId}", method = RequestMethod.DELETE)
@RequestMapping(value = "/entityView/{entityViewId}", method = RequestMethod.DELETE)
@ResponseStatus(value = HttpStatus.OK)
public void deleteEntityView(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException {
checkParameter(ENTITY_VIEW_ID, strEntityViewId);
@ -95,4 +99,44 @@ public class EntityViewController extends BaseController {
throw handleException(e);
}
}
@PreAuthorize("hasAuthority('TENANT_ADMIN')")
@RequestMapping(value = "/tenant/entityViews", params = {"limit"}, method = RequestMethod.GET)
@ResponseBody
public TextPageData<EntityView> getTenantEntityViews(
@RequestParam int limit,
@RequestParam(required = false) String textSearch,
@RequestParam(required = false) String idOffset,
@RequestParam(required = false) String textOffset) throws ThingsboardException {
try {
TenantId tenantId = getCurrentUser().getTenantId();
TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset);
return checkNotNull(entityViewService.findEntityViewByTenantId(tenantId, pageLink));
} catch (Exception e) {
throw handleException(e);
}
}
@PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')")
@RequestMapping(value = "/entityViews", method = RequestMethod.POST)
@ResponseBody
public List<EntityView> findByQuery(@RequestBody EntityViewSearchQuery query) throws ThingsboardException {
checkNotNull(query);
checkNotNull(query.getParameters());
checkEntityId(query.getParameters().getEntityId());
try {
List<EntityView> entityViews = checkNotNull(entityViewService.findEntityViewsByQuery(query).get());
entityViews = entityViews.stream().filter(entityView -> {
try {
checkEntityView(entityView);
return true;
} catch (ThingsboardException e) {
return false;
}
}).collect(Collectors.toList());
return entityViews;
} catch (Exception e) {
throw handleException(e);
}
}
}

42
common/data/src/main/java/org/thingsboard/server/common/data/entityview/EntityViewSearchQuery.java

@ -0,0 +1,42 @@
/**
* Copyright © 2016-2018 The Thingsboard Authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.thingsboard.server.common.data.entityview;
import lombok.Data;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntityRelationsQuery;
import org.thingsboard.server.common.data.relation.EntityTypeFilter;
import org.thingsboard.server.common.data.relation.RelationsSearchParameters;
import java.util.Collections;
import java.util.List;
@Data
public class EntityViewSearchQuery {
private RelationsSearchParameters parameters;
private String relationType;
public EntityRelationsQuery toEntitySearchQuery() {
EntityRelationsQuery query = new EntityRelationsQuery();
query.setParameters(parameters);
query.setFilters(
Collections.singletonList(new EntityTypeFilter(relationType == null ? EntityRelation.CONTAINS_TYPE : relationType,
Collections.singletonList(EntityType.ENTITY_VIEW))));
return query;
}
}

2
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewDao.java

@ -16,7 +16,6 @@
package org.thingsboard.server.dao.entityview;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.Dao;
@ -92,5 +91,4 @@ public interface EntityViewDao extends Dao<EntityView> {
UUID customerId,
UUID entityId,
TextPageLink pageLink);
}

8
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewService.java

@ -16,12 +16,18 @@
package org.thingsboard.server.dao.entityview;
import com.google.common.util.concurrent.ListenableFuture;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.id.*;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import java.util.List;
/**
* Created by Victor Basanets on 8/27/2017.
*/
@ -57,4 +63,6 @@ public interface EntityViewService {
void unassignCustomerEntityViews(TenantId tenantId, CustomerId customerId);
ListenableFuture<EntityView> findEntityViewByIdAsync(EntityViewId entityViewId);
ListenableFuture<List<EntityView>> findEntityViewsByQuery(EntityViewSearchQuery query);
}

43
dao/src/main/java/org/thingsboard/server/dao/entityview/EntityViewServiceImpl.java

@ -15,6 +15,8 @@
*/
package org.thingsboard.server.dao.entityview;
import com.google.common.base.Function;
import com.google.common.util.concurrent.Futures;
import com.google.common.util.concurrent.ListenableFuture;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
@ -25,14 +27,22 @@ import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.thingsboard.server.common.data.Customer;
import org.thingsboard.server.common.data.Device;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.Tenant;
import org.thingsboard.server.common.data.device.DeviceSearchQuery;
import org.thingsboard.server.common.data.entityview.EntityViewSearchQuery;
import org.thingsboard.server.common.data.id.CustomerId;
import org.thingsboard.server.common.data.id.DeviceId;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.EntityViewId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageData;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.common.data.relation.EntityRelation;
import org.thingsboard.server.common.data.relation.EntitySearchDirection;
import org.thingsboard.server.dao.customer.CustomerDao;
import org.thingsboard.server.dao.entity.AbstractEntityService;
import org.thingsboard.server.dao.exception.DataValidationException;
@ -40,8 +50,12 @@ import org.thingsboard.server.dao.service.DataValidator;
import org.thingsboard.server.dao.service.PaginatedRemover;
import org.thingsboard.server.dao.tenant.TenantDao;
import javax.annotation.Nullable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import static org.thingsboard.server.common.data.CacheConstants.DEVICE_CACHE;
import static org.thingsboard.server.common.data.CacheConstants.ENTITY_VIEW_CACHE;
@ -55,8 +69,7 @@ import static org.thingsboard.server.dao.service.Validator.validateString;
*/
@Service
@Slf4j
public class EntityViewServiceImpl extends AbstractEntityService
implements EntityViewService {
public class EntityViewServiceImpl extends AbstractEntityService implements EntityViewService {
public static final String INCORRECT_TENANT_ID = "Incorrect tenantId ";
public static final String INCORRECT_PAGE_LINK = "Incorrect page link ";
@ -75,7 +88,7 @@ public class EntityViewServiceImpl extends AbstractEntityService
@Autowired
private CacheManager cacheManager;
@Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
// @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityViewId}")
@Override
public EntityView findEntityViewById(EntityViewId entityViewId) {
log.trace("Executing findEntityViewById [{}]", entityViewId);
@ -91,7 +104,7 @@ public class EntityViewServiceImpl extends AbstractEntityService
.orElse(null);
}
@CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityView.id}")
// @CacheEvict(cacheNames = ENTITY_VIEW_CACHE, key = "{#entityView.id}")
@Override
public EntityView saveEntityView(EntityView entityView) {
log.trace("Executing save entity view [{}]", entityView);
@ -136,7 +149,7 @@ public class EntityViewServiceImpl extends AbstractEntityService
return new TextPageData<>(entityViews, pageLink);
}
@Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #entityId, #pageLink}")
// @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #entityId, #pageLink}")
@Override
public TextPageData<EntityView> findEntityViewByTenantIdAndEntityId(TenantId tenantId, EntityId entityId,
TextPageLink pageLink) {
@ -176,7 +189,7 @@ public class EntityViewServiceImpl extends AbstractEntityService
return new TextPageData<>(entityViews, pageLink);
}
@Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #customerId, #entityId, #pageLink}")
// @Cacheable(cacheNames = ENTITY_VIEW_CACHE, key = "{#tenantId, #customerId, #entityId, #pageLink}")
@Override
public TextPageData<EntityView> findEntityViewsByTenantIdAndCustomerIdAndEntityId(TenantId tenantId,
CustomerId customerId,
@ -211,6 +224,24 @@ public class EntityViewServiceImpl extends AbstractEntityService
return entityViewDao.findByIdAsync(entityViewId.getId());
}
@Override
public ListenableFuture<List<EntityView>> findEntityViewsByQuery(EntityViewSearchQuery query) {
ListenableFuture<List<EntityRelation>> relations = relationService.findByQuery(query.toEntitySearchQuery());
ListenableFuture<List<EntityView>> entityViews = Futures.transformAsync(relations, r -> {
EntitySearchDirection direction = query.toEntitySearchQuery().getParameters().getDirection();
List<ListenableFuture<EntityView>> futures = new ArrayList<>();
for (EntityRelation relation : r) {
EntityId entityId = direction == EntitySearchDirection.FROM ? relation.getTo() : relation.getFrom();
if (entityId.getEntityType() == EntityType.ENTITY_VIEW) {
futures.add(findEntityViewByIdAsync(new EntityViewId(entityId.getId())));
}
}
return Futures.successfulAsList(futures);
});
return entityViews;
}
private DataValidator<EntityView> entityViewValidator =
new DataValidator<EntityView>() {

1
dao/src/main/java/org/thingsboard/server/dao/model/ModelConstants.java

@ -151,6 +151,7 @@ public class ModelConstants {
public static final String ENTITY_VIEW_TENANT_ID_PROPERTY = TENANT_ID_PROPERTY;
public static final String ENTITY_VIEW_CUSTOMER_ID_PROPERTY = CUSTOMER_ID_PROPERTY;
public static final String ENTITY_VIEW_NAME_PROPERTY = DEVICE_NAME_PROPERTY;
public static final String ENTITY_VIEW_TYPE_PROPERTY = DEVICE_TYPE_PROPERTY;
public static final String ENTITY_VIEW_TENANT_AND_NAME_VIEW_NAME = "entity_view_by_tenant_and_name";
public static final String ENTITY_VIEW_KEYS_PROPERTY = "keys";
public static final String ENTITY_VIEW_TS_BEGIN_PROPERTY = "ts_begin";

14
dao/src/main/java/org/thingsboard/server/dao/model/nosql/EntityViewEntity.java

@ -16,6 +16,7 @@
package org.thingsboard.server.dao.model.nosql;
import com.datastax.driver.core.utils.UUIDs;
import com.datastax.driver.mapping.annotations.Column;
import com.datastax.driver.mapping.annotations.PartitionKey;
import com.datastax.driver.mapping.annotations.Table;
import com.fasterxml.jackson.databind.JsonNode;
@ -31,10 +32,8 @@ import org.thingsboard.server.common.data.objects.TelemetryEntityView;
import org.thingsboard.server.dao.model.ModelConstants;
import org.thingsboard.server.dao.model.SearchTextEntity;
import javax.persistence.Column;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import java.io.IOException;
import java.util.UUID;
@ -55,22 +54,21 @@ public class EntityViewEntity implements SearchTextEntity<EntityView> {
@Column(name = ID_PROPERTY)
private UUID id;
@PartitionKey(value = 1)
@Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY)
private UUID entityId;
@Enumerated(EnumType.STRING)
@Column(name = ENTITY_TYPE_PROPERTY)
private EntityType entityType;
@PartitionKey(value = 2)
@PartitionKey(value = 1)
@Column(name = ModelConstants.ENTITY_VIEW_TENANT_ID_PROPERTY)
private UUID tenantId;
@PartitionKey(value = 3)
@PartitionKey(value = 2)
@Column(name = ModelConstants.ENTITY_VIEW_CUSTOMER_ID_PROPERTY)
private UUID customerId;
@Column(name = ModelConstants.ENTITY_VIEW_ENTITY_ID_PROPERTY)
private UUID entityId;
@Column(name = ModelConstants.ENTITY_VIEW_NAME_PROPERTY)
private String name;

6
dao/src/main/java/org/thingsboard/server/dao/sql/entityview/JpaEntityViewDao.java

@ -15,12 +15,16 @@
*/
package org.thingsboard.server.dao.sql.entityview;
import com.google.common.util.concurrent.ListenableFuture;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.repository.CrudRepository;
import org.springframework.stereotype.Component;
import org.thingsboard.server.common.data.EntitySubtype;
import org.thingsboard.server.common.data.EntityType;
import org.thingsboard.server.common.data.EntityView;
import org.thingsboard.server.common.data.id.EntityId;
import org.thingsboard.server.common.data.id.TenantId;
import org.thingsboard.server.common.data.page.TextPageLink;
import org.thingsboard.server.dao.DaoUtil;
import org.thingsboard.server.dao.entityview.EntityViewDao;
@ -28,6 +32,8 @@ import org.thingsboard.server.dao.model.sql.EntityViewEntity;
import org.thingsboard.server.dao.sql.JpaAbstractSearchTextDao;
import org.thingsboard.server.dao.util.SqlDao;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.Optional;

2
dao/src/main/resources/cassandra/schema.cql

@ -651,7 +651,7 @@ CREATE TABLE IF NOT EXISTS thingsboard.entity_views (
ts_end bigint,
search_text text,
additional_info text,
PRIMARY KEY (id, entity_id, tenant_id, customer_id)
PRIMARY KEY (id, tenant_id, customer_id)
);
CREATE MATERIALIZED VIEW IF NOT EXISTS thingsboard.entity_views_by_tenant_and_name AS

4
ui/src/app/api/entity-view.service.js

@ -155,6 +155,10 @@ function EntityViewService($http, $q, $window, userService, attributeService, cu
function saveEntityView(entityView) {
var deferred = $q.defer();
var url = '/api/entityView';
entityView.keys = {};
entityView.keys.timeseries = ['a', 'b'];
$http.post(url, entityView).then(function success(response) {
deferred.resolve(response.data);
}, function fail() {

2
ui/src/app/common/types.constant.js

@ -328,7 +328,7 @@ export default angular.module('thingsboard.types', [])
alarm: "ALARM",
rulechain: "RULE_CHAIN",
rulenode: "RULE_NODE",
entityview: "ENTITY_VIEW"
entityView: "ENTITY_VIEW"
},
aliasEntityType: {
current_customer: "CURRENT_CUSTOMER"

10
ui/src/app/entity-view/entity-view-fieldset.tpl.html

@ -15,6 +15,9 @@
limitations under the License.
-->
<md-button ng-click="onMakePublic({event: $event})"
ng-show="!isEdit && entityViewScope === 'tenant' && !isAssignedToCustomer && !isPublic"
class="md-raised md-primary">{{ 'entity-view.make-public' | translate }}</md-button>
<md-button ng-click="onAssignToCustomer({event: $event})"
ng-show="!isEdit && entityViewScope === 'tenant' && !isAssignedToCustomer"
class="md-raised md-primary">{{ 'entity-view.assign-to-customer' | translate }}</md-button>
@ -49,13 +52,6 @@
<div translate ng-message="required">entity-view.name-required</div>
</div>
</md-input-container>
<tb-entity-subtype-autocomplete
ng-disabled="$root.loading || !isEdit"
tb-required="true"
the-form="theForm"
ng-model="entityView.type"
entity-type="types.entityType.entityview">
</tb-entity-subtype-autocomplete>
<md-input-container class="md-block">
<label translate>entity-view.description</label>
<textarea ng-model="entityView.additionalInfo.description" rows="2"></textarea>

12
ui/src/app/entity-view/entity-view.controller.js

@ -194,7 +194,7 @@ export function EntityViewController($rootScope, userService, entityViewService,
entityViewGroupActionsList.push(
{
onAction: function ($event, items) {
assignEntiyViewsToCustomer($event, items);
assignEntityViewsToCustomer($event, items);
},
name: function() { return $translate.instant('entity-view.assign-entity-views') },
details: function(selectedCount) {
@ -221,10 +221,10 @@ export function EntityViewController($rootScope, userService, entityViewService,
fetchEntityViewsFunction = function (pageLink, entityViewType) {
return entityViewService.getCustomerEntityViews(customerId, pageLink, true, null, entityViewType);
};
deleteentityViewFunction = function (entityViewId) {
deleteEntityViewFunction = function (entityViewId) {
return entityViewService.unassignEntityViewFromCustomer(entityViewId);
};
refreshentityViewsParamsFunction = function () {
refreshEntityViewsParamsFunction = function () {
return {"customerId": customerId, "topIndex": vm.topIndex};
};
@ -271,9 +271,9 @@ export function EntityViewController($rootScope, userService, entityViewService,
}
}
vm.entityViewGridConfig.refreshParamsFunc = refreshentityViewsParamsFunction;
vm.entityViewGridConfig.fetchItemsFunc = fetchentityViewsFunction;
vm.entityViewGridConfig.deleteItemFunc = deleteentityViewFunction;
vm.entityViewGridConfig.refreshParamsFunc = refreshEntityViewsParamsFunction;
vm.entityViewGridConfig.fetchItemsFunc = fetchEntityViewsFunction;
vm.entityViewGridConfig.deleteItemFunc = deleteEntityViewFunction;
}

4
ui/src/app/entity-view/entity-view.directive.js

@ -27,6 +27,7 @@ export default function EntityViewDirective($compile, $templateCache, toast, $tr
scope.types = types;
scope.isAssignedToCustomer = false;
scope.isPublic = false;
scope.assignedCustomer = null;
scope.$watch('entityView', function(newVal) {
@ -36,10 +37,12 @@ export default function EntityViewDirective($compile, $templateCache, toast, $tr
customerService.getShortCustomerInfo(scope.entityView.customerId.id).then(
function success(customer) {
scope.assignedCustomer = customer;
scope.isPublic = customer.isPublic;
}
);
} else {
scope.isAssignedToCustomer = false;
scope.isPublic = false;
scope.assignedCustomer = null;
}
}
@ -60,6 +63,7 @@ export default function EntityViewDirective($compile, $templateCache, toast, $tr
entityViewScope: '=',
theForm: '=',
onAssignToCustomer: '&',
onMakePublic: '&',
onUnassignFromCustomer: '&',
onDeleteEntityView: '&'
}

10
ui/src/app/entity-view/entity-view.routes.js

@ -35,14 +35,14 @@ export default function EntityViewRoutes($stateProvider, types) {
}
},
data: {
entityViewsTypes: 'tenant',
entityViewsType: 'tenant',
searchEnabled: true,
searchByEntitySubtype: true,
searchEntityType: types.entityType.entityview,
pageTitle: 'entity-views.entity-views'
pageTitle: 'entity-view.entity-views'
},
ncyBreadcrumb: {
label: '{"icon": "devices_other", "label": "entity-view.entity-views"}'
label: '{"icon": "view_stream", "label": "entity-view.entity-views"}'
}
})
.state('home.customers.entityViews', {
@ -58,14 +58,14 @@ export default function EntityViewRoutes($stateProvider, types) {
}
},
data: {
entityViewsTypes: 'customer',
entityViewsType: 'customer',
searchEnabled: true,
searchByEntitySubtype: true,
searchEntityType: types.entityType.entityview,
pageTitle: 'customer.entity-views'
},
ncyBreadcrumb: {
label: '{"icon": "devices_other", "label": "{{ vm.customerEntityViewsTitle }}", "translate": "false"}'
label: '{"icon": "view_stream", "label": "{{ vm.customerEntityViewsTitle }}", "translate": "false"}'
}
});

20
ui/src/app/entity-view/entity-views.tpl.html

@ -29,13 +29,12 @@
on-assign-to-customer="vm.assignToCustomer(event, [ vm.grid.detailsConfig.currentItem.id.id ])"
on-make-public="vm.makePublic(event, vm.grid.detailsConfig.currentItem)"
on-unassign-from-customer="vm.unassignFromCustomer(event, vm.grid.detailsConfig.currentItem, isPublic)"
on-manage-credentials="vm.manageCredentials(event, vm.grid.detailsConfig.currentItem)"
on-delete-entity-view="vm.grid.deleteItem(event, vm.grid.detailsConfig.currentItem)"></tb-entity-view>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.attributes' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.entityview}}"
entity-type="{{vm.types.entityType.entityView}}"
entity-name="vm.grid.operatingItem().name"
default-attribute-scope="{{vm.types.attributesScope.client.value}}">
</tb-attribute-table>
@ -43,19 +42,19 @@
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'attribute.latest-telemetry' | translate }}">
<tb-attribute-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.entityview}}"
entity-type="{{vm.types.entityType.entityView}}"
entity-name="vm.grid.operatingItem().name"
default-attribute-scope="{{vm.types.latestTelemetry.value}}"
disable-attribute-scope-selection="true">
</tb-attribute-table>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'alarm.alarms' | translate }}">
<tb-alarm-table flex entity-type="vm.types.entityType.entityview"
<tb-alarm-table flex entity-type="vm.types.entityType.entityView"
entity-id="vm.grid.operatingItem().id.id">
</tb-alarm-table>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'entity-view.events' | translate }}">
<tb-event-table flex entity-type="vm.types.entityType.entityview"
<tb-event-table flex entity-type="vm.types.entityType.entityView"
entity-id="vm.grid.operatingItem().id.id"
tenant-id="vm.grid.operatingItem().tenantId.id"
default-event-type="{{vm.types.eventType.error.value}}">
@ -64,18 +63,11 @@
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode" md-on-select="vm.grid.triggerResize()" label="{{ 'relation.relations' | translate }}">
<tb-relation-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-type="{{vm.types.entityType.entityview}}">
entity-type="{{vm.types.entityType.entityView}}">
</tb-relation-table>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.grid.operatingItem().additionalInfo.gateway" md-on-select="vm.grid.triggerResize()" label="{{ 'extension.extensions' | translate }}">
<tb-extension-table flex
entity-id="vm.grid.operatingItem().id.id"
entity-name="vm.grid.operatingItem().name"
entity-type="{{vm.types.entityType.entityview}}">
</tb-extension-table>
</md-tab>
<md-tab ng-if="!vm.grid.detailsConfig.isDetailsEditMode && vm.grid.isTenantAdmin()" md-on-select="vm.grid.triggerResize()" label="{{ 'audit-log.audit-logs' | translate }}">
<tb-audit-log-table flex entity-type="vm.types.entityType.entityview"
<tb-audit-log-table flex entity-type="vm.types.entityType.entityView"
entity-id="vm.grid.operatingItem().id.id"
audit-log-mode="{{vm.types.auditLogMode.entity}}">
</tb-audit-log-table>

4
ui/src/app/entity-view/index.js

@ -20,7 +20,7 @@ import thingsboardApiEntityView from '../api/entity-view.service';
import thingsboardApiCustomer from '../api/customer.service';
import EntityViewRoutes from './entity-view.routes';
import EntityViewCardController from './entity-view.controller';
import {EntityViewController, EntityViewCardController} from './entity-view.controller';
import AssignEntityViewToCustomerController from './assign-to-customer.controller';
import AddEntityViewsToCustomerController from './add-entity-views-to-customer.controller';
import EntityViewDirective from './entity-view.directive';
@ -33,7 +33,7 @@ export default angular.module('thingsboard.entityView', [
thingsboardApiCustomer
])
.config(EntityViewRoutes)
.controller('EntityViewController', EntityViewCardController)
.controller('EntityViewController', EntityViewController)
.controller('EntityViewCardController', EntityViewCardController)
.controller('AssignEntityViewToCustomerController', AssignEntityViewToCustomerController)
.controller('AddEntityViewsToCustomerController', AddEntityViewsToCustomerController)

2
ui/src/app/layout/index.js

@ -48,6 +48,7 @@ import thingsboardAdmin from '../admin';
import thingsboardProfile from '../profile';
import thingsboardAsset from '../asset';
import thingsboardDevice from '../device';
import thingsboardEntityView from '../entity-view';
import thingsboardWidgetLibrary from '../widget';
import thingsboardDashboard from '../dashboard';
import thingsboardRuleChain from '../rulechain';
@ -79,6 +80,7 @@ export default angular.module('thingsboard.home', [
thingsboardProfile,
thingsboardAsset,
thingsboardDevice,
thingsboardEntityView,
thingsboardWidgetLibrary,
thingsboardDashboard,
thingsboardRuleChain,

3
ui/src/app/locale/locale.constant-en_US.json

@ -821,7 +821,8 @@
"assignedToCustomer": "Assigned to customer",
"unable-entity-view-device-alias-title": "Unable to delete entity view alias",
"unable-entity-view-device-alias-text": "Device alias '{{entityViewAlias}}' can't be deleted as it used by the following widget(s):<br/>{{widgetsList}}",
"select-entity-view": "Select entity view"
"select-entity-view": "Select entity view",
"make-public": "Make entity view public"
},
"event": {
"event-type": "Event type",

52
ui/src/app/services/menu.service.js

@ -167,6 +167,12 @@ function Menu(userService, $state, $rootScope) {
state: 'home.devices',
icon: 'devices_other'
},
{
name: 'entity-view.entity-views',
type: 'link',
state: 'home.entityViews',
icon: 'view_stream'
},
{
name: 'widget.widget-library',
type: 'link',
@ -227,6 +233,16 @@ function Menu(userService, $state, $rootScope) {
}
]
},
{
name: 'entity-view.management',
places: [
{
name: 'entity-view.entity-views',
icon: 'view_stream',
state: 'home.entityViews'
}
]
},
{
name: 'dashboard.management',
places: [
@ -273,6 +289,12 @@ function Menu(userService, $state, $rootScope) {
state: 'home.devices',
icon: 'devices_other'
},
{
name: 'entity-view.entity-views',
type: 'link',
state: 'home.entityViews',
icon: 'view_stream'
},
{
name: 'dashboard.dashboards',
type: 'link',
@ -301,16 +323,26 @@ function Menu(userService, $state, $rootScope) {
}
]
},
{
name: 'dashboard.view-dashboards',
places: [
{
name: 'dashboard.dashboards',
icon: 'dashboard',
state: 'home.dashboards'
}
]
}];
{
name: 'entity-view.management',
places: [
{
name: 'entity-view.entity-views',
icon: 'view_stream',
state: 'home.entityViews'
}
]
},
{
name: 'dashboard.view-dashboards',
places: [
{
name: 'dashboard.dashboards',
icon: 'dashboard',
state: 'home.dashboards'
}
]
}];
}
}
}

Loading…
Cancel
Save