From 06a0941dbea59cb975f6f62215e34fd38eb9be07 Mon Sep 17 00:00:00 2001 From: Volodymyr Babak Date: Mon, 10 Sep 2018 14:37:46 +0300 Subject: [PATCH] Entity view misc fixes --- .../controller/EntityViewController.java | 84 +++++++++++++++++++ .../entity-view/entity-view-fieldset.tpl.html | 24 ++++++ .../app/entity-view/entity-view.directive.js | 36 +++++++- ui/src/app/entity-view/entity-view.routes.js | 4 +- ui/src/app/locale/locale.constant-en_US.json | 4 +- 5 files changed, 148 insertions(+), 4 deletions(-) diff --git a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java index 227bed01f3..b5adc327f5 100644 --- a/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java +++ b/application/src/main/java/org/thingsboard/server/controller/EntityViewController.java @@ -19,16 +19,22 @@ 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.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.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.DeviceId; 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.dao.exception.IncorrectParameterException; +import org.thingsboard.server.dao.model.ModelConstants; import org.thingsboard.server.service.security.model.SecurityUser; import java.util.ArrayList; @@ -100,6 +106,84 @@ public class EntityViewController extends BaseController { } } + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/customer/{customerId}/entityView/{entityViewId}", method = RequestMethod.POST) + @ResponseBody + public EntityView assignEntityViewToCustomer(@PathVariable("customerId") String strCustomerId, + @PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { + checkParameter("customerId", strCustomerId); + checkParameter(ENTITY_VIEW_ID, strEntityViewId); + try { + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); + Customer customer = checkCustomerId(customerId); + + EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); + checkEntityViewId(entityViewId); + + EntityView savedEntityView = checkNotNull(entityViewService.assignEntityViewToCustomer(entityViewId, customerId)); + + logEntityAction(entityViewId, savedEntityView, + savedEntityView.getCustomerId(), + ActionType.ASSIGNED_TO_CUSTOMER, null, strEntityViewId, strCustomerId, customer.getName()); + + return savedEntityView; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, + null, + ActionType.ASSIGNED_TO_CUSTOMER, e, strEntityViewId, strCustomerId); + throw handleException(e); + } + } + + @PreAuthorize("hasAuthority('TENANT_ADMIN')") + @RequestMapping(value = "/customer/entityView/{entityViewId}", method = RequestMethod.DELETE) + @ResponseBody + public EntityView unassignEntityViewFromCustomer(@PathVariable(ENTITY_VIEW_ID) String strEntityViewId) throws ThingsboardException { + checkParameter(ENTITY_VIEW_ID, strEntityViewId); + try { + EntityViewId entityViewId = new EntityViewId(toUUID(strEntityViewId)); + EntityView entityView = checkEntityViewId(entityViewId); + if (entityView.getCustomerId() == null || entityView.getCustomerId().getId().equals(ModelConstants.NULL_UUID)) { + throw new IncorrectParameterException("Entity View isn't assigned to any customer!"); + } + Customer customer = checkCustomerId(entityView.getCustomerId()); + + EntityView savedEntityView = checkNotNull(entityViewService.unassignEntityViewFromCustomer(entityViewId)); + + logEntityAction(entityViewId, entityView, + entityView.getCustomerId(), + ActionType.UNASSIGNED_FROM_CUSTOMER, null, strEntityViewId, customer.getId().toString(), customer.getName()); + + return savedEntityView; + } catch (Exception e) { + logEntityAction(emptyId(EntityType.ENTITY_VIEW), null, + null, + ActionType.UNASSIGNED_FROM_CUSTOMER, e, strEntityViewId); + throw handleException(e); + } + } + + @PreAuthorize("hasAnyAuthority('TENANT_ADMIN', 'CUSTOMER_USER')") + @RequestMapping(value = "/customer/{customerId}/entityViews", params = {"limit"}, method = RequestMethod.GET) + @ResponseBody + public TextPageData getCustomerEntityViews( + @PathVariable("customerId") String strCustomerId, + @RequestParam int limit, + @RequestParam(required = false) String textSearch, + @RequestParam(required = false) String idOffset, + @RequestParam(required = false) String textOffset) throws ThingsboardException { + checkParameter("customerId", strCustomerId); + try { + TenantId tenantId = getCurrentUser().getTenantId(); + CustomerId customerId = new CustomerId(toUUID(strCustomerId)); + checkCustomerId(customerId); + TextPageLink pageLink = createPageLink(limit, textSearch, idOffset, textOffset); + return checkNotNull(entityViewService.findEntityViewsByTenantIdAndCustomerId(tenantId, customerId, pageLink)); + } catch (Exception e) { + throw handleException(e); + } + } + @PreAuthorize("hasAuthority('TENANT_ADMIN')") @RequestMapping(value = "/tenant/entityViews", params = {"limit"}, method = RequestMethod.GET) @ResponseBody diff --git a/ui/src/app/entity-view/entity-view-fieldset.tpl.html b/ui/src/app/entity-view/entity-view-fieldset.tpl.html index cb46f3ddf7..c73b0a2493 100644 --- a/ui/src/app/entity-view/entity-view-fieldset.tpl.html +++ b/ui/src/app/entity-view/entity-view-fieldset.tpl.html @@ -52,9 +52,33 @@
entity-view.name-required
+ + +
+ + +
+
+ + +
diff --git a/ui/src/app/entity-view/entity-view.directive.js b/ui/src/app/entity-view/entity-view.directive.js index 5a3d8765a3..b07d4372fb 100644 --- a/ui/src/app/entity-view/entity-view.directive.js +++ b/ui/src/app/entity-view/entity-view.directive.js @@ -20,7 +20,7 @@ import entityViewFieldsetTemplate from './entity-view-fieldset.tpl.html'; /* eslint-enable import/no-unresolved, import/default */ /*@ngInject*/ -export default function EntityViewDirective($compile, $templateCache, toast, $translate, types, clipboardService, entityViewService, customerService) { +export default function EntityViewDirective($compile, $templateCache, $filter, toast, $translate, types, clipboardService, entityViewService, customerService) { var linker = function (scope, element) { var template = $templateCache.get(entityViewFieldsetTemplate); element.html(template); @@ -30,6 +30,8 @@ export default function EntityViewDirective($compile, $templateCache, toast, $tr scope.isPublic = false; scope.assignedCustomer = null; + scope.allowedEntityTypes = [types.entityType.device, types.entityType.asset]; + scope.$watch('entityView', function(newVal) { if (newVal) { if (scope.entityView.customerId && scope.entityView.customerId.id !== types.id.nullUid) { @@ -45,9 +47,41 @@ export default function EntityViewDirective($compile, $templateCache, toast, $tr scope.isPublic = false; scope.assignedCustomer = null; } + scope.startTs = $filter('date')(scope.entityView.endTs, 'yyyy-MM-dd HH:mm:ss'); + scope.endTs = $filter('date')(scope.entityView.startTs, 'yyyy-MM-dd HH:mm:ss'); } }); + + scope.$watch('startTs', function (newDate) { + if (newDate) { + if (newDate.getTime() > scope.maxStartTs) { + scope.startTs = angular.copy(scope.maxStartTs); + } + updateMinMaxDates(); + } + }); + + scope.$watch('endTs', function (newDate) { + if (newDate) { + if (newDate.getTime() < scope.minEndTs) { + scope.endTs = angular.copy(scope.minEndTs); + } + updateMinMaxDates(); + } + }); + + function updateMinMaxDates() { + if (scope.endTs) { + scope.maxStartTs = angular.copy(new Date(scope.endTs.getTime() - 1000)); + scope.entityView.endTs = $filter('date')(scope.endTs, 'yyyy-MM-dd HH:mm:ss'); + } + if (scope.startTs) { + scope.minEndTs = angular.copy(new Date(scope.startTs.getTime() + 1000)); + scope.entityView.startTs = $filter('date')(scope.startTs, 'yyyy-MM-dd HH:mm:ss'); + } + } + scope.onEntityViewIdCopied = function() { toast.showSuccess($translate.instant('entity-view.idCopiedMessage'), 750, angular.element(element).parent().parent(), 'bottom left'); }; diff --git a/ui/src/app/entity-view/entity-view.routes.js b/ui/src/app/entity-view/entity-view.routes.js index 481dfc8f90..c14d430f32 100644 --- a/ui/src/app/entity-view/entity-view.routes.js +++ b/ui/src/app/entity-view/entity-view.routes.js @@ -38,7 +38,7 @@ export default function EntityViewRoutes($stateProvider, types) { entityViewsType: 'tenant', searchEnabled: true, searchByEntitySubtype: true, - searchEntityType: types.entityType.entityview, + searchEntityType: types.entityType.entityView, pageTitle: 'entity-view.entity-views' }, ncyBreadcrumb: { @@ -61,7 +61,7 @@ export default function EntityViewRoutes($stateProvider, types) { entityViewsType: 'customer', searchEnabled: true, searchByEntitySubtype: true, - searchEntityType: types.entityType.entityview, + searchEntityType: types.entityType.entityView, pageTitle: 'customer.entity-views' }, ncyBreadcrumb: { diff --git a/ui/src/app/locale/locale.constant-en_US.json b/ui/src/app/locale/locale.constant-en_US.json index 09769edc47..e98d4fe1ca 100644 --- a/ui/src/app/locale/locale.constant-en_US.json +++ b/ui/src/app/locale/locale.constant-en_US.json @@ -822,7 +822,9 @@ "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):
{{widgetsList}}", "select-entity-view": "Select entity view", - "make-public": "Make entity view public" + "make-public": "Make entity view public", + "start-ts": "Start ts", + "end-ts": "End ts" }, "event": { "event-type": "Event type",