diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllerhandler/GlobalExceptionHandler.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllerhandler/GlobalExceptionHandler.java index 5e7763b30..ebefb8eff 100644 --- a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllerhandler/GlobalExceptionHandler.java +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllerhandler/GlobalExceptionHandler.java @@ -150,7 +150,7 @@ public class GlobalExceptionHandler { Map.entry("error", "System error") ); } - }; + } String serialization = this.jsonHandlingService.toJsonSafe(result); return new HandledException(statusCode, serialization, logLevel); } diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java index 83b503d4e..a318ad8e2 100644 --- a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/AnnotationController.java @@ -72,7 +72,7 @@ public class AnnotationController { this.censorFactory.censor(AnnotationCensor.class).censor(lookup.getProject(), null); - AnnotationQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermissionAssociated); + AnnotationQuery query = lookup.enrich(this.queryFactory).disableTracking().authorize(AuthorizationFlags.OwnerOrPermissionAssociated); List data = query.collect(); List models = this.builderFactory.builder(AnnotationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermissionAssociated).build(lookup.getProject(), data); long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); @@ -88,7 +88,7 @@ public class AnnotationController { this.censorFactory.censor(AnnotationCensor.class).censor(fieldSet, null); - AnnotationQuery query = this.queryFactory.query(AnnotationQuery.class).authorize(AuthorizationFlags.OwnerOrPermissionAssociated).ids(id); + AnnotationQuery query = this.queryFactory.query(AnnotationQuery.class).disableTracking().authorize(AuthorizationFlags.OwnerOrPermissionAssociated).ids(id); Annotation model = this.builderFactory.builder(AnnotationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermissionAssociated).build(fieldSet, query.firstAs(fieldSet)); if (model == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, Annotation.class.getSimpleName()}, LocaleContextHolder.getLocale())); diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/PrincipalController.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/PrincipalController.java index 922506475..4850e8641 100644 --- a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/PrincipalController.java +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/controllers/PrincipalController.java @@ -30,18 +30,15 @@ public class PrincipalController { private final CurrentPrincipalResolver currentPrincipalResolver; private final AccountBuilder accountBuilder; - private final ClaimExtractor claimExtractor; @Autowired public PrincipalController( CurrentPrincipalResolver currentPrincipalResolver, AccountBuilder accountBuilder, - AuditService auditService, - ClaimExtractor claimExtractor) { + AuditService auditService) { this.currentPrincipalResolver = currentPrincipalResolver; this.accountBuilder = accountBuilder; this.auditService = auditService; - this.claimExtractor = claimExtractor; } @GetMapping("me") @@ -76,17 +73,4 @@ public class PrincipalController { } - @GetMapping("my-tenants") - public List myTenants() { - logger.debug("my-tenants"); - - MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal(); - List tenants = this.claimExtractor.asStrings(principal, ClaimNames.TenantCodesClaimName); - - this.auditService.track(AuditableAction.Tenants_Lookup); - //auditService.trackIdentity(AuditableAction.IdentityTracking_Action); - - return tenants == null ? null : tenants.stream().distinct().collect(Collectors.toList()); - } - } diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/tenant/TenantInterceptor.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/tenant/TenantInterceptor.java index ad0c8d8de..70dc50be4 100644 --- a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/tenant/TenantInterceptor.java +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/tenant/TenantInterceptor.java @@ -6,6 +6,7 @@ import gr.cite.annotation.authorization.Permission; import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.tenant.TenantScope; import gr.cite.annotation.common.scope.user.UserScope; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.data.TenantUserEntity; import gr.cite.annotation.data.UserEntity; import gr.cite.annotation.data.tenant.TenantScopedBaseEntity; @@ -52,6 +53,7 @@ public class TenantInterceptor implements WebRequestInterceptor { private final UserAllowedTenantCacheService userAllowedTenantCacheService; private final ErrorThesaurusProperties errors; private final QueryUtilsService queryUtilsService; + public final TenantEntityManager tenantEntityManager; @PersistenceContext public EntityManager entityManager; @@ -64,7 +66,7 @@ public class TenantInterceptor implements WebRequestInterceptor { ApplicationContext applicationContext, TenantScopeProperties tenantScopeProperties, UserAllowedTenantCacheService userAllowedTenantCacheService, - ErrorThesaurusProperties errors, QueryUtilsService queryUtilsService) { + ErrorThesaurusProperties errors, QueryUtilsService queryUtilsService, TenantEntityManager tenantEntityManager) { this.tenantScope = tenantScope; this.userScope = userScope; this.currentPrincipalResolver = currentPrincipalResolver; @@ -74,6 +76,7 @@ public class TenantInterceptor implements WebRequestInterceptor { this.userAllowedTenantCacheService = userAllowedTenantCacheService; this.errors = errors; this.queryUtilsService = queryUtilsService; + this.tenantEntityManager = tenantEntityManager; } @Override @@ -103,16 +106,7 @@ public class TenantInterceptor implements WebRequestInterceptor { } if (isUserAllowedTenant) { - if(!tenantScope.isDefaultTenant()) { - this.entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) - .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); - } else { - this.entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - } + this.tenantEntityManager.reloadTenantFilters(); } else { if (isAllowedNoTenant || this.isWhiteListedEndpoint(request)) { tenantScope.setTenant(null, null); @@ -181,8 +175,8 @@ public class TenantInterceptor implements WebRequestInterceptor { @Override public void postHandle(@NonNull WebRequest request, ModelMap model) { this.tenantScope.setTenant(null, null); + this.tenantEntityManager.disableTenantFilters(); } - @Override public void afterCompletion(@NonNull WebRequest request, Exception ex) { } diff --git a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/user/UserInterceptor.java b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/user/UserInterceptor.java index 8bf390cad..36e86189d 100644 --- a/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/user/UserInterceptor.java +++ b/annotation-service/annotation-web/src/main/java/gr/cite/annotation/web/scope/user/UserInterceptor.java @@ -63,7 +63,7 @@ public class UserInterceptor implements WebRequestInterceptor { this.userScope.setUserId(userId); } private UUID findExistingUserFromDb(String subjectId) { - UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).externalIds(subjectId).firstAs(new BaseFieldSet().ensure(UserCredential._user)); + UserCredentialEntity userCredential = this.queryFactory.query(UserCredentialQuery.class).disableTracking().externalIds(subjectId).firstAs(new BaseFieldSet().ensure(UserCredential._user)); if (userCredential != null) { return userCredential.getUserId(); } diff --git a/annotation-service/annotation/pom.xml b/annotation-service/annotation/pom.xml index 635a3927d..b596dc8cd 100644 --- a/annotation-service/annotation/pom.xml +++ b/annotation-service/annotation/pom.xml @@ -52,7 +52,7 @@ gr.cite data-tools - 2.1.2 + 2.1.4 gr.cite @@ -77,7 +77,7 @@ gr.cite exceptions - 1.0.0 + 2.1.0 gr.cite @@ -93,7 +93,7 @@ gr.cite cipher - 1.0.0 + 2.1.0 compile diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java index f1a4d68e8..67b6eed97 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/authorization/authorizationcontentresolver/AuthorizationContentResolverImpl.java @@ -48,7 +48,7 @@ public class AuthorizationContentResolverImpl implements AuthorizationContentRes List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, AnnotationEntity._entityId); if (idsToResolve.isEmpty()) return affiliatedResources; - List entityUsers = this.queryFactory.query(EntityUserQuery.class).entityIds(ids).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); + List entityUsers = this.queryFactory.query(EntityUserQuery.class).disableTracking().entityIds(ids).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); for (UUID entityId : entityUsers.stream().map(EntityUserEntity::getEntityId).distinct().toList()){ affiliatedResources.get(entityId).setAffiliated(true); @@ -79,8 +79,8 @@ public class AuthorizationContentResolverImpl implements AuthorizationContentRes List idsToResolve = this.getAffiliatedFromCache(ids, userId, affiliatedResources, AnnotationEntity.class.getSimpleName()); if (idsToResolve.isEmpty()) return affiliatedResources; - List annotationEntities = this.queryFactory.query(AnnotationQuery.class).ids(ids).collectAs(new BaseFieldSet().ensure(Annotation._id).ensure(Annotation._entityId).ensure(Annotation._id)); - List entityUsers = this.queryFactory.query(EntityUserQuery.class).entityIds(annotationEntities.stream().map(AnnotationEntity::getEntityId).distinct().toList()).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); + List annotationEntities = this.queryFactory.query(AnnotationQuery.class).disableTracking().ids(ids).collectAs(new BaseFieldSet().ensure(Annotation._id).ensure(Annotation._entityId).ensure(Annotation._id)); + List entityUsers = this.queryFactory.query(EntityUserQuery.class).disableTracking().entityIds(annotationEntities.stream().map(AnnotationEntity::getEntityId).distinct().toList()).userIds(userId).isActive(IsActive.Active).collectAs(new BaseFieldSet().ensure(EntityUser._id).ensure(EntityUser._entityId)); Map> dmpUsersMap = entityUsers.stream().collect(Collectors.groupingBy(EntityUserEntity::getEntityId)); for (AnnotationEntity annotation : annotationEntities){ diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/XmlHandlingService.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/XmlHandlingService.java index 89fdc44f9..71ece3a73 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/XmlHandlingService.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/XmlHandlingService.java @@ -70,7 +70,7 @@ public class XmlHandlingService { public T fromXml(Class type, String xmlString) throws JAXBException, InstantiationException, IllegalAccessException, ParserConfigurationException, IOException, SAXException { if (XmlSerializable.class.isAssignableFrom(type)){ XmlSerializable object = (XmlSerializable)type.newInstance(); - return (T) object.fromXml(this.getDocument(xmlString).getDocumentElement()); + return object.fromXml(this.getDocument(xmlString).getDocumentElement()); } else { JAXBContext jaxbContext = JAXBContext.newInstance(type); Unmarshaller jaxbUnmarshaller = jaxbContext.createUnmarshaller(); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/lock/LockByKeyManager.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/lock/LockByKeyManager.java index 038923309..5976e526b 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/lock/LockByKeyManager.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/lock/LockByKeyManager.java @@ -25,7 +25,7 @@ public class LockByKeyManager { } - private static ConcurrentHashMap locks = new ConcurrentHashMap(); + private static final ConcurrentHashMap locks = new ConcurrentHashMap(); public void lock(String key) { LockWrapper lockWrapper = locks.compute(key, (k, v) -> v == null ? new LockWrapper() : v.addThreadInQueue()); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/fake/FakeRequestAttributes.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/fake/FakeRequestAttributes.java index 62390b7d6..51fb71fff 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/fake/FakeRequestAttributes.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/fake/FakeRequestAttributes.java @@ -8,7 +8,7 @@ import java.util.LinkedHashMap; import java.util.Map; public class FakeRequestAttributes implements RequestAttributes { - private Map requestAttributeMap = new HashMap<>(); + private final Map requestAttributeMap = new HashMap<>(); private final Map requestDestructionCallbacks = new LinkedHashMap<>(8); private volatile boolean requestActive = true; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/tenant/TenantScope.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/tenant/TenantScope.java index ed39ac7a5..f91403fc3 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/tenant/TenantScope.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/scope/tenant/TenantScope.java @@ -1,5 +1,6 @@ package gr.cite.annotation.common.scope.tenant; +import gr.cite.annotation.data.TenantEntityManager; import gr.cite.annotation.data.tenant.TenantScopedBaseEntity; import jakarta.persistence.EntityManager; import org.hibernate.Session; @@ -27,11 +28,11 @@ public class TenantScope { } public Boolean isMultitenant() { - return multitenancy.isMultitenant(); + return this.multitenancy.isMultitenant(); } public String getDefaultTenantCode() { - return multitenancy.getDefaultTenantCode(); + return this.multitenancy.getDefaultTenantCode(); } public Boolean isSet() { @@ -62,55 +63,18 @@ public class TenantScope { return this.tenantCode.get(); } - public void setTempTenant(EntityManager entityManager, UUID tenant, String tenantCode) { + public void setTempTenant(TenantEntityManager entityManager, UUID tenant, String tenantCode) throws InvalidApplicationException { this.tenant.set(tenant); this.tenantCode.set(tenantCode); - entityManager - .unwrap(Session.class) - .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); - - entityManager - .unwrap(Session.class) - .disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - if (this.tenant.get() != null || this.isDefaultTenant()) { - if(!this.isDefaultTenant()) { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) - .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); - } else { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - } - } + entityManager.reloadTenantFilters(); } - public void removeTempTenant(EntityManager entityManager) { + public void removeTempTenant(TenantEntityManager entityManager) throws InvalidApplicationException { this.tenant.set(this.initialTenant.get()); this.tenantCode.set(this.initialTenantCode.get()); - - entityManager - .unwrap(Session.class) - .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); - - entityManager - .unwrap(Session.class) - .disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - if (this.initialTenant.get() != null || this.isDefaultTenant()) { - if(!this.isDefaultTenant()) { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) - .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenant.get().toString()); - } else { - entityManager - .unwrap(Session.class) - .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - } - } + entityManager.reloadTenantFilters(); } public void setTenant(UUID tenant, String tenantCode) { @@ -122,6 +86,3 @@ public class TenantScope { } } } - - - diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/validation/UuidValidator.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/validation/UuidValidator.java index 8d8ab1008..ffc1a90a1 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/validation/UuidValidator.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/validation/UuidValidator.java @@ -10,6 +10,7 @@ import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Component; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.UUID; @@ -33,10 +34,10 @@ public class UuidValidator extends BaseValidator { @Override protected List specifications(UUID item) { - return Arrays.asList( - this.spec() - .must(() -> this.isValidGuid(item)) - .failOn("uuid").failWith(messageSource.getMessage("Validation_Required", new Object[]{"uuid"}, LocaleContextHolder.getLocale())) + return Collections.singletonList( + this.spec() + .must(() -> this.isValidGuid(item)) + .failOn("uuid").failWith(messageSource.getMessage("Validation_Required", new Object[]{"uuid"}, LocaleContextHolder.getLocale())) ); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java index 31f73207c..f0cf76365 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/TenantEntityManager.java @@ -33,9 +33,9 @@ public class TenantEntityManager { } public T merge(T entity) throws InvalidApplicationException { - if (tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { - if (!tenantScope.isDefaultTenant()) { - if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); + if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { + if (!this.tenantScope.isDefaultTenant()) { + if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); } else if (tenantScopedEntity.getTenantId() != null) { throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); } @@ -44,9 +44,9 @@ public class TenantEntityManager { } public void remove(Object entity) throws InvalidApplicationException { - if (tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { - if (!tenantScope.isDefaultTenant()) { - if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); + if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { + if (!this.tenantScope.isDefaultTenant()) { + if (tenantScopedEntity.getTenantId() == null || !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); } else if (tenantScopedEntity.getTenantId() != null) { throw new MyForbiddenException(this.errors.getTenantTampering().getCode(), this.errors.getTenantTampering().getMessage()); } @@ -57,12 +57,22 @@ public class TenantEntityManager { public T find(Class entityClass, Object primaryKey) throws InvalidApplicationException { T entity = this.entityManager.find(entityClass, primaryKey); - if (tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { - if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(tenantScope.getTenant())) return null; + if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { + if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null; } return entity; } + public T find(Class entityClass, Object primaryKey, boolean disableTracking) throws InvalidApplicationException { + T entity = this.entityManager.find(entityClass, primaryKey); + + if (this.tenantScope.isMultitenant() && (entity instanceof TenantScoped tenantScopedEntity)) { + if (tenantScopedEntity.getTenantId() != null && !tenantScopedEntity.getTenantId().equals(this.tenantScope.getTenant())) return null; + } + if (disableTracking) this.entityManager.detach(entity); + return entity; + } + public void flush() { this.entityManager.flush(); } @@ -80,14 +90,17 @@ public class TenantEntityManager { public void clear() { this.entityManager.clear(); } - - public void enableTenantFilters() throws InvalidApplicationException { - if (!tenantScope.isSet()) return; - if(!tenantScope.isDefaultTenant()) { + + public void reloadTenantFilters() throws InvalidApplicationException { + this.disableTenantFilters(); + + if (!this.tenantScope.isSet()) return; + + if (!this.tenantScope.isDefaultTenant()) { this.entityManager .unwrap(Session.class) .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) - .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenantScope.getTenant().toString()); } else { this.entityManager .unwrap(Session.class) @@ -95,7 +108,24 @@ public class TenantEntityManager { } } - public void disableTenantFilters(){ + public void loadExplictTenantFilters() throws InvalidApplicationException { + this.disableTenantFilters(); + + if (!this.tenantScope.isSet()) return; + + if (!this.tenantScope.isDefaultTenant()) { + this.entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT) + .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, this.tenantScope.getTenant().toString()); + } else { + this.entityManager + .unwrap(Session.class) + .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + } + } + + public void disableTenantFilters() { this.entityManager .unwrap(Session.class) .disableFilter(TenantScopedBaseEntity.TENANT_FILTER); @@ -103,14 +133,17 @@ public class TenantEntityManager { this.entityManager .unwrap(Session.class) .disableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); + + this.entityManager + .unwrap(Session.class) + .disableFilter(TenantScopedBaseEntity.TENANT_FILTER_EXPLICT); } - + public EntityManager getEntityManager() { - return entityManager; + return this.entityManager; } public void setEntityManager(EntityManager entityManager) { this.entityManager = entityManager; } - } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantFilterAspect.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantFilterAspect.java index 1f5338325..32f63706e 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantFilterAspect.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantFilterAspect.java @@ -1,44 +1,44 @@ -package gr.cite.annotation.data.tenant; - -import gr.cite.annotation.common.scope.tenant.TenantScope; -import jakarta.persistence.EntityManager; -import org.aspectj.lang.JoinPoint; -import org.aspectj.lang.annotation.AfterReturning; -import org.aspectj.lang.annotation.Aspect; -import org.hibernate.Session; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Component; - -import javax.management.InvalidApplicationException; - -@Aspect -@Component -public class TenantFilterAspect { - - private final TenantScope tenantScope; - - @Autowired - public TenantFilterAspect( - TenantScope tenantScope - ) { - this.tenantScope = tenantScope; - } - - @AfterReturning( - pointcut = "bean(entityManagerFactory) && execution(* createEntityManager(..))", - returning = "retVal") - public void getSessionAfter(JoinPoint joinPoint, Object retVal) throws InvalidApplicationException { - if (retVal instanceof EntityManager && tenantScope.isSet()) { - Session session = ((EntityManager) retVal).unwrap(Session.class); - if(!tenantScope.isDefaultTenant()) { - session - .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) - .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); - } else { - session - .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); - } - } - } - -} +//package gr.cite.annotation.data.tenant; +// +//import gr.cite.annotation.common.scope.tenant.TenantScope; +//import jakarta.persistence.EntityManager; +//import org.aspectj.lang.JoinPoint; +//import org.aspectj.lang.annotation.AfterReturning; +//import org.aspectj.lang.annotation.Aspect; +//import org.hibernate.Session; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Component; +// +//import javax.management.InvalidApplicationException; +// +//@Aspect +//@Component +//public class TenantFilterAspect { +// +// private final TenantScope tenantScope; +// +// @Autowired +// public TenantFilterAspect( +// TenantScope tenantScope +// ) { +// this.tenantScope = tenantScope; +// } +// +// @AfterReturning( +// pointcut = "bean(entityManagerFactory) && execution(* createEntityManager(..))", +// returning = "retVal") +// public void getSessionAfter(JoinPoint joinPoint, Object retVal) throws InvalidApplicationException { +// if (retVal instanceof EntityManager && tenantScope.isSet()) { +// Session session = ((EntityManager) retVal).unwrap(Session.class); +// if(!tenantScope.isDefaultTenant()) { +// session +// .enableFilter(TenantScopedBaseEntity.TENANT_FILTER) +// .setParameter(TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, tenantScope.getTenant().toString()); +// } else { +// session +// .enableFilter(TenantScopedBaseEntity.DEFAULT_TENANT_FILTER); +// } +// } +// } +// +//} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantScopedBaseEntity.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantScopedBaseEntity.java index c34be941e..14dd7f4fb 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantScopedBaseEntity.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/data/tenant/TenantScopedBaseEntity.java @@ -16,22 +16,25 @@ import java.util.UUID; //@Getter //@Setter //@NoArgsConstructor -@FilterDef(name = TenantScopedBaseEntity.TENANT_FILTER, parameters = {@ParamDef(name = TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, type = String.class)}) +@FilterDef(name = TenantScopedBaseEntity.TENANT_FILTER, parameters = @ParamDef(name = TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, type = String.class)) +@FilterDef(name = TenantScopedBaseEntity.TENANT_FILTER_EXPLICT, parameters = @ParamDef(name = TenantScopedBaseEntity.TENANT_FILTER_TENANT_PARAM, type = String.class)) @FilterDef(name = TenantScopedBaseEntity.DEFAULT_TENANT_FILTER) -@Filter(name = TenantScopedBaseEntity.DEFAULT_TENANT_FILTER, condition = "(tenant = tenant is null)") @Filter(name = TenantScopedBaseEntity.TENANT_FILTER, condition = "(tenant = (cast(:tenantId as uuid)) or tenant is null)") +@Filter(name = TenantScopedBaseEntity.TENANT_FILTER_EXPLICT, condition = "(tenant = (cast(:tenantId as uuid)))") +@Filter(name = TenantScopedBaseEntity.DEFAULT_TENANT_FILTER, condition = "(tenant = tenant is null)") @EntityListeners(TenantListener.class) public abstract class TenantScopedBaseEntity implements TenantScoped, Serializable { private static final long serialVersionUID = 1L; public static final String TENANT_FILTER = "tenantFilter"; public static final String DEFAULT_TENANT_FILTER = "defaultTenantFilter"; + public static final String TENANT_FILTER_EXPLICT = "tenantFilterExplict"; public static final String TENANT_FILTER_TENANT_PARAM = "tenantId"; @Column(name = "tenant", columnDefinition = "uuid", nullable = true) private UUID tenantId; public static final String _tenantId = "tenantId"; public UUID getTenantId() { - return tenantId; + return this.tenantId; } @Override diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java index cf81badb5..f8fa89d4b 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/InboxIntegrationEventConfigurer.java @@ -4,6 +4,7 @@ import gr.cite.annotation.integrationevent.inbox.InboxProperties; import gr.cite.annotation.integrationevent.inbox.InboxRepositoryImpl; import gr.cite.queueinbox.InboxConfigurer; import gr.cite.queueinbox.repository.InboxRepository; +import jakarta.persistence.EntityManagerFactory; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; @@ -15,18 +16,20 @@ import org.springframework.context.annotation.Configuration; @ConditionalOnProperty(prefix = "queue.task.listener", name = "enable", matchIfMissing = false) public class InboxIntegrationEventConfigurer extends InboxConfigurer { - private ApplicationContext applicationContext; + private final ApplicationContext applicationContext; - private InboxProperties inboxProperties; + private final InboxProperties inboxProperties; - public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) { + private final EntityManagerFactory entityManagerFactory; + public InboxIntegrationEventConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory) { this.applicationContext = applicationContext; this.inboxProperties = inboxProperties; + this.entityManagerFactory = entityManagerFactory; } @Bean public InboxRepository inboxRepositoryCreator() { - return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties); + return new InboxRepositoryImpl(this.applicationContext, this.inboxProperties, this.entityManagerFactory); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java index 52602ad8f..15a0bed4e 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/OutboxIntegrationEventConfigurer.java @@ -9,6 +9,7 @@ import gr.cite.queueoutbox.repository.OutboxRepository; import gr.cite.rabbitmq.IntegrationEventMessageConstants; import gr.cite.rabbitmq.RabbitProperties; import gr.cite.rabbitmq.broker.MessageHydrator; +import jakarta.persistence.EntityManagerFactory; import org.springframework.amqp.core.MessageProperties; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; @@ -25,12 +26,14 @@ import java.util.UUID; @EnableConfigurationProperties({OutboxProperties.class}) @ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false) public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { - private ApplicationContext applicationContext; - private OutboxProperties outboxProperties; + private final ApplicationContext applicationContext; + private final OutboxProperties outboxProperties; + private final EntityManagerFactory entityManagerFactory; - public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties) { + public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory) { this.applicationContext = applicationContext; this.outboxProperties = outboxProperties; + this.entityManagerFactory = entityManagerFactory; } @Bean @@ -66,7 +69,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { @Bean public OutboxRepository outboxRepositoryCreator() { - return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties); + return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties, this.entityManagerFactory); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java index ce2831fd8..f13222728 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/InboxRepositoryImpl.java @@ -44,13 +44,15 @@ public class InboxRepositoryImpl implements InboxRepository { private final JsonHandlingService jsonHandlingService; private final InboxProperties inboxProperties; + private final EntityManagerFactory entityManagerFactory; public InboxRepositoryImpl( - ApplicationContext applicationContext, - InboxProperties inboxProperties + ApplicationContext applicationContext, + InboxProperties inboxProperties, EntityManagerFactory entityManagerFactory ) { this.applicationContext = applicationContext; - this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); + this.entityManagerFactory = entityManagerFactory; + this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.inboxProperties = inboxProperties; } @@ -62,8 +64,7 @@ public class InboxRepositoryImpl implements InboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -120,9 +121,7 @@ public class InboxRepositoryImpl implements InboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -166,9 +165,7 @@ public class InboxRepositoryImpl implements InboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -214,9 +211,8 @@ public class InboxRepositoryImpl implements InboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { queueMessage = this.createQueueInboxEntity(inboxCreatorParams); - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -275,9 +271,7 @@ public class InboxRepositoryImpl implements InboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); TenantEntityManager tenantEntityManager = this.applicationContext.getBean(TenantEntityManager.class); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiesremoval/AnnotationEntitiesRemovalIntegrationEventHandlerImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiesremoval/AnnotationEntitiesRemovalIntegrationEventHandlerImpl.java index 35214a3d1..72a04485e 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiesremoval/AnnotationEntitiesRemovalIntegrationEventHandlerImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiesremoval/AnnotationEntitiesRemovalIntegrationEventHandlerImpl.java @@ -22,13 +22,8 @@ import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.validation.ValidatorFactory; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -80,16 +75,16 @@ public class AnnotationEntitiesRemovalIntegrationEventHandlerImpl implements Ann EventProcessingStatus status = EventProcessingStatus.Success; try { if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); + TenantEntity tenant = queryFactory.query(TenantQuery.class).disableTracking().ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); if (tenant == null) { logger.error("missing tenant from event message"); return EventProcessingStatus.Error; } - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), properties.getTenantId(), tenant.getCode()); + this.tenantScope.setTempTenant(tenantEntityManager, properties.getTenantId(), tenant.getCode()); } else if (this.tenantScope.isMultitenant()) { // logger.error("missing tenant from event message"); // return EventProcessingStatus.Error; - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode()); + this.tenantScope.setTempTenant(tenantEntityManager, null, this.tenantScope.getDefaultTenantCode()); } @@ -117,9 +112,9 @@ public class AnnotationEntitiesRemovalIntegrationEventHandlerImpl implements Ann logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); } finally { currentPrincipalResolver.pop(); - tenantScope.removeTempTenant(this.tenantEntityManager.getEntityManager()); try { - this.tenantEntityManager.enableTenantFilters(); + tenantScope.removeTempTenant(this.tenantEntityManager); + this.tenantEntityManager.reloadTenantFilters(); } catch (InvalidApplicationException e) { } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiestouch/AnnotationEntitiesTouchedIntegrationEventHandlerImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiestouch/AnnotationEntitiesTouchedIntegrationEventHandlerImpl.java index fa3c1d6e9..1a6b06be0 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiestouch/AnnotationEntitiesTouchedIntegrationEventHandlerImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/annotationentitiestouch/AnnotationEntitiesTouchedIntegrationEventHandlerImpl.java @@ -3,7 +3,6 @@ package gr.cite.annotation.integrationevent.inbox.annotationentitiestouch; import gr.cite.annotation.audit.AuditableAction; import gr.cite.annotation.common.JsonHandlingService; import gr.cite.annotation.common.enums.IsActive; -import gr.cite.annotation.common.scope.fake.FakeRequestScope; import gr.cite.annotation.common.scope.tenant.TenantScope; import gr.cite.annotation.data.EntityUserEntity; import gr.cite.annotation.data.TenantEntity; @@ -14,7 +13,6 @@ import gr.cite.annotation.integrationevent.inbox.IntegrationEventProperties; import gr.cite.annotation.model.Tenant; import gr.cite.annotation.query.EntityUserQuery; import gr.cite.annotation.query.TenantQuery; -import gr.cite.annotation.service.tenant.TenantService; import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorProperties; import gr.cite.tools.auditing.AuditService; @@ -23,13 +21,8 @@ import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.validation.ValidatorFactory; -import jakarta.persistence.EntityManager; -import jakarta.persistence.EntityManagerFactory; -import jakarta.persistence.EntityTransaction; -import jakarta.persistence.OptimisticLockException; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.config.ConfigurableBeanFactory; -import org.springframework.context.ApplicationContext; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; @@ -81,16 +74,16 @@ public class AnnotationEntitiesTouchedIntegrationEventHandlerImpl implements Ann EventProcessingStatus status = EventProcessingStatus.Success; try { if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); + TenantEntity tenant = queryFactory.query(TenantQuery.class).disableTracking().ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); if (tenant == null) { logger.error("missing tenant from event message"); return EventProcessingStatus.Error; } - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), properties.getTenantId(), tenant.getCode()); + this.tenantScope.setTempTenant(tenantEntityManager, properties.getTenantId(), tenant.getCode()); } else if (this.tenantScope.isMultitenant()) { // logger.error("missing tenant from event message"); // return EventProcessingStatus.Error; - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode()); + this.tenantScope.setTempTenant(tenantEntityManager, null, this.tenantScope.getDefaultTenantCode()); } currentPrincipalResolver.push(InboxPrincipal.build(properties, claimExtractorProperties)); @@ -136,9 +129,9 @@ public class AnnotationEntitiesTouchedIntegrationEventHandlerImpl implements Ann logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); } finally { currentPrincipalResolver.pop(); - tenantScope.removeTempTenant(this.tenantEntityManager.getEntityManager()); try { - this.tenantEntityManager.enableTenantFilters(); + tenantScope.removeTempTenant(this.tenantEntityManager); + this.tenantEntityManager.reloadTenantFilters(); } catch (InvalidApplicationException e) { } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/tenantremoval/TenantRemovalConsistencyHandler.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/tenantremoval/TenantRemovalConsistencyHandler.java index 96b0f51a7..f895eed8c 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/tenantremoval/TenantRemovalConsistencyHandler.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/tenantremoval/TenantRemovalConsistencyHandler.java @@ -19,7 +19,7 @@ public class TenantRemovalConsistencyHandler implements ConsistencyHandler 0; } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/userremoval/UserRemovalConsistencyHandler.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/userremoval/UserRemovalConsistencyHandler.java index d1699bd97..d4340e0bb 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/userremoval/UserRemovalConsistencyHandler.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/userremoval/UserRemovalConsistencyHandler.java @@ -19,7 +19,7 @@ public class UserRemovalConsistencyHandler implements ConsistencyHandler specifications(UserCredential item) { - return Arrays.asList( - this.spec() - .must(() -> !this.isEmpty(item.getSubjectId())) - .failOn(UserCredential._subjectId).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserCredential._subjectId}, LocaleContextHolder.getLocale())) + return Collections.singletonList( + this.spec() + .must(() -> !this.isEmpty(item.getSubjectId())) + .failOn(UserCredential._subjectId).failWith(messageSource.getMessage("Validation_Required", new Object[]{UserCredential._subjectId}, LocaleContextHolder.getLocale())) ); } } @@ -272,10 +273,10 @@ public class UserTouchedIntegrationEvent extends TrackedEvent { @Override protected List specifications(TenantUser item) { - return Arrays.asList( - this.spec() - .must(() -> !this.isNull(item.getTenant())) - .failOn(TenantUser._tenant).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantUser._tenant}, LocaleContextHolder.getLocale())) + return Collections.singletonList( + this.spec() + .must(() -> !this.isNull(item.getTenant())) + .failOn(TenantUser._tenant).failWith(messageSource.getMessage("Validation_Required", new Object[]{TenantUser._tenant}, LocaleContextHolder.getLocale())) ); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/usertouch/UserTouchedIntegrationEventHandlerImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/usertouch/UserTouchedIntegrationEventHandlerImpl.java index a338db5f7..a7d87971b 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/usertouch/UserTouchedIntegrationEventHandlerImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/inbox/usertouch/UserTouchedIntegrationEventHandlerImpl.java @@ -23,6 +23,7 @@ import org.springframework.beans.factory.config.ConfigurableBeanFactory; import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import javax.management.InvalidApplicationException; import java.util.AbstractMap; import java.util.Map; @@ -71,16 +72,16 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr EventProcessingStatus status = EventProcessingStatus.Success; try { if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) { - TenantEntity tenant = queryFactory.query(TenantQuery.class).ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); + TenantEntity tenant = queryFactory.query(TenantQuery.class).disableTracking().ids(properties.getTenantId()).firstAs(new BaseFieldSet().ensure(Tenant._id).ensure(Tenant._code)); if (tenant == null) { logger.error("missing tenant from event message"); return EventProcessingStatus.Error; } - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), properties.getTenantId(), tenant.getCode()); + this.tenantScope.setTempTenant(tenantEntityManager, properties.getTenantId(), tenant.getCode()); } else if (this.tenantScope.isMultitenant()) { // logger.error("missing tenant from event message"); // return EventProcessingStatus.Error; - this.tenantScope.setTempTenant(tenantEntityManager.getEntityManager(), null, this.tenantScope.getDefaultTenantCode()); + this.tenantScope.setTempTenant(tenantEntityManager, null, this.tenantScope.getDefaultTenantCode()); } currentPrincipalResolver.push(InboxPrincipal.build(properties, claimExtractorProperties)); @@ -96,7 +97,11 @@ public class UserTouchedIntegrationEventHandlerImpl implements UserTouchedIntegr logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); } finally { currentPrincipalResolver.pop(); - tenantScope.removeTempTenant(this.tenantEntityManager.getEntityManager()); + try { + tenantScope.removeTempTenant(this.tenantEntityManager); + } catch (InvalidApplicationException e) { + logger.error(e.getMessage(), e); + } } return status; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java index 5ce77cb02..4ec9735c3 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxRepositoryImpl.java @@ -33,17 +33,16 @@ public class OutboxRepositoryImpl implements OutboxRepository { private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(OutboxRepositoryImpl.class)); - private final JsonHandlingService jsonHandlingService; - private final OutboxProperties outboxProperties; - + private final EntityManagerFactory entityManagerFactory; + public OutboxRepositoryImpl( ApplicationContext applicationContext, - OutboxProperties outboxProperties + OutboxProperties outboxProperties, EntityManagerFactory entityManagerFactory ) { this.applicationContext = applicationContext; - this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); this.outboxProperties = outboxProperties; + this.entityManagerFactory = entityManagerFactory; } @Override @@ -54,8 +53,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { QueryFactory queryFactory = this.applicationContext.getBean(QueryFactory.class); - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -115,9 +113,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -161,9 +157,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -209,9 +203,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -265,9 +257,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -309,9 +299,7 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); @@ -353,9 +341,8 @@ public class OutboxRepositoryImpl implements OutboxRepository { try (FakeRequestScope ignored = new FakeRequestScope()) { try { queueMessage = this.mapEvent((OutboxIntegrationEvent) item); - EntityManagerFactory entityManagerFactory = this.applicationContext.getBean(EntityManagerFactory.class); - entityManager = entityManagerFactory.createEntityManager(); + entityManager = this.entityManagerFactory.createEntityManager(); transaction = entityManager.getTransaction(); transaction.begin(); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java index 2e57b962f..9228a7d3a 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/AnnotationBuilder.java @@ -100,7 +100,7 @@ public class AnnotationBuilder extends BaseBuilder .map(AnnotationEntity::getSubjectId) .distinct() .collect(Collectors.toList()); - UserQuery query = this.queryFactory.query(UserQuery.class).ids(userIds); + UserQuery query = this.queryFactory.query(UserQuery.class).disableTracking().ids(userIds); Map> users = this.builderFactory.builder(UserBuilder.class).authorize(this.authorize).asMasterKey(query, clone, User::getId); users.forEach((key, val) -> { diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java index 00f27ee18..bc9e04835 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/model/builder/BaseBuilder.java @@ -33,7 +33,7 @@ public abstract class BaseBuilder implements Builder { M model = null; return null; //TODO } - List models = this.build(directives, Arrays.asList(data)); + List models = this.build(directives, List.of(data)); return models.stream().findFirst().orElse(null); //TODO } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java index f217b462c..90b83f788 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/AnnotationQuery.java @@ -8,7 +8,6 @@ import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.data.EntityUserEntity; import gr.cite.annotation.model.Annotation; -import gr.cite.annotation.model.EntityUser; import gr.cite.annotation.query.utils.BuildSubQueryInput; import gr.cite.annotation.query.utils.QueryUtilsService; import gr.cite.commons.web.authz.service.AuthorizationService; @@ -175,6 +174,16 @@ public class AnnotationQuery extends QueryBase { return this; } + public AnnotationQuery enableTracking() { + this.noTracking = false; + return this; + } + + public AnnotationQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.excludedIds) || this.isEmpty(this.isActives) || this.isEmpty(this.entityIds); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java index 6b309a7cc..c21138867 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/EntityUserQuery.java @@ -29,9 +29,9 @@ public class EntityUserQuery extends QueryBase { private Collection ids, entityIds, userIds; - private Collection isActives;; + private Collection isActives; - private final AuthorizationService authService; + private final AuthorizationService authService; private final UserScope userScope; @@ -107,6 +107,16 @@ public class EntityUserQuery extends QueryBase { return this; } + public EntityUserQuery enableTracking() { + this.noTracking = false; + return this; + } + + public EntityUserQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Boolean isFalseQuery() { return false; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java index c99534127..b96a1be0a 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueInboxQuery.java @@ -120,6 +120,16 @@ public class QueueInboxQuery extends QueryBase { return this; } + public QueueInboxQuery enableTracking() { + this.noTracking = false; + return this; + } + + public QueueInboxQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Class entityClass() { return QueueInboxEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java index a6083fa61..58d4d2cfe 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/QueueOutboxQuery.java @@ -125,6 +125,16 @@ public class QueueOutboxQuery extends QueryBase { return this; } + public QueueOutboxQuery enableTracking() { + this.noTracking = false; + return this; + } + + public QueueOutboxQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Class entityClass() { return QueueOutboxEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java index b0d02ba5e..1f3aaa200 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantQuery.java @@ -68,6 +68,16 @@ public class TenantQuery extends QueryBase { return this; } + public TenantQuery enableTracking() { + this.noTracking = false; + return this; + } + + public TenantQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Boolean isFalseQuery() { return this.isEmpty(this.ids) || this.isEmpty(this.isActives); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java index 1fb4acef9..5f78245bd 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/TenantUserQuery.java @@ -114,6 +114,16 @@ public class TenantUserQuery extends QueryBase { return this; } + public TenantUserQuery enableTracking() { + this.noTracking = false; + return this; + } + + public TenantUserQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Class entityClass() { return TenantUserEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java index 014582bf8..08bf1ea88 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserCredentialQuery.java @@ -125,6 +125,16 @@ public class UserCredentialQuery extends QueryBase { return this; } + public UserCredentialQuery enableTracking() { + this.noTracking = false; + return this; + } + + public UserCredentialQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Boolean isFalseQuery() { return diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java index 1e6ac6e4c..7d81d9863 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/query/UserQuery.java @@ -84,6 +84,16 @@ public class UserQuery extends QueryBase { return this; } + public UserQuery enableTracking() { + this.noTracking = false; + return this; + } + + public UserQuery disableTracking() { + this.noTracking = false; + return this; + } + @Override protected Class entityClass() { return UserEntity.class; diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java index f9aa5815e..7efc4e6f8 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationServiceImpl.java @@ -23,7 +23,6 @@ import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; -import jakarta.transaction.Transactional; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; @@ -69,7 +68,6 @@ public class AnnotationServiceImpl implements AnnotationService { } @Override - @Transactional public Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException { logger.debug(new MapLogEntry("persisting annotation").And("model", model).And("fields", fields)); diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/user/UserServiceImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/user/UserServiceImpl.java index 880d0b479..9c1339f2c 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/user/UserServiceImpl.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/user/UserServiceImpl.java @@ -30,7 +30,6 @@ import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; -import jakarta.transaction.Transactional; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; import org.springframework.context.i18n.LocaleContextHolder; @@ -85,7 +84,6 @@ public class UserServiceImpl implements UserService { } @Override - @Transactional public User persist(UserTouchedIntegrationEvent model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException, JsonProcessingException { logger.debug(new MapLogEntry("persisting user").And("model", model).And("fields", fields)); @@ -185,7 +183,7 @@ public class UserServiceImpl implements UserService { try { TenantEntity tenant = tenantEntities.stream().filter(x -> x.getId().equals(model.getTenant())).findFirst().orElse(null); if (tenant == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{model.getTenant(), Tenant.class.getSimpleName()}, LocaleContextHolder.getLocale())); - this.tenantScope.setTempTenant(this.entityManager.getEntityManager(), tenant.getId(), tenant.getCode()); + this.tenantScope.setTempTenant(this.entityManager, tenant.getId(), tenant.getCode()); data = new TenantUserEntity(); data.setId(UUID.randomUUID()); data.setUserId(userId); @@ -195,7 +193,7 @@ public class UserServiceImpl implements UserService { data.setIsActive(IsActive.Active); entityManager.persist(data); } finally { - this.tenantScope.removeTempTenant(this.entityManager.getEntityManager()); + this.tenantScope.removeTempTenant(this.entityManager); } } updatedCreatedIds.add(data.getId()); diff --git a/annotation-service/pom.xml b/annotation-service/pom.xml index 707d22518..76a693429 100644 --- a/annotation-service/pom.xml +++ b/annotation-service/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.1 + 3.2.5 @@ -43,7 +43,7 @@ org.hibernate.orm hibernate-core compile - 6.3.1.Final + 6.5.2.Final org.hibernate.orm @@ -71,7 +71,7 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 - 2.13.3 + 2.17.0 @@ -107,7 +107,7 @@ gr.cite data-tools - 2.1.2 + 2.1.4 @@ -119,7 +119,7 @@ gr.cite validation - 3.0.2 + 3.0.3 @@ -149,6 +149,12 @@ queue-outbox 2.1.1 + + + gr.cite + cache + 2.2.0 + diff --git a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java index 0313f713a..59f827790 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java +++ b/backend/core/src/main/java/org/opencdmp/commons/types/descriptiontemplate/PageEntity.java @@ -20,7 +20,7 @@ public class PageEntity { private List sections; public List getSections() { - return sections; + return this.sections; } public void setSections(List sections) { @@ -28,7 +28,7 @@ public class PageEntity { } public String getId() { - return id; + return this.id; } public void setId(String id) { @@ -36,7 +36,7 @@ public class PageEntity { } public int getOrdinal() { - return ordinal; + return this.ordinal; } public void setOrdinal(int ordinal) { @@ -44,7 +44,7 @@ public class PageEntity { } public String getTitle() { - return title; + return this.title; } public void setTitle(String title) { diff --git a/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java index 62c13b805..00e806ac8 100644 --- a/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/user/UserServiceImpl.java @@ -43,6 +43,7 @@ import org.opencdmp.data.tenant.TenantScopedBaseEntity; import org.opencdmp.errorcode.ErrorThesaurusProperties; import org.opencdmp.event.EventBroker; import org.opencdmp.event.UserTouchedEvent; +import org.opencdmp.integrationevent.outbox.annotationentitytouch.AnnotationEntityTouchedIntegrationEventHandler; import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEvent; import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import org.opencdmp.integrationevent.outbox.userremoval.UserRemovalIntegrationEventHandler; @@ -112,7 +113,7 @@ public class UserServiceImpl implements UserService { private final UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler; private final AuthorizationProperties authorizationProperties; private final TenantScope tenantScope; - + private final AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler; @Autowired public UserServiceImpl( TenantEntityManager entityManager, @@ -125,7 +126,7 @@ public class UserServiceImpl implements UserService { EventBroker eventBroker, JsonHandlingService jsonHandlingService, XmlHandlingService xmlHandlingService, QueryFactory queryFactory, - UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotifyIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory, ElasticService elasticService, UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler, UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler, AuthorizationProperties authorizationProperties, TenantScope tenantScope) { + UserScope userScope, KeycloakService keycloakService, ActionConfirmationService actionConfirmationService, NotificationProperties notificationProperties, NotifyIntegrationEventHandler eventHandler, ValidatorFactory validatorFactory, ElasticService elasticService, UserTouchedIntegrationEventHandler userTouchedIntegrationEventHandler, UserRemovalIntegrationEventHandler userRemovalIntegrationEventHandler, AuthorizationProperties authorizationProperties, TenantScope tenantScope, AnnotationEntityTouchedIntegrationEventHandler annotationEntityTouchedIntegrationEventHandler) { this.entityManager = entityManager; this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; @@ -148,6 +149,7 @@ public class UserServiceImpl implements UserService { this.userRemovalIntegrationEventHandler = userRemovalIntegrationEventHandler; this.authorizationProperties = authorizationProperties; this.tenantScope = tenantScope; + this.annotationEntityTouchedIntegrationEventHandler = annotationEntityTouchedIntegrationEventHandler; } //region persist @@ -739,6 +741,14 @@ public class UserServiceImpl implements UserService { for (DescriptionEntity description : descriptions){ this.elasticService.persistDescription(description); } + + for (DmpEntity dmp : dmps){ + this.annotationEntityTouchedIntegrationEventHandler.handleDmp(dmp.getId()); + } + + for (DescriptionEntity description : descriptions){ + this.annotationEntityTouchedIntegrationEventHandler.handleDescription(description.getId()); + } } public void confirmRemoveCredential(String token) throws InvalidApplicationException { diff --git a/dmp-frontend/src/app/core/services/matomo/analytics-service.ts b/dmp-frontend/src/app/core/services/matomo/analytics-service.ts index 1a705c3a1..3b4d8560e 100644 --- a/dmp-frontend/src/app/core/services/matomo/analytics-service.ts +++ b/dmp-frontend/src/app/core/services/matomo/analytics-service.ts @@ -7,6 +7,43 @@ import { AnalyticsProviderType, AnalyticsProviders } from "@app/core/model/confi export class AnalyticsService { public static Dashboard: string = 'Home Dashboard'; + public static About: string = 'About'; + public static DescriptionTemplateEditor: string = 'Admin: DMP Blueprints'; + public static DescriptionTemplateListing: string = 'Admin: DMP Templates'; + public static DmpBlueprintEditor: string = 'Admin: DMP Blueprints'; + public static DmpBlueprintListing: string = 'Admin: DMP Templates'; + public static LanguagesEditor: string = 'Admin: Languages'; + public static PrefillingSourcesEditor: string = 'Admin: PrefillingSources'; + public static ReferencesEditor: string = 'Admin: References'; + public static TenantsEditor: string = 'Admin: Tenants'; + public static TenantConfigurationsColorsEditor: string = 'Admin: TenantConfigurations'; + public static TenantConfigurationsUserLocaleEditor: string = 'Admin: TenantConfigurations'; + public static DepositEditor: string = 'Admin: TenantConfigurations'; + public static FileTransformerEditor: string = 'Admin: TenantConfigurations'; + public static LogoEditor: string = 'Admin: TenantConfigurations'; + public static ContactContent: string = 'Contact Content'; + public static RecentEditedActivity: string = 'Recent DMP Activity'; + public static DescriptionEditor: string = 'Description Editor'; + public static DescriptionListing: string = 'Descriptions'; + public static DatasetCriteriaDialog: string = 'Dataset Criteria'; + public static DescriptionListingItem: string = 'Description Listing Item'; + public static DescriptionOverview: string = 'Description Overview'; + public static DmpEditor: string = 'DMP Editor'; + public static DmpListing: string = 'DMPs'; + public static DmpCriteriaDialog: string = 'DMP Criteria'; + public static DmpListingItem: string = 'DMP Listing Item'; + public static StartNewDmpDialog: string = 'Start New DMP Dialog'; + public static DmpUploadDialog: string = 'DMP Upload Dialog'; + public static DmpOverview: string = 'DMP Overview'; + public static FAQ: string = 'FAQ'; + public static Glossary: string = 'Glossary'; + public static Navbar: string = 'Navbar'; + public static Sidebar: string = 'Sidebar'; + public static SidebarFooter: string = 'Sidebar Footer'; + public static Terms: string = 'Terms of Service'; + public static UserGuideContent: string = 'User Guide Content'; + public static UserProfile: string = 'User Profile'; + public static NotificationTempplateEditor: string = 'Admin: Notification Tempplates'; constructor( private configurationService: ConfigurationService, diff --git a/dmp-frontend/src/app/ui/about/about.component.ts b/dmp-frontend/src/app/ui/about/about.component.ts index 44e3a2286..e3713500a 100644 --- a/dmp-frontend/src/app/ui/about/about.component.ts +++ b/dmp-frontend/src/app/ui/about/about.component.ts @@ -3,7 +3,7 @@ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { BaseComponent } from '@common/base/base.component'; import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; @@ -23,13 +23,13 @@ export class AboutComponent extends BaseComponent implements OnInit { private supportiveMaterialService: SupportiveMaterialService, private sanitizer: DomSanitizer, private languageService: LanguageService, - private matomoService: MatomoService, private translate: TranslateService, private router: Router, + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('About'); + this.analyticsService.trackPageView(AnalyticsService.About); this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/about'])); }); diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts index c8cc0d165..202c4e644 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts @@ -22,7 +22,6 @@ import { LanguageInfoService } from '@app/core/services/culture/language-info-se import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; import { DescriptionTemplateService } from '@app/core/services/description-template/description-template.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { UserService } from '@app/core/services/user/user.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; @@ -45,6 +44,7 @@ import { LockTargetType } from '@app/core/common/enum/lock-target-type'; import { Title } from '@angular/platform-browser'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -138,10 +138,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor { diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/listing/dmp-blueprint-listing.component.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/listing/dmp-blueprint-listing.component.ts index d3da0d554..ac2801abc 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/listing/dmp-blueprint-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/listing/dmp-blueprint-listing.component.ts @@ -8,7 +8,6 @@ import { DmpBlueprint } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { DmpBlueprintLookup } from '@app/core/query/dmp-blueprint.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; @@ -29,6 +28,7 @@ import { nameof } from 'ts-simple-nameof'; import { ImportDmpBlueprintDialogComponent } from './import-dmp-blueprint/import-dmp-blueprint.dialog.component'; import { IsActiveTypePipe } from '@common/formatting/pipes/is-active-type.pipe'; import { DmpBlueprintVersionStatus } from '@app/core/common/enum/dmp-blueprint-version-status'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -70,12 +70,12 @@ export class DmpBlueprintListingComponent extends BaseListingComponent { this.prepareForm(entity); if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) { diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts index ce41a3593..a2e291aaf 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/default-user-locale/default-user-locale-editor.component.ts @@ -6,7 +6,6 @@ import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/serv // import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @@ -29,6 +28,7 @@ import { CultureService } from '@app/core/services/culture/culture-service'; import { LanguageService } from '@app/core/services/language/language.service'; import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { DefaultUserLocaleService } from '@app/core/services/default-user-locale/default-user-locale.service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -78,7 +78,7 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen private languageService: LanguageService, private defaultUserLocaleEditorService: DefaultUserLocaleEditorService, private defaultUserLocaleService: DefaultUserLocaleService, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(); this.languages = this.languageService.getAvailableLanguagesCodes().sort((x, y) => x.localeCompare(y)); @@ -93,7 +93,9 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen ngOnInit(): void { this.singleTimezoneAutocompleteConfiguration = this.defaultUserLocaleService.singleTimezoneAutocompleteConfiguration; this.singleCultureAutocompleteConfiguration = this.defaultUserLocaleService.singleCultureAutocompleteConfiguration; - this.matomoService.trackPageView('Admin: TenantConfigurations'); + + this.analyticsService.trackPageView(AnalyticsService.TenantConfigurationsUserLocaleEditor); + this.getItem((entity) => { this.prepareForm(entity); if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) { diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts index 7a04794b0..08389e137 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/deposit/deposit-editor.component.ts @@ -5,7 +5,6 @@ import { MatDialog } from '@angular/material/dialog'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @@ -22,6 +21,7 @@ import { TenantConfigurationType } from '@app/core/common/enum/tenant-configurat import { HttpErrorResponse } from '@angular/common/http'; import { ResponseErrorCode } from '@app/core/common/enum/respone-error-code'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -61,7 +61,7 @@ export class DepositEditorComponent extends BasePendingChangesComponent implemen private logger: LoggingService, private tenantConfigurationService: TenantConfigurationService, private depositEditorService: DepositEditorService, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(); } @@ -71,7 +71,8 @@ export class DepositEditorComponent extends BasePendingChangesComponent implemen } ngOnInit(): void { - this.matomoService.trackPageView('Admin: TenantConfigurations'); + this.analyticsService.trackPageView(AnalyticsService.DepositEditor); + this.getItem((entity) => { this.prepareForm(entity); if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) { diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts index 7d8009e35..d245971a8 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/file-transformer/file-transformer-editor.component.ts @@ -5,7 +5,6 @@ import { MatDialog } from '@angular/material/dialog'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @@ -22,6 +21,7 @@ import { TenantConfigurationType } from '@app/core/common/enum/tenant-configurat import { HttpErrorResponse } from '@angular/common/http'; import { ResponseErrorCode } from '@app/core/common/enum/respone-error-code'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -61,7 +61,7 @@ export class FileTransformerEditorComponent extends BasePendingChangesComponent private logger: LoggingService, private tenantConfigurationService: TenantConfigurationService, private fileTransformerEditorService: FileTransformerEditorService, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(); } @@ -71,7 +71,7 @@ export class FileTransformerEditorComponent extends BasePendingChangesComponent } ngOnInit(): void { - this.matomoService.trackPageView('Admin: TenantConfigurations'); + this.analyticsService.trackPageView(AnalyticsService.FileTransformerEditor); this.getItem((entity) => { this.prepareForm(entity); if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) { diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts index 6498297c1..262cef30f 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/logo/logo-editor.component.ts @@ -5,7 +5,6 @@ import { MatDialog } from '@angular/material/dialog'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @@ -26,6 +25,7 @@ import { StorageFileService } from '@app/core/services/storage-file/storage-file import { Guid } from '@common/types/guid'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import * as FileSaver from 'file-saver'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -69,9 +69,10 @@ export class LogoEditorComponent extends BasePendingChangesComponent implements private logger: LoggingService, private tenantConfigurationService: TenantConfigurationService, private logoEditorService: LogoEditorService, - private matomoService: MatomoService, private fileUtils: FileUtils, - private storageFileService: StorageFileService + private storageFileService: StorageFileService, + private analyticsService: AnalyticsService + ) { super(); } @@ -81,7 +82,7 @@ export class LogoEditorComponent extends BasePendingChangesComponent implements } ngOnInit(): void { - this.matomoService.trackPageView('Admin: TenantConfigurations'); + this.analyticsService.trackPageView(AnalyticsService.LogoEditor); this.getItem((entity) => { this.prepareForm(entity); if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) { diff --git a/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.ts index bfd62582d..e65d5dbc2 100644 --- a/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant/editor/tenant-editor.component.ts @@ -13,7 +13,6 @@ import { AppPermission } from '@app/core/common/enum/permission.enum'; import { Tenant, TenantPersist } from '@app/core/model/tenant/tenant'; import { AuthService } from '@app/core/services/auth/auth.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; import { BaseEditor } from '@common/base/base-editor'; @@ -29,6 +28,7 @@ import { TenantEditorService } from './tenant-editor.service'; import { TenantEditorModel } from './tenant-editor.model'; import { LockService } from '@app/core/services/lock/lock.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -84,13 +84,13 @@ export class TenantEditorComponent extends BaseEditor private logger: LoggingService, private tenantEditorService: TenantEditorService, private fileUtils: FileUtils, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(dialog, language, formService, router, uiNotificationService, httpErrorHandlingService, filterService, datePipe, route, queryParamsService, lockService, authService, configurationService); } ngOnInit(): void { - this.matomoService.trackPageView('Admin: Tenants'); + this.analyticsService.trackPageView(AnalyticsService.TenantsEditor); super.ngOnInit(); } diff --git a/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.ts b/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.ts index b79641261..b721062cf 100644 --- a/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.ts +++ b/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.ts @@ -9,8 +9,8 @@ import { ValidationErrorModel } from '@common/forms/validation/error-model/valid import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; import { FormService } from '@common/forms/form-service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-contact-content', @@ -31,13 +31,13 @@ export class ContactContentComponent extends BaseComponent implements OnInit { private language: TranslateService, private formService: FormService, private httpClient: HttpClient, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Contact Content'); + this.analyticsService.trackPageView(AnalyticsService.ContactContent); if (this.isDialog) { this.formGroup = this.form; } else { diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts index 7a3244041..bcd8de7e4 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts @@ -7,7 +7,6 @@ import { DashboardStatistics } from '@app/core/model/dashboard/dashboard-statist import { AuthService } from '@app/core/services/auth/auth.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { DashboardService } from '@app/core/services/dashboard/dashboard.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; @@ -43,7 +42,6 @@ export class DashboardComponent extends BaseComponent implements OnInit { private dialog: MatDialog, private language: TranslateService, private guidedTourService: GuidedTourService, - private matomoService: MatomoService, private analyticsService: AnalyticsService, public referenceTypeService: ReferenceTypeService, private fb: UntypedFormBuilder, @@ -65,7 +63,6 @@ export class DashboardComponent extends BaseComponent implements OnInit { }); this.analyticsService.trackPageView(AnalyticsService.Dashboard); - // this.matomoService.trackPageView('Home Dashboard'); if (!this.isAuthenticated()) { this.dashboardService.getPublicDashboardStatistics() diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts index e98a401e0..c3a975d26 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -12,7 +12,6 @@ import { Reference } from '@app/core/model/reference/reference'; import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup'; import { DashboardService } from "@app/core/services/dashboard/dashboard.service"; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { debounceTime, takeUntil } from 'rxjs/operators'; @@ -24,6 +23,7 @@ import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-drafts', @@ -58,14 +58,14 @@ export class DraftsComponent extends BaseComponent implements OnInit { private authentication: AuthService, private dashboardService: DashboardService, private location: Location, - private matomoService: MatomoService, - private dmpService: DmpService + private dmpService: DmpService, + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Recent DMP Activity'); + this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity); this.route.queryParams.subscribe(params => { if (this.isActive) { let page = (params['page'] === undefined) ? 1 : +params['page']; diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index eaefa4871..1a24be391 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -19,7 +19,7 @@ import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-l import { AuthService } from '@app/core/services/auth/auth.service'; import { DashboardService } from '@app/core/services/dashboard/dashboard.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { Lookup } from '@common/model/lookup'; @@ -74,14 +74,14 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn private authentication: AuthService, private dashboardService: DashboardService, private location: Location, - private matomoService: MatomoService, - private dmpService: DmpService + private dmpService: DmpService, + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Recent DMP Activity'); + this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity); this.route.queryParams.subscribe(params => { if (this.isActive) { let page = (params['page'] === undefined) ? 0 : + params['page']; diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts index 13317ffa8..1d6860471 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts @@ -13,7 +13,6 @@ import { Reference } from '@app/core/model/reference/reference'; import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DashboardService } from '@app/core/services/dashboard/dashboard.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { debounceTime, takeUntil } from 'rxjs/operators'; @@ -21,6 +20,7 @@ import { nameof } from 'ts-simple-nameof'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-recent-edited-description-activity', @@ -56,13 +56,13 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl private authentication: AuthService, private dashboardService: DashboardService, private location: Location, - private matomoService: MatomoService + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Recent DMP Activity'); + this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity); this.route.queryParams.subscribe(params => { if (this.isActive) { let page = (params['page'] === undefined) ? 1 : +params['page']; diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts index 6b6e4e5d1..9a0e8e077 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts @@ -17,7 +17,7 @@ import { Reference } from '@app/core/model/reference/reference'; import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DashboardService } from '@app/core/services/dashboard/dashboard.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { debounceTime, takeUntil } from 'rxjs/operators'; @@ -63,13 +63,13 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O private authentication: AuthService, private dashboardService: DashboardService, private location: Location, - private matomoService: MatomoService, + private analyticsService: AnalyticsService ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Recent DMP Activity'); + this.analyticsService.trackPageView(AnalyticsService.RecentEditedActivity); this.route.queryParams.subscribe(params => { if (this.isActive) { let page = (params['page'] === undefined) ? 1 : +params['page']; diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 387587546..b6f468299 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -22,7 +22,6 @@ import { DmpService } from '@app/core/services/dmp/dmp.service'; import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service'; import { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService @@ -49,6 +48,7 @@ import { ToCEntry } from './table-of-contents/models/toc-entry'; import { ToCEntryType } from './table-of-contents/models/toc-entry-type.enum'; import { TableOfContentsValidationService } from './table-of-contents/services/table-of-contents-validation-service'; import { TableOfContentsComponent } from './table-of-contents/table-of-contents.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-description-editor-component', @@ -98,12 +98,12 @@ export class DescriptionEditorComponent extends BaseEditor, private httpClient: HttpClient, - private matomoService: MatomoService, + private analyticsService: AnalyticsService, @Inject(MAT_DIALOG_DATA) public data: { isPublic: boolean, status: Number, criteria: DatasetCriteria, formGroup: UntypedFormGroup, updateDataFn: Function } ) { } ngOnInit() { - this.matomoService.trackPageView('Dataset Criteria'); + this.analyticsService.trackPageView(AnalyticsService.DatasetCriteriaDialog); this.criteria.setCriteria(this.data.criteria); } diff --git a/dmp-frontend/src/app/ui/description/listing/description-listing.component.html b/dmp-frontend/src/app/ui/description/listing/description-listing.component.html index 6daf95490..7eebe739b 100644 --- a/dmp-frontend/src/app/ui/description/listing/description-listing.component.html +++ b/dmp-frontend/src/app/ui/description/listing/description-listing.component.html @@ -44,10 +44,10 @@
-
+
{{'DMP-LISTING.SORT-BY' | translate}}:
-
+
{{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}} @@ -58,8 +58,14 @@
+
+ +
-
+
diff --git a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts index edbc8ff2c..14ce87d23 100644 --- a/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/description-listing.component.ts @@ -21,7 +21,6 @@ import { DmpLookup } from '@app/core/query/dmp.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DescriptionService } from '@app/core/services/description/description.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; @@ -35,6 +34,8 @@ import { debounceTime, takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { StartNewDescriptionDialogComponent } from '../start-new-description-dialog/start-new-description-dialog.component'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; +import { SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-description-listing-component', @@ -73,6 +74,23 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit dmpText: string; descriptionText: string; + private _sortDirection: SortDirection = SortDirection.Descending; //SortDirection.Descending: "-" + set sortDirection(sortDirection: SortDirection) { + this._sortDirection = sortDirection; + } + get isAscending(): boolean { + return this._sortDirection == SortDirection.Ascending; + } + get isDescending(): boolean { + return this._sortDirection == SortDirection.Descending; + } + get sortingDirectionPrefix(): string { + return this.isAscending ? "+" : "-"; + } + get sortingTooltipText(): string { + return this.isAscending ? this.language.instant('DESCRIPTION-LISTING.ACTIONS.TOGGLE-ΑSCENDING') : this.language.instant('DESCRIPTION-LISTING.ACTIONS.TOGGLE-DESCENDING'); + } + constructor( private descriptionService: DescriptionService, private router: Router, @@ -84,14 +102,14 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit private authentication: AuthService, private guidedTourService: GuidedTourService, private httpClient: HttpClient, - private matomoService: MatomoService, + private analyticsService: AnalyticsService, private fb: UntypedFormBuilder, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Descriptions'); + this.analyticsService.trackPageView(AnalyticsService.DescriptionListing); this.isPublic = this.router.url === '/explore-descriptions'; if (this.isPublic) { //TODO: refactor @@ -184,11 +202,11 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit orderByChanged(){ if (this.formGroup.get('order').value == RecentActivityOrder.Status){ - this.lookup.order = { items: ['-' + nameof(x => x.status)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.status)] }; } else if(this.formGroup.get('order').value == RecentActivityOrder.Label){ - this.lookup.order = { items: ['-' + nameof(x => x.label)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.label)] }; }else{ - this.lookup.order = { items: ['-' + nameof(x => x.updatedAt)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.updatedAt)] }; } this.refresh(this.lookup); } @@ -394,4 +412,8 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit return this.lookup.like !== undefined && this.lookup.like !== null; } + toggleSortDirection(): void { + this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; + this.orderByChanged(); + } } diff --git a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts index 47556aaaa..66e507f60 100644 --- a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.ts @@ -28,6 +28,7 @@ import { DescriptionStatus } from '../../../../core/common/enum/description-stat import { DescriptionCopyDialogComponent } from '../../description-copy-dialog/description-copy-dialog.component'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-description-listing-item-component', @@ -69,12 +70,13 @@ export class DescriptionListingItemComponent extends BaseComponent implements On public referenceTypeService: ReferenceTypeService, public fileTransformerService: FileTransformerService, private fb: UntypedFormBuilder, + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Description Listing Item'); + this.analyticsService.trackPageView(AnalyticsService.DescriptionListingItem); if (this.description.isActive === IsActive.Inactive) { this.isDeleted = true; } else if (this.description.status === DescriptionStatus.Draft) { diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.html b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html index 710dca7c6..242103b84 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.html +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html @@ -89,8 +89,8 @@
- -
 
+
+
 
{{ dmpReference.reference?.label }},
{{ dmpReference.reference?.label }}
diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss b/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss index f4ee17589..1106f7b4d 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.scss @@ -52,8 +52,9 @@ } .id-btn { - background: url("../../../../assets/images/orcid.png") no-repeat center; - width: 1em; + background: url("../../../../assets/images/orcid_unauth.png") no-repeat center; + width: 1rem; + height: 1rem; margin-right: 0.3em; align-self: center; } diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts index 411724726..32cb494ed 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.ts @@ -41,6 +41,7 @@ import { IsActive } from '@app/core/common/enum/is-active.enum'; import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dialog/dmp-invitation-dialog.component'; import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -92,13 +93,15 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni public fileTransformerService: FileTransformerService, private referenceTypeService: ReferenceTypeService, private fb: UntypedFormBuilder, - private lockService: LockService + private lockService: LockService, + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Description Overview'); + this.analyticsService.trackPageView(AnalyticsService.DescriptionOverview); + this.canDelete = false; this.canEdit = false; this.canFinalize = false; @@ -174,6 +177,10 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni }); } + get unauthorizedTootipText(): string { + return this.language.instant('DESCRIPTION-OVERVIEW.INFOS.UNAUTHORIZED-ORCID'); + } + checkLockStatus(id: Guid) { this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) .subscribe(lockStatus => { diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts index 1b00babfc..0c113a0b3 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts @@ -31,7 +31,6 @@ import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.servic import { DmpService } from '@app/core/services/dmp/dmp.service'; import { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { UserService } from '@app/core/services/user/user.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; @@ -52,6 +51,7 @@ import { DmpEditorModel, DmpFieldIndicator } from './dmp-editor.model'; import { DmpEditorResolver } from './dmp-editor.resolver'; import { DmpEditorService } from './dmp-editor.service'; import { Title } from '@angular/platform-browser'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-dmp-editor', @@ -160,14 +160,14 @@ export class DmpEditorComponent extends BaseEditor implemen private dmpService: DmpService, private logger: LoggingService, public dmpBlueprintService: DmpBlueprintService, - private matomoService: MatomoService, // public visibilityRulesService: VisibilityRulesService, private languageInfoService: LanguageInfoService, public enumUtils: EnumUtils, public descriptionTemplateService: DescriptionTemplateService, public userService: UserService, public descriptionService: DescriptionService, - public titleService: Title + public titleService: Title, + private analyticsService: AnalyticsService, ) { const descriptionLabel:string = route.snapshot.data['entity']?.label; if (descriptionLabel) { @@ -179,7 +179,8 @@ export class DmpEditorComponent extends BaseEditor implemen } ngOnInit(): void { - this.matomoService.trackPageView('DMP Editor'); + this.analyticsService.trackPageView(AnalyticsService.DmpEditor); + super.ngOnInit(); if (this.isNew === false && this.step === 0) this.nextStep(); diff --git a/dmp-frontend/src/app/ui/dmp/listing/criteria/dmp-criteria-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/listing/criteria/dmp-criteria-dialog.component.ts index 45f23a416..708e4f9a0 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/criteria/dmp-criteria-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/criteria/dmp-criteria-dialog.component.ts @@ -2,8 +2,8 @@ import { Inject, Component, ViewChild, OnInit, Output, EventEmitter } from '@ang import { MAT_DIALOG_DATA, MatDialogRef } from '@angular/material/dialog'; import { DmpCriteriaComponent } from './dmp-criteria.component'; import { UntypedFormGroup } from '@angular/forms'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'dmp-criteria-dialog-component', @@ -18,13 +18,14 @@ export class DmpCriteriaDialogComponent implements OnInit { constructor( public dialogRef: MatDialogRef, private httpClient: HttpClient, - private matomoService: MatomoService, + private analyticsService: AnalyticsService, + @Inject(MAT_DIALOG_DATA) public data: { showGrant: boolean, isPublic: boolean, criteria: DmpCriteria, formGroup: UntypedFormGroup, updateDataFn: Function } ) { } ngOnInit() { - this.matomoService.trackPageView('DMP Criteria'); + this.analyticsService.trackPageView(AnalyticsService.DmpCriteriaDialog); this.criteria.setCriteria(this.data.criteria); } diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html index 09c0fcadd..bb1bc1593 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.html @@ -29,10 +29,10 @@
-
+
{{'DMP-LISTING.SORT-BY' | translate}}:
-
+
{{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}} @@ -42,7 +42,13 @@
-
+
+ +
+
{{ 'GENERAL.ACTIONS.TAKE-A-TOUR'| translate }} diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts index c5ff0c96b..74e6c16e9 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.ts @@ -9,7 +9,6 @@ import { ActivatedRoute, Router } from '@angular/router'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { AuthService } from '@app/core/services/auth/auth.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; @@ -34,6 +33,8 @@ import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; +import { SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-dmp-listing-component', @@ -59,6 +60,23 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr scrollbar: boolean; order = RecentActivityOrder; + private _sortDirection: SortDirection = SortDirection.Descending; //SortDirection.Descending: "-" + set sortDirection(sortDirection: SortDirection) { + this._sortDirection = sortDirection; + } + get isAscending(): boolean { + return this._sortDirection == SortDirection.Ascending; + } + get isDescending(): boolean { + return this._sortDirection == SortDirection.Descending; + } + get sortingDirectionPrefix(): string { + return this.isAscending ? "+" : "-"; + } + get sortingTooltipText(): string { + return this.isAscending ? this.language.instant('DMP-LISTING.ACTIONS.TOGGLE-ΑSCENDING') : this.language.instant('DMP-LISTING.ACTIONS.TOGGLE-DESCENDING'); + } + constructor( private dmpService: DmpService, private router: Router, @@ -71,13 +89,15 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr private authService: AuthService, private guidedTourService: GuidedTourService, private httpClient: HttpClient, - private matomoService: MatomoService + private analyticsService: AnalyticsService, + ) { super(); } ngOnInit() { - this.matomoService.trackPageView('DMPs'); + this.analyticsService.trackPageView(AnalyticsService.DmpListing); + this.isPublic = this.router.url.startsWith('/explore-plans'); if (this.isPublic) { //TODO refactor @@ -167,11 +187,11 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr orderByChanged(){ if (this.formGroup.get('order').value == RecentActivityOrder.Status){ - this.lookup.order = { items: ['-' + nameof(x => x.status)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.status)] }; } else if(this.formGroup.get('order').value == RecentActivityOrder.Label){ - this.lookup.order = { items: ['-' + nameof(x => x.label)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.label)] }; }else{ - this.lookup.order = { items: ['-' + nameof(x => x.updatedAt)] }; + this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.updatedAt)] }; } this.refresh(this.lookup); } @@ -386,4 +406,9 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr public hasLikeCriteria(): boolean { return this.lookup.like !== undefined && this.lookup.like !== null; } + + toggleSortDirection(): void { + this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; + this.orderByChanged(); + } } diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index e4a13e752..a177f2e04 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -10,7 +10,6 @@ import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.servic import { DmpService } from '@app/core/services/dmp/dmp.service'; import { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service'; import { LockService } from '@app/core/services/lock/lock.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { ReferenceService } from '@app/core/services/reference/reference.service'; @@ -30,6 +29,7 @@ import { AppPermission } from '@app/core/common/enum/permission.enum'; import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type'; import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { DmpDeleteDialogComponent } from '../../dmp-delete-dialog/dmp-delete-dialog.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-dmp-listing-item-component', @@ -61,16 +61,17 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { private lockService: LockService, private location: Location, private httpClient: HttpClient, - private matomoService: MatomoService, public referenceService: ReferenceService, public referenceTypeService: ReferenceTypeService, public fileTransformerService: FileTransformerService, - private fileUtils: FileUtils) { + private fileUtils: FileUtils, + private analyticsService: AnalyticsService, + ) { super(); } ngOnInit() { - this.matomoService.trackPageView('DMP Listing Item'); + this.analyticsService.trackPageView(AnalyticsService.DmpListingItem); if (this.dmp.status == DmpStatus.Draft) { this.isDraft = true; this.isFinalized = false; diff --git a/dmp-frontend/src/app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component.ts index 5e8411926..1a7401de4 100644 --- a/dmp-frontend/src/app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component.ts @@ -3,12 +3,12 @@ import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { Router } from '@angular/router'; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseComponent } from '@common/base/base.component'; import { TranslateService } from '@ngx-translate/core'; import { takeUntil } from 'rxjs/operators'; import { DmpUploadDialogComponent } from '../upload-dialogue/dmp-upload-dialog.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-start-new-dmp', @@ -28,14 +28,14 @@ export class StartNewDmpDialogComponent extends BaseComponent { private language: TranslateService, private dmpService: DmpService, private httpClient: HttpClient, - private matomoService: MatomoService + private analyticsService: AnalyticsService, ) { super(); this.isDialog = data.isDialog; } ngOnInit() { - this.matomoService.trackPageView('Start New DMP Dialog'); + this.analyticsService.trackPageView(AnalyticsService.StartNewDmpDialog); } cancel() { diff --git a/dmp-frontend/src/app/ui/dmp/new/upload-dialogue/dmp-upload-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/new/upload-dialogue/dmp-upload-dialog.component.ts index 284419940..746643e21 100644 --- a/dmp-frontend/src/app/ui/dmp/new/upload-dialogue/dmp-upload-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/new/upload-dialogue/dmp-upload-dialog.component.ts @@ -3,7 +3,7 @@ import { Component, Inject } from '@angular/core'; import { MAT_DIALOG_DATA, MatDialog, MatDialogRef } from '@angular/material/dialog'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; import { BaseComponent } from '@common/base/base.component'; import { Observable } from 'rxjs'; @@ -34,14 +34,15 @@ export class DmpUploadDialogComponent extends BaseComponent { private _service: DmpService, private dialog: MatDialog, private httpClient: HttpClient, - private matomoService: MatomoService, + private analyticsService: AnalyticsService, + @Inject(MAT_DIALOG_DATA) public data: any, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('DMP Upload Dialog'); + this.analyticsService.trackPageView(AnalyticsService.DmpUploadDialog); } cancel() { diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 9fb728bce..054391004 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -78,8 +78,8 @@
- -   + +   {{ dmpReference.reference?.label }},  {{ dmpReference.reference?.label }} diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss index af5c994b1..2444140e1 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss @@ -36,8 +36,9 @@ // ********BUTTONS******** .id-btn { - background: url("../../../../assets/images/orcid.png") no-repeat center; - width: 1em; + background: url("../../../../assets/images/orcid_unauth.png") no-repeat center; + width: 1rem; + height: 1rem; margin-right: 0.3em; align-self: center; } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 06ab83428..f810996f5 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -49,6 +49,7 @@ import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver'; import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type'; import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { DmpDeleteDialogComponent } from '../dmp-delete-dialog/dmp-delete-dialog.component'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-dmp-overview', @@ -103,13 +104,14 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { public referenceService: ReferenceService, public enumUtils: EnumUtils, public fileTransformerService: FileTransformerService, - private referenceTypeService: ReferenceTypeService + private referenceTypeService: ReferenceTypeService, + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('DMP Overview'); + this.analyticsService.trackPageView(AnalyticsService.DmpOverview); // Gets dmp data using parameter id this.route.params .pipe(takeUntil(this._destroyed)) @@ -201,6 +203,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } } + get unauthorizedTootipText(): string { + return this.language.instant('DMP-OVERVIEW.INFOS.UNAUTHORIZED-ORCID'); + } + onFetchingDeletedCallbackError(redirectRoot: string) { this.uiNotificationService.snackBarNotification(this.language.instant('DMP-OVERVIEW.ERROR.DELETED-DMP'), SnackBarNotificationLevel.Error); this.router.navigate([redirectRoot]); diff --git a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts index ffc5ecb95..994b5146e 100644 --- a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts +++ b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts @@ -1,11 +1,11 @@ import { Component, OnInit, Input } from '@angular/core'; import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { BaseComponent } from '@common/base/base.component'; import { takeUntil } from 'rxjs/operators'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-faq-content', @@ -23,11 +23,11 @@ export class FaqContentComponent extends BaseComponent implements OnInit { private supportiveMaterialService: SupportiveMaterialService, private sanitizer: DomSanitizer, private languageService: LanguageService, - private matomoService: MatomoService + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('FAQ'); + this.analyticsService.trackPageView(AnalyticsService.FAQ); this.supportiveMaterialService.getPayload(SupportiveMaterialFieldType.Faq, this.languageService.getCurrentLanguage()) .pipe(takeUntil(this._destroyed)) diff --git a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts index a6945cd14..2af0f968d 100644 --- a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts +++ b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts @@ -3,7 +3,7 @@ import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { BaseComponent } from '@common/base/base.component'; import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; @@ -25,13 +25,14 @@ export class GlossaryContentComponent extends BaseComponent implements OnInit { private supportiveMaterialService: SupportiveMaterialService, private sanitizer: DomSanitizer, private languageService: LanguageService, - private matomoService: MatomoService, private translate: TranslateService, - private router: Router + private router: Router, + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Glossary'); + this.analyticsService.trackPageView(AnalyticsService.Glossary); + this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/glossary'])); diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.ts b/dmp-frontend/src/app/ui/navbar/navbar.component.ts index 46269c046..dec52e62c 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.ts +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.ts @@ -7,7 +7,6 @@ import { AppRole } from '@app/core/common/enum/app-role'; import { User } from '@app/core/model/user/user'; import { AuthService, LoginStatus } from '@app/core/services/auth/auth.service'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { ProgressIndicationService } from '@app/core/services/progress-indication/progress-indication-service'; import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice'; import { BaseComponent } from '@common/base/base.component'; @@ -26,6 +25,7 @@ import { nameof } from 'ts-simple-nameof'; import { StorageFile } from '@app/core/model/storage-file/storage-file'; import { StorageFileService } from '@app/core/services/storage-file/storage-file.service'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-navbar', @@ -56,13 +56,13 @@ export class NavbarComponent extends BaseComponent implements OnInit { private dialog: MatDialog, private progressIndicationService: ProgressIndicationService, private languageService: LanguageService, - private matomoService: MatomoService, private sidenavService: SideNavService, private tenantConfigurationService: TenantConfigurationService, private inappNotificationService: InAppNotificationService, private configurationService: ConfigurationService, private storageFileService: StorageFileService, - private sanitizer: DomSanitizer + private sanitizer: DomSanitizer, + private analyticsService: AnalyticsService, ) { super(); this.location = location; @@ -72,7 +72,8 @@ export class NavbarComponent extends BaseComponent implements OnInit { } ngOnInit() { - this.matomoService.trackPageView('Navbar'); + this.analyticsService.trackPageView(AnalyticsService.Navbar); + this.currentRoute = this.router.url; // this.listTitles = GENERAL_ROUTES.filter(listTitle => listTitle); // this.listTitles.push(DMP_ROUTES.filter(listTitle => listTitle)); diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/sidebar-footer.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/sidebar-footer.component.ts index b05e0868d..7afb06f34 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/sidebar-footer.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/sidebar-footer.component.ts @@ -16,7 +16,7 @@ import { takeUntil } from 'rxjs/operators'; import { AuthService } from "@app/core/services/auth/auth.service"; import { UserGuideDialogComponent } from '@app/ui/user-guide/dialog/user-guide-dialog.component'; import { HttpClient } from '@angular/common/http'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-sidebar-footer', @@ -37,13 +37,14 @@ export class SidebarFooterComponent extends BaseComponent implements OnInit { private formService: FormService, private authentication: AuthService, private httpClient: HttpClient, - private matomoService: MatomoService + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Sidebar Footer'); + this.analyticsService.trackPageView(AnalyticsService.SidebarFooter); + this.contactEmailFormModel = new ContactEmailFormModel(); this.formGroup = this.contactEmailFormModel.buildForm(); } diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts index 027298717..5677a420e 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar-footer/terms/terms.component.ts @@ -3,7 +3,7 @@ import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; import { Router } from '@angular/router'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { BaseComponent } from '@common/base/base.component'; import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; @@ -23,13 +23,14 @@ export class TermsComponent extends BaseComponent implements OnInit { private supportiveMaterialService: SupportiveMaterialService, private sanitizer: DomSanitizer, private languageService: LanguageService, - private matomoService: MatomoService, private translate: TranslateService, - private router: Router + private router: Router, + private analyticsService: AnalyticsService, ) { super(); } ngOnInit() { - this.matomoService.trackPageView('Terms of Service'); + this.analyticsService.trackPageView(AnalyticsService.Terms); + this.translate.onLangChange.subscribe((event: LangChangeEvent) => { this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/terms-and-conditions'])); }); diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 86362a1c4..9f8460a7e 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -3,7 +3,6 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { TranslateService } from '@ngx-translate/core'; import { AppRole } from '../../core/common/enum/app-role'; import { AuthService, LoginStatus } from '../../core/services/auth/auth.service'; @@ -11,6 +10,7 @@ import { LanguageDialogComponent } from '../language/dialog/language-dialog.comp import { UserDialogComponent } from '../navbar/user-dialog/user-dialog.component'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { takeUntil } from 'rxjs/operators'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; declare interface RouteInfo { path: string; @@ -49,12 +49,12 @@ export class SidebarComponent implements OnInit { public router: Router, private location: Location, private httpClient: HttpClient, - private matomoService: MatomoService - ) { - } + private analyticsService: AnalyticsService, + ) { } ngOnInit() { - this.matomoService.trackPageView('Sidebar'); + this.analyticsService.trackPageView(AnalyticsService.Sidebar); + this.currentRoute = this.router.url; this.authentication.getAuthenticationStateObservable().pipe().subscribe(authenticationState => { diff --git a/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts b/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts index 67337e15e..893572b1d 100644 --- a/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts +++ b/dmp-frontend/src/app/ui/supportive-material-editor/supportive-material-editor.component.ts @@ -6,7 +6,6 @@ import { TranslateService } from '@ngx-translate/core'; import { ActivatedRoute, Router } from '@angular/router'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { SupportiveMaterial, SupportiveMaterialPersist } from '@app/core/model/supportive-material/supportive-material'; @@ -74,7 +73,6 @@ export class SupportiveMaterialEditorComponent extends BaseEditor this.scroll(ev)); this.tocScrollEvent = ((ev) => { this.activeToc(ev); diff --git a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts index 85b969eee..b415aab3d 100644 --- a/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts +++ b/dmp-frontend/src/app/ui/user-profile/user-profile.component.ts @@ -11,7 +11,6 @@ import { AuthService } from '@app/core/services/auth/auth.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { CultureService } from '@app/core/services/culture/culture-service'; import { LanguageService } from '@app/core/services/language/language.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { UserService } from '@app/core/services/user/user.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; @@ -39,6 +38,7 @@ import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/sing import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Tenant } from '@app/core/model/tenant/tenant'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-user-profile', @@ -84,13 +84,13 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes private dialog: MatDialog, public enumUtils: EnumUtils, private httpClient: HttpClient, - private matomoService: MatomoService, private formBuilder: UntypedFormBuilder, private keycloakService: KeycloakService, private principalService: PrincipalService, private formService: FormService, private referenceService: ReferenceService, - private referenceTypeService: ReferenceTypeService + private referenceTypeService: ReferenceTypeService, + private analyticsService: AnalyticsService, ) { super(); this.languages = this.languageService.getAvailableLanguagesCodes(); @@ -118,7 +118,8 @@ export class UserProfileComponent extends BaseComponent implements OnInit, OnDes this.tenantFormGroup = this.formBuilder.group({ tenantCode: [this.authService.selectedTenant(), [Validators.required]] }); - this.matomoService.trackPageView('User Profile'); + this.analyticsService.trackPageView(AnalyticsService.UserProfile); + this.organisationsSingleAutoCompleteConfiguration = this.referenceService.getSingleAutocompleteSearchConfiguration(this.referenceTypeService.getOrganizationReferenceType(), null); this.route.params .pipe(takeUntil(this._destroyed)) diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index b2ea407ea..04c454b74 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -633,7 +633,9 @@ "CLONE": "Clone", "DELETE": "Delete", "DEPOSIT": "Deposit", - "EXPORT": "Export" + "EXPORT": "Export", + "TOGGLE-DESCENDING": "Order by ascending", + "TOGGLE-ΑSCENDING": "Order by descending" }, "EMPTY-LIST": "Nothing here yet." }, @@ -709,6 +711,9 @@ }, "ROLES": { "ALL-SECTIONS": "All Sections" + }, + "INFOS": { + "UNAUTHORIZED-ORCID": "This ORCID is entered by the Plan creators, without further acknowledgement of the owner." } }, "DESCRIPTION-OVERVIEW": { @@ -759,6 +764,9 @@ "FINALISE-POPUP": {}, "ROLES": { "ALL-SECTIONS": "All Sections" + }, + "INFOS": { + "UNAUTHORIZED-ORCID": "This ORCID is entered by the Plan creators, without further acknowledgement of the owner." } }, "DESCRIPTION-LISTING": { @@ -780,7 +788,9 @@ "EXPORT": "Export", "INVITE-SHORT": "Invite", "DELETE": "Delete", - "COPY-DESCRIPTION": "Copy Description" + "COPY-DESCRIPTION": "Copy Description", + "TOGGLE-DESCENDING": "Order by ascending", + "TOGGLE-ΑSCENDING": "Order by descending" }, "STATES": { "EDITED": "Edited", diff --git a/dmp-frontend/src/assets/images/login/orcid_unauth.png b/dmp-frontend/src/assets/images/login/orcid_unauth.png new file mode 100644 index 000000000..904d6177e Binary files /dev/null and b/dmp-frontend/src/assets/images/login/orcid_unauth.png differ diff --git a/dmp-frontend/src/assets/images/orcid_unauth.png b/dmp-frontend/src/assets/images/orcid_unauth.png new file mode 100644 index 000000000..904d6177e Binary files /dev/null and b/dmp-frontend/src/assets/images/orcid_unauth.png differ diff --git a/dmp-frontend/src/notification-service/ui/admin/notification-template/editor/notification-template-editor.component.ts b/dmp-frontend/src/notification-service/ui/admin/notification-template/editor/notification-template-editor.component.ts index fd2943a11..afe18a1da 100644 --- a/dmp-frontend/src/notification-service/ui/admin/notification-template/editor/notification-template-editor.component.ts +++ b/dmp-frontend/src/notification-service/ui/admin/notification-template/editor/notification-template-editor.component.ts @@ -18,7 +18,6 @@ import { FilterService } from '@common/modules/text-filter/filter-service'; import { DatePipe } from '@angular/common'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; import { NotificationServiceEnumUtils } from '@notification-service/core/formatting/enum-utils.service'; -import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { NotificationTemplateEditorService } from './notification-template-editor.service'; import { Guid } from '@common/types/guid'; import { NotificationTemplateEditorResolver } from './notification-template-editor.resolver'; @@ -37,6 +36,7 @@ import { NotificationType } from '@notification-service/core/enum/notification-t import { EmailOverrideMode } from '@notification-service/core/enum/email-override-mode'; import { NotificationDataType } from '@notification-service/core/enum/notification-data-type'; import { Title } from '@angular/platform-browser'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-notification-template-editor', @@ -99,8 +99,8 @@ export class NotificationTemplateEditorComponent extends BaseEditor data = query.collectAs(lookup.getProject()); List models = this.builderFactory.builder(InAppNotificationBuilder.class).build(lookup.getProject(), data); long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); @@ -88,7 +88,7 @@ public class InAppNotificationController { @GetMapping("{id}") @Transactional - public InAppNotification Get(@PathVariable UUID id, FieldSet fieldSet, Locale locale) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { + public InAppNotification Get(@PathVariable UUID id, FieldSet fieldSet) throws MyApplicationException, MyForbiddenException, MyNotFoundException, InvalidApplicationException { logger.debug(new MapLogEntry("retrieving" + InAppNotification.class.getSimpleName()).And("id", id).And("fields", fieldSet)); UUID userId = this.userScope.getUserId(); diff --git a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationController.java b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationController.java index 0cc2889da..abd8b9607 100644 --- a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationController.java +++ b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationController.java @@ -64,7 +64,7 @@ public class NotificationController { this.censorFactory.censor(NotificationCensor.class).censor(lookup.getProject()); - NotificationQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + NotificationQuery query = lookup.enrich(this.queryFactory).disableTracking().authorize(AuthorizationFlags.OwnerOrPermission); List data = query.collectAs(lookup.getProject()); List models = this.builderFactory.builder(NotificationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); diff --git a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationTemplateController.java b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationTemplateController.java index 44bd2482d..eb4cf3f45 100644 --- a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationTemplateController.java +++ b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/NotificationTemplateController.java @@ -65,7 +65,7 @@ public class NotificationTemplateController { this.censorFactory.censor(NotificationTemplateCensor.class).censor(lookup.getProject()); - NotificationTemplateQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + NotificationTemplateQuery query = lookup.enrich(this.queryFactory).disableTracking().authorize(AuthorizationFlags.OwnerOrPermission); List data = query.collectAs(lookup.getProject()); List models = this.builderFactory.builder(NotificationTemplateBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); diff --git a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/PrincipalController.java b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/PrincipalController.java index 21438e8cd..71b1dfd47 100644 --- a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/PrincipalController.java +++ b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/PrincipalController.java @@ -29,18 +29,15 @@ public class PrincipalController { private final CurrentPrincipalResolver currentPrincipalResolver; private final AccountBuilder accountBuilder; - private final ClaimExtractor claimExtractor; @Autowired public PrincipalController( CurrentPrincipalResolver currentPrincipalResolver, AccountBuilder accountBuilder, - AuditService auditService, - ClaimExtractor claimExtractor) { + AuditService auditService) { this.currentPrincipalResolver = currentPrincipalResolver; this.accountBuilder = accountBuilder; this.auditService = auditService; - this.claimExtractor = claimExtractor; } @GetMapping("me") diff --git a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/TenantConfigurationController.java b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/TenantConfigurationController.java index 0f258397f..bfd19884a 100644 --- a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/TenantConfigurationController.java +++ b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/TenantConfigurationController.java @@ -86,7 +86,7 @@ public class TenantConfigurationController { this.censorFactory.censor(TenantConfigurationCensor.class).censor(lookup.getProject(), null); - TenantConfigurationQuery query = lookup.enrich(this.queryFactory).authorize(AuthorizationFlags.OwnerOrPermission); + TenantConfigurationQuery query = lookup.enrich(this.queryFactory).disableTracking().authorize(AuthorizationFlags.OwnerOrPermission); List data = query.collectAs(lookup.getProject()); List models = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); @@ -103,7 +103,7 @@ public class TenantConfigurationController { this.censorFactory.censor(TenantConfigurationCensor.class).censor(fieldSet, null); - TenantConfigurationQuery query = this.queryFactory.query(TenantConfigurationQuery.class).disableTracking()authorize(AuthorizationFlags.OwnerOrPermission).ids(id); + TenantConfigurationQuery query = this.queryFactory.query(TenantConfigurationQuery.class).disableTracking().authorize(AuthorizationFlags.OwnerOrPermission).ids(id); TenantConfiguration model = this.builderFactory.builder(TenantConfigurationBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(fieldSet, query.firstAs(fieldSet)); if (model == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{id, TenantConfiguration.class.getSimpleName()}, LocaleContextHolder.getLocale())); diff --git a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/UserNotificationPreferenceController.java b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/UserNotificationPreferenceController.java index 35f37a802..22a46598f 100644 --- a/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/UserNotificationPreferenceController.java +++ b/notification-service/notification-web/src/main/java/gr/cite/notification/web/controllers/UserNotificationPreferenceController.java @@ -76,7 +76,7 @@ public class UserNotificationPreferenceController { this.censorFactory.censor(UserNotificationPreferenceCensor.class).censor(lookup.getProject(), null); - UserNotificationPreferenceQuery query = lookup.enrich(this.queryFactory); + UserNotificationPreferenceQuery query = lookup.enrich(this.queryFactory).disableTracking(); List data = query.collectAs(lookup.getProject()); List models = this.builderFactory.builder(UserNotificationPreferenceBuilder.class).authorize(AuthorizationFlags.OwnerOrPermission).build(lookup.getProject(), data); long count = (lookup.getMetadata() != null && lookup.getMetadata().getCountAll()) ? query.count() : models.size(); diff --git a/notification-service/pom.xml b/notification-service/pom.xml index 5b7f1b0f5..76f3dc093 100644 --- a/notification-service/pom.xml +++ b/notification-service/pom.xml @@ -13,7 +13,7 @@ org.springframework.boot spring-boot-starter-parent - 3.2.1 + 3.2.5 @@ -43,7 +43,7 @@ org.hibernate.orm hibernate-core compile - 6.3.1.Final + 6.5.2.Final org.hibernate.orm @@ -71,7 +71,7 @@ com.fasterxml.jackson.datatype jackson-datatype-jsr310 - 2.13.3 + 2.17.0 @@ -107,7 +107,7 @@ gr.cite data-tools - 2.1.2 + 2.1.4 @@ -119,7 +119,7 @@ gr.cite validation - 3.0.2 + 3.0.3