From 40bffe71e5ac54c4e459646abdce8cccee6a8cc1 Mon Sep 17 00:00:00 2001 From: Sofia Papacharalampous Date: Tue, 11 Jun 2024 17:43:54 +0300 Subject: [PATCH 1/7] remove token from auditing --- .../main/java/org/opencdmp/controllers/UserController.java | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/backend/web/src/main/java/org/opencdmp/controllers/UserController.java b/backend/web/src/main/java/org/opencdmp/controllers/UserController.java index e246f1de2..fcf262973 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/UserController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/UserController.java @@ -301,9 +301,7 @@ public class UserController { public Boolean getUserTokenPermission(@PathVariable("token") String token) throws InvalidApplicationException, IOException { logger.debug(new MapLogEntry("allow merge account to user").And("token", token)); - this.auditService.track(AuditableAction.User_AllowMergeAccount, Map.ofEntries( - new AbstractMap.SimpleEntry("token", token) - )); + this.auditService.track(AuditableAction.User_AllowMergeAccount); return this.userTypeService.doesTokenBelongToLoggedInUser(token); } From 7b2507bbf19fedebf13bdd9aeec1dd5936c3143a Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 11 Jun 2024 18:22:35 +0300 Subject: [PATCH 2/7] add description annotation created notification template --- .../resources/config/notification-devel.yml | 51 +++ .../email/body.en.html | 304 ++++++++++++++++++ .../email/subject.en.txt | 1 + .../inapp/body.en.html | 12 + .../inapp/subject.en.txt | 1 + 5 files changed, 369 insertions(+) create mode 100644 notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/body.en.html create mode 100644 notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/subject.en.txt create mode 100644 notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/body.en.html create mode 100644 notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/subject.en.txt diff --git a/notification-service/notification-web/src/main/resources/config/notification-devel.yml b/notification-service/notification-web/src/main/resources/config/notification-devel.yml index 75a6ed388..11e23d889 100644 --- a/notification-service/notification-web/src/main/resources/config/notification-devel.yml +++ b/notification-service/notification-web/src/main/resources/config/notification-devel.yml @@ -24,6 +24,9 @@ notification: - #descriptionFinalised type: 33790bad-94d4-488a-8ee2-7f6295ca18ea contacts: [ inapp, email ] + - #descriptionAnnotationCreated + type: db1e99d2-a240-4e75-9bb2-ef25b234c1f0 + contacts: [ inapp, email ] - #mergeAcountConfirmation type: BFE68845-CB05-4C5A-A03D-29161A7C9660 contacts: [ email ] @@ -196,6 +199,31 @@ notification: bcc-mode: 0 allow-attachments: false cipher-fields: [ ] + - #descriptionAnnotationCreated + key: db1e99d2-a240-4e75-9bb2-ef25b234c1f0 + subject-path: classpath:notification_templates/descriptionannotationcreated/email/subject.{language}.txt + subject-field-options: + mandatory: [ ] + optional: [ ] + body-path: classpath:notification_templates/descriptionannotationcreated/email/body.{language}.html + body-field-options: + mandatory: [ "{reasonName}", "{name}", "{installation-url}", "{id}" ] + optional: + - key: "{recipient}" + value: + - key: "{tenant-url-path}" + value: + formatting: + '[{reasonName}]': null + '[{name}]': null + '[{recipient}]': null + '[{tenant-url-path}]': null + cc: [ ] + cc-mode: 0 + bcc: [ ] + bcc-mode: 0 + allow-attachments: false + cipher-fields: [ ] - #mergeAccountConfirmation key: BFE68845-CB05-4C5A-A03D-29161A7C9660 subject-path: classpath:notification_templates/mergeacountconfirmation/email/subject.{language}.txt @@ -449,6 +477,29 @@ notification: '[{tenant-url-path}]': null priority-key: null cipher-fields: [ ] + - #descriptionAnnotationCreated + key: db1e99d2-a240-4e75-9bb2-ef25b234c1f0 + subject-path: classpath:notification_templates/descriptionannotationcreated/inapp/subject.{language}.txt + subject-field-options: + mandatory: [ ] + optional: [ ] + body-path: classpath:notification_templates/descriptionannotationcreated/inapp/body.{language}.html + body-field-options: + mandatory: [ "{reasonName}", "{name}", "{installation-url}", "{id}" ] + optional: + - key: "{recipient}" + value: + - key: "{tenant-url-path}" + value: + formatting: + '[{reasonName}]': null + '[{name}]': null + '[{installation-url}]': null + '[{id}]': null + '[{recipient}]': null + '[{tenant-url-path}]': null + priority-key: null + cipher-fields: [ ] - #mergeAccountConfirmation key: BFE68845-CB05-4C5A-A03D-29161A7C9660 subject-path: classpath:notification_templates/mergeacountconfirmation/inapp/subject.{language}.txt diff --git a/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/body.en.html b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/body.en.html new file mode 100644 index 000000000..dc9b2e8de --- /dev/null +++ b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/body.en.html @@ -0,0 +1,304 @@ + + + + + + OpenCDMP Notification + + + + + + + + + +
  +
+ + + This is preheader text. Some clients will show this text as a preview. + + + + + + + + +
+ + + + +
+

Dear {recipient},

+

{reasonName} made a comment on the Description {name}.

+ + + + + + + +
+ + + + + + +
Click here to view it.
+
+ +
+
+ + + + + + +
+
 
+ + \ No newline at end of file diff --git a/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/subject.en.txt b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/subject.en.txt new file mode 100644 index 000000000..aa807d661 --- /dev/null +++ b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/email/subject.en.txt @@ -0,0 +1 @@ +OpenCDMP - Comment for Description \ No newline at end of file diff --git a/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/body.en.html b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/body.en.html new file mode 100644 index 000000000..d16a3e0b2 --- /dev/null +++ b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/body.en.html @@ -0,0 +1,12 @@ + + + + + + + +

Dear {recipient},

+

{reasonName} made a comment on the Description {name}.

+ Click here to view it. + + \ No newline at end of file diff --git a/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/subject.en.txt b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/subject.en.txt new file mode 100644 index 000000000..aa807d661 --- /dev/null +++ b/notification-service/notification-web/src/main/resources/notification_templates/descriptionannotationcreated/inapp/subject.en.txt @@ -0,0 +1 @@ +OpenCDMP - Comment for Description \ No newline at end of file From 0f8bee6210f6ddcb1ce1e0db18bcc10af3248b2b Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 11 Jun 2024 18:26:43 +0300 Subject: [PATCH 3/7] annotation created event after annotation persist --- .../src/main/resources/config/queue.yml | 1 + .../common/JsonHandlingService.java | 31 +++-- .../OutboxIntegrationEventConfigurer.java | 6 +- .../outbox/OutboxIntegrationEvent.java | 2 + .../outbox/OutboxProperties.java | 11 +- .../outbox/OutboxRepositoryImpl.java | 33 ++++- .../AnnotationCreatedEvent.java | 114 ++++++++++++++++++ ...otationCreatedIntegrationEventHandler.java | 7 ++ ...ionCreatedIntegrationEventHandlerImpl.java | 36 ++++++ .../service/annotation/AnnotationService.java | 2 +- .../annotation/AnnotationServiceImpl.java | 38 ++++-- 11 files changed, 259 insertions(+), 22 deletions(-) create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedEvent.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandler.java create mode 100644 annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandlerImpl.java diff --git a/annotation-service/annotation-web/src/main/resources/config/queue.yml b/annotation-service/annotation-web/src/main/resources/config/queue.yml index 11cb67ea1..18cf14d5f 100644 --- a/annotation-service/annotation-web/src/main/resources/config/queue.yml +++ b/annotation-service/annotation-web/src/main/resources/config/queue.yml @@ -25,6 +25,7 @@ queue: enable: false options: exchange: null + annotation-created-topic: annotation.created rabbitmq: enable: false interval-seconds: 3 diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/JsonHandlingService.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/JsonHandlingService.java index e1b68a157..0ff1467bc 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/common/JsonHandlingService.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/common/JsonHandlingService.java @@ -2,41 +2,56 @@ package gr.cite.annotation.common; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.ObjectReader; +import com.fasterxml.jackson.datatype.jsr310.JavaTimeModule; import gr.cite.tools.logging.LoggerService; import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; import org.springframework.stereotype.Component; +import java.util.HashMap; +import java.util.Map; + @Component +@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON) public class JsonHandlingService { - private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(JsonHandlingService.class)); - private final ObjectMapper objectMapper = new ObjectMapper(); + private final ObjectMapper objectMapper; + + public JsonHandlingService() { + this.objectMapper = new ObjectMapper(); + this.objectMapper.registerModule(new JavaTimeModule()); + } public String toJson(Object item) throws JsonProcessingException { if (item == null) return null; - return objectMapper.writeValueAsString(item); + return this.objectMapper.writeValueAsString(item); } public String toJsonSafe(Object item) { if (item == null) return null; try { - return objectMapper.writeValueAsString(item); + return this.objectMapper.writeValueAsString(item); } catch (Exception ex) { - logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex); return null; } } public T fromJson(Class type, String json) throws JsonProcessingException { if (json == null) return null; - return objectMapper.readValue(json, type); + return this.objectMapper.readValue(json, type); + } + + public HashMap mapFromJson(String json) throws JsonProcessingException { + ObjectReader reader = this.objectMapper.readerFor(Map.class); + return reader.readValue(json); } public T fromJsonSafe(Class type, String json) { if (json == null) return null; try { - return objectMapper.readValue(json, type); + return this.objectMapper.readValue(json, type); } catch (Exception ex) { - logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex); return null; } } 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 6f035d511..7cb7306cf 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 @@ -26,9 +26,11 @@ import java.util.UUID; @ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false) public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { private final ApplicationContext applicationContext; + private final OutboxProperties outboxProperties; - public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext) { + public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties) { this.applicationContext = applicationContext; + this.outboxProperties = outboxProperties; } @Bean @@ -64,7 +66,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer { @Bean public OutboxRepository outboxRepositoryCreator() { - return new OutboxRepositoryImpl(this.applicationContext); + return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties); } } diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxIntegrationEvent.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxIntegrationEvent.java index ceca4f86e..1d2306158 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxIntegrationEvent.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxIntegrationEvent.java @@ -6,6 +6,8 @@ import gr.cite.rabbitmq.IntegrationEvent; @JsonIgnoreProperties(ignoreUnknown = true) public class OutboxIntegrationEvent extends IntegrationEvent { + + public static final String ANNOTATION_CREATED = "ANNOTATION_CREATED"; private TrackedEvent event; public TrackedEvent getEvent() { diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxProperties.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxProperties.java index 2130633a6..119d049e9 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxProperties.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/OutboxProperties.java @@ -7,13 +7,20 @@ public class OutboxProperties { private final String exchange; + private final String annotationCreatedTopic; - public OutboxProperties(String exchange - ) { + + public OutboxProperties(String exchange, + String annotationCreatedTopic) { this.exchange = exchange; + this.annotationCreatedTopic = annotationCreatedTopic; } public String getExchange() { return exchange; } + + public String getAnnotationCreatedTopic() { + return annotationCreatedTopic; + } } 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 6c39eb75a..36f72a52d 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,12 +33,16 @@ public class OutboxRepositoryImpl implements OutboxRepository { @PersistenceUnit private EntityManagerFactory entityManagerFactory; + private final JsonHandlingService jsonHandlingService; + private final OutboxProperties outboxProperties; public OutboxRepositoryImpl( - ApplicationContext applicationContext - ) { + ApplicationContext applicationContext, + OutboxProperties outboxProperties) { this.applicationContext = applicationContext; + this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class); + this.outboxProperties = outboxProperties; } @Override @@ -370,10 +374,35 @@ public class OutboxRepositoryImpl implements OutboxRepository { private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) { String routingKey; switch (event.getType()) { + case OutboxIntegrationEvent.ANNOTATION_CREATED: { + routingKey = this.outboxProperties.getAnnotationCreatedTopic(); + break; + } default: { logger.error("unrecognized outgoing integration event {}. Skipping...", event.getType()); return null; } } + + UUID correlationId = UUID.randomUUID(); + if (event.getEvent() != null) + event.getEvent().setTrackingContextTag(correlationId.toString()); + event.setMessage(this.jsonHandlingService.toJsonSafe(event.getEvent())); + + QueueOutboxEntity queueMessage = new QueueOutboxEntity(); + queueMessage.setId(UUID.randomUUID()); + queueMessage.setTenantId(event.getTenantId()); + queueMessage.setExchange(this.outboxProperties.getExchange()); + queueMessage.setRoute(routingKey); + queueMessage.setMessageId(event.getMessageId()); + queueMessage.setMessage(this.jsonHandlingService.toJsonSafe(event)); + queueMessage.setIsActive(IsActive.Active); + queueMessage.setNotifyStatus(QueueOutboxNotifyStatus.PENDING); + queueMessage.setRetryCount(0); + queueMessage.setCreatedAt(Instant.now()); + queueMessage.setUpdatedAt(Instant.now()); + + return queueMessage; + } } \ No newline at end of file diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedEvent.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedEvent.java new file mode 100644 index 000000000..a79dea3e3 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedEvent.java @@ -0,0 +1,114 @@ +package gr.cite.annotation.integrationevent.outbox.annotationcreated; + +import gr.cite.annotation.common.enums.AnnotationProtectionType; +import gr.cite.annotation.integrationevent.TrackedEvent; + +import java.time.Instant; +import java.util.UUID; + +public class AnnotationCreatedEvent extends TrackedEvent { + + private UUID id; + + private UUID entityId; + + private String entityType; + + private String anchor; + + private String payload; + + private UUID subjectId; + + private UUID threadId; + + private UUID parentId; + + private AnnotationProtectionType protectionType; + + private Instant timeStamp; + + public AnnotationCreatedEvent() { + } + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getEntityId() { + return entityId; + } + + public void setEntityId(UUID entityId) { + this.entityId = entityId; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String getAnchor() { + return anchor; + } + + public void setAnchor(String anchor) { + this.anchor = anchor; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public UUID getSubjectId() { + return subjectId; + } + + public void setSubjectId(UUID subjectId) { + this.subjectId = subjectId; + } + + public UUID getThreadId() { + return threadId; + } + + public void setThreadId(UUID threadId) { + this.threadId = threadId; + } + + public UUID getParentId() { + return parentId; + } + + public void setParentId(UUID parentId) { + this.parentId = parentId; + } + + public AnnotationProtectionType getProtectionType() { + return protectionType; + } + + public void setProtectionType(AnnotationProtectionType protectionType) { + this.protectionType = protectionType; + } + + public Instant getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(Instant timeStamp) { + this.timeStamp = timeStamp; + } +} + diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandler.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandler.java new file mode 100644 index 000000000..440572ece --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandler.java @@ -0,0 +1,7 @@ +package gr.cite.annotation.integrationevent.outbox.annotationcreated; + +import javax.management.InvalidApplicationException; + +public interface AnnotationCreatedIntegrationEventHandler { + void handle(AnnotationCreatedEvent event) throws InvalidApplicationException; +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandlerImpl.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandlerImpl.java new file mode 100644 index 000000000..b3b15cd52 --- /dev/null +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/integrationevent/outbox/annotationcreated/AnnotationCreatedIntegrationEventHandlerImpl.java @@ -0,0 +1,36 @@ +package gr.cite.annotation.integrationevent.outbox.annotationcreated; + +import gr.cite.annotation.common.scope.tenant.TenantScope; +import gr.cite.annotation.integrationevent.outbox.OutboxIntegrationEvent; +import gr.cite.annotation.integrationevent.outbox.OutboxService; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.web.context.annotation.RequestScope; + +import javax.management.InvalidApplicationException; +import java.util.UUID; + +@Component +@RequestScope +public class AnnotationCreatedIntegrationEventHandlerImpl implements AnnotationCreatedIntegrationEventHandler { + + private final OutboxService outboxService; + private final TenantScope tenantScope; + + @Autowired + public AnnotationCreatedIntegrationEventHandlerImpl( + OutboxService outboxService, TenantScope tenantScope) { + this.outboxService = outboxService; + this.tenantScope = tenantScope; + } + + @Override + public void handle(AnnotationCreatedEvent event) throws InvalidApplicationException { + OutboxIntegrationEvent message = new OutboxIntegrationEvent(); + message.setMessageId(UUID.randomUUID()); + message.setType(OutboxIntegrationEvent.ANNOTATION_CREATED); + message.setEvent(event); + if (this.tenantScope.isSet()) message.setTenantId(this.tenantScope.getTenant()); + this.outboxService.publish(message); + } +} diff --git a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java index 232d5f22e..013ba7f53 100644 --- a/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java +++ b/annotation-service/annotation/src/main/java/gr/cite/annotation/service/annotation/AnnotationService.java @@ -13,7 +13,7 @@ import java.util.UUID; public interface AnnotationService { - Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException; + Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException; void deleteAndSave(UUID id) throws InvalidApplicationException; 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 7efc4e6f8..6e29e5e3c 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 @@ -8,6 +8,8 @@ import gr.cite.annotation.common.enums.IsActive; import gr.cite.annotation.common.scope.user.UserScope; import gr.cite.annotation.data.AnnotationEntity; import gr.cite.annotation.data.TenantEntityManager; +import gr.cite.annotation.integrationevent.outbox.annotationcreated.AnnotationCreatedEvent; +import gr.cite.annotation.integrationevent.outbox.annotationcreated.AnnotationCreatedIntegrationEventHandler; import gr.cite.annotation.model.Annotation; import gr.cite.annotation.model.builder.AnnotationBuilder; import gr.cite.annotation.model.deleter.AnnotationDeleter; @@ -30,9 +32,7 @@ import org.springframework.stereotype.Service; import javax.management.InvalidApplicationException; import java.time.Instant; -import java.util.EnumSet; -import java.util.List; -import java.util.UUID; +import java.util.*; @Service public class AnnotationServiceImpl implements AnnotationService { @@ -52,12 +52,14 @@ public class AnnotationServiceImpl implements AnnotationService { private final MessageSource messageSource; + private final AnnotationCreatedIntegrationEventHandler annotationCreatedEventHandler; + public AnnotationServiceImpl( - AuthorizationService authorizationService, - DeleterFactory deleterFactory, + AuthorizationService authorizationService, + DeleterFactory deleterFactory, TenantEntityManager entityManager, - BuilderFactory builderFactory, UserScope userScope, AuthorizationContentResolver authorizationContentResolver, MessageSource messageSource) { + BuilderFactory builderFactory, UserScope userScope, AuthorizationContentResolver authorizationContentResolver, MessageSource messageSource, AnnotationCreatedIntegrationEventHandler annotationCreatedEventHandler) { this.authorizationService = authorizationService; this.deleterFactory = deleterFactory; this.entityManager = entityManager; @@ -65,10 +67,11 @@ public class AnnotationServiceImpl implements AnnotationService { this.userScope = userScope; this.authorizationContentResolver = authorizationContentResolver; this.messageSource = messageSource; + this.annotationCreatedEventHandler = annotationCreatedEventHandler; } @Override - public Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException { + public Annotation persist(AnnotationPersist model, FieldSet fields) throws MyForbiddenException, MyValidationException, MyApplicationException, MyNotFoundException, InvalidApplicationException { logger.debug(new MapLogEntry("persisting annotation").And("model", model).And("fields", fields)); this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.entityAffiliation(model.getEntityId())), Permission.NewAnnotation); @@ -92,9 +95,30 @@ public class AnnotationServiceImpl implements AnnotationService { this.entityManager.flush(); + this.sendAnnotationCreatedEvent(data); + return this.builderFactory.builder(AnnotationBuilder.class).authorize(EnumSet.of(AuthorizationFlags.None)).build(BaseFieldSet.build(fields, Annotation._id), data); } + private void sendAnnotationCreatedEvent(AnnotationEntity annotation) throws InvalidApplicationException { + AnnotationCreatedEvent event = new AnnotationCreatedEvent(); + + event.setId(annotation.getId()); + event.setSubjectId(annotation.getSubjectId()); + event.setEntityId(annotation.getEntityId()); + event.setEntityType(annotation.getEntityType()); + event.setAnchor(annotation.getAnchor()); + event.setPayload(annotation.getPayload()); + event.setThreadId(annotation.getThreadId()); + event.setParentId(annotation.getParentId()); + event.setProtectionType(annotation.getProtectionType()); + event.setTimeStamp(Instant.now()); + + this.annotationCreatedEventHandler.handle(event); + } + + + @Override public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { logger.debug("deleting Annotation: {}", id); From 141a53509c89c954bab012a1c0f3acd0212fc2ec Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 11 Jun 2024 18:35:54 +0300 Subject: [PATCH 4/7] annotation created event in main queue inbox --- .../org/opencdmp/audit/AuditableAction.java | 2 + .../annotation/AnnotationProtectionType.java | 31 +++ .../notification/NotificationProperties.java | 9 + .../integrationevent/AppRabbitConfigurer.java | 13 +- .../inbox/InboxProperties.java | 11 +- .../inbox/InboxRepositoryImpl.java | 13 +- .../inbox/IntegrationEventHandler.java | 4 +- ...notationEntityCreatedIntegrationEvent.java | 189 ++++++++++++++++++ ...nEntityCreatedIntegrationEventHandler.java | 9 + ...ityCreatedIntegrationEventHandlerImpl.java | 178 +++++++++++++++++ .../service/deposit/DepositServiceImpl.java | 8 - .../description/DescriptionServiceImpl.java | 10 - .../resources/config/notification-devel.yml | 1 + .../web/src/main/resources/config/queue.yml | 1 + 14 files changed, 447 insertions(+), 32 deletions(-) create mode 100644 backend/core/src/main/java/org/opencdmp/commons/enums/annotation/AnnotationProtectionType.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEvent.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandler.java create mode 100644 backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandlerImpl.java diff --git a/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java index 76a4465d9..907adb9f4 100644 --- a/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java +++ b/backend/core/src/main/java/org/opencdmp/audit/AuditableAction.java @@ -173,6 +173,8 @@ public class AuditableAction { public static final EventId TenantConfiguration_Persist = new EventId(270002, "TenantConfiguration_Persist"); public static final EventId TenantConfiguration_Delete = new EventId(270003, "TenantConfiguration_Delete"); public static final EventId TenantConfiguration_LookupByType = new EventId(270004, "TenantConfiguration_LookupByType"); + + public static final EventId Annotation_Created_Notify = new EventId(280000, "Annotation_Created_Notify"); diff --git a/backend/core/src/main/java/org/opencdmp/commons/enums/annotation/AnnotationProtectionType.java b/backend/core/src/main/java/org/opencdmp/commons/enums/annotation/AnnotationProtectionType.java new file mode 100644 index 000000000..cfbc79571 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/commons/enums/annotation/AnnotationProtectionType.java @@ -0,0 +1,31 @@ +package org.opencdmp.commons.enums.annotation; + +import com.fasterxml.jackson.annotation.JsonValue; +import org.opencdmp.commons.enums.EnumUtils; +import org.opencdmp.data.converters.enums.DatabaseEnum; + +import java.util.Map; + +public enum AnnotationProtectionType implements DatabaseEnum { + + Private((short) 0), + EntityAccessors((short) 1); + + private final Short value; + + AnnotationProtectionType(Short value) { + this.value = value; + } + + @JsonValue + public Short getValue() { + return value; + } + + private static final Map map = EnumUtils.getEnumValueMap(AnnotationProtectionType.class); + + public static AnnotationProtectionType of(Short i) { + return map.get(i); + } + +} diff --git a/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java index f434964f5..a4e6dc488 100644 --- a/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java +++ b/backend/core/src/main/java/org/opencdmp/commons/notification/NotificationProperties.java @@ -13,6 +13,7 @@ public class NotificationProperties { private UUID dmpFinalisedType; private UUID descriptionModifiedType; private UUID descriptionFinalisedType; + private UUID descriptionAnnotationCreated; private UUID mergeAccountConfirmationType; private UUID removeCredentialConfirmationType; private UUID dmpDepositType; @@ -133,4 +134,12 @@ public class NotificationProperties { public void setContactSupportEmail(String contactSupportEmail) { this.contactSupportEmail = contactSupportEmail; } + + public UUID getDescriptionAnnotationCreated() { + return descriptionAnnotationCreated; + } + + public void setDescriptionAnnotationCreated(UUID descriptionAnnotationCreated) { + this.descriptionAnnotationCreated = descriptionAnnotationCreated; + } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/AppRabbitConfigurer.java b/backend/core/src/main/java/org/opencdmp/integrationevent/AppRabbitConfigurer.java index 3d40f0a4d..5c27d6e3e 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/AppRabbitConfigurer.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/AppRabbitConfigurer.java @@ -9,6 +9,7 @@ import gr.cite.rabbitmq.consumer.InboxCreator; import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.context.ApplicationContext; +import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import java.util.ArrayList; @@ -19,21 +20,23 @@ import java.util.List; @ConditionalOnProperty(prefix = "queue.rabbitmq", name = "listenerEnabled") public class AppRabbitConfigurer extends RabbitConfigurer { - private ApplicationContext applicationContext; + private final ApplicationContext applicationContext; + private final InboxProperties inboxProperties; - public AppRabbitConfigurer(ApplicationContext applicationContext) { + public AppRabbitConfigurer(ApplicationContext applicationContext, InboxProperties inboxProperties) { this.applicationContext = applicationContext; + this.inboxProperties = inboxProperties; } - // @Bean + @Bean public InboxBindings inboxBindingsCreator() { List bindingItems = new ArrayList<>(); - + bindingItems.addAll(this.inboxProperties.getAnnotationCreatedTopic()); return new InboxBindings(bindingItems); } - // @Bean + @Bean(name = "InboxCreator") public InboxCreator inboxCreator() { return (params) -> { InboxRepository inboxRepository = this.applicationContext.getBean(InboxRepository.class); diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxProperties.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxProperties.java index d5c29630a..db18d9bb5 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxProperties.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxProperties.java @@ -4,6 +4,8 @@ import jakarta.validation.constraints.NotNull; import org.springframework.boot.context.properties.ConfigurationProperties; import org.springframework.validation.annotation.Validated; +import java.util.List; + @Validated @ConfigurationProperties(prefix = "queue.task.listener.options") //@ConstructorBinding @@ -12,14 +14,19 @@ public class InboxProperties { @NotNull private final String exchange; + private final List annotationCreatedTopic; + public InboxProperties( - String exchange - ) { + String exchange, List annotationCreatedTopic) { this.exchange = exchange; + this.annotationCreatedTopic = annotationCreatedTopic; } public String getExchange() { return exchange; } + public List getAnnotationCreatedTopic() { + return annotationCreatedTopic; + } } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java index e6a003283..04828f1c1 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/InboxRepositoryImpl.java @@ -15,6 +15,7 @@ import org.opencdmp.commons.enums.IsActive; import org.opencdmp.commons.fake.FakeRequestScope; import org.opencdmp.data.QueueInboxEntity; import org.opencdmp.data.TenantEntityManager; +import org.opencdmp.integrationevent.inbox.annotationentitycreated.AnnotationEntityCreatedIntegrationEventHandler; import org.opencdmp.query.QueueInboxQuery; import org.slf4j.LoggerFactory; import org.springframework.context.ApplicationContext; @@ -359,12 +360,12 @@ public class InboxRepositoryImpl implements InboxRepository { private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) { IntegrationEventHandler handler = null; logger.debug("Processing message with routing key '{}'", queueInboxMessage.getRoute()); -// if (this.routingKeyMatched(queueInboxMessage.getRoute(), this.inboxProperties.getTenantRemovalTopic())) -// handler = this.applicationContext.getBean(TenantRemovalIntegrationEventHandler.class); -// else { -// logger.error("No handler found for message routing key '{}'. Discarding.", queueInboxMessage.getRoute()); -// handler = null; -// } + if (this.routingKeyMatched(queueInboxMessage.getRoute(), this.inboxProperties.getAnnotationCreatedTopic())) + handler = this.applicationContext.getBean(AnnotationEntityCreatedIntegrationEventHandler.class); + else { + logger.error("No handler found for message routing key '{}'. Discarding.", queueInboxMessage.getRoute()); + handler = null; + } if (handler == null) return EventProcessingStatus.Discard; diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/IntegrationEventHandler.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/IntegrationEventHandler.java index 5ba093351..7afae8c53 100644 --- a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/IntegrationEventHandler.java +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/IntegrationEventHandler.java @@ -1,7 +1,9 @@ package org.opencdmp.integrationevent.inbox; +import javax.management.InvalidApplicationException; + public interface IntegrationEventHandler { - EventProcessingStatus handle(IntegrationEventProperties properties, String message); + EventProcessingStatus handle(IntegrationEventProperties properties, String message) throws InvalidApplicationException; } diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEvent.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEvent.java new file mode 100644 index 000000000..d90ac5bc9 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEvent.java @@ -0,0 +1,189 @@ +package org.opencdmp.integrationevent.inbox.annotationentitycreated; + +import gr.cite.tools.validation.ValidatorFactory; +import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.enums.annotation.AnnotationProtectionType; +import org.opencdmp.commons.validation.BaseValidator; +import org.opencdmp.convention.ConventionService; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.opencdmp.integrationevent.TrackedEvent; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import java.time.Instant; +import java.util.Arrays; +import java.util.List; +import java.util.UUID; + +public class AnnotationEntityCreatedIntegrationEvent extends TrackedEvent { + + private UUID id; + public static final String _id = "id"; + private UUID entityId; + public static final String _entityId = "entityId"; + + private String entityType; + public static final String _entityType = "entityType"; + + private String anchor; + public static final String _anchor = "anchor"; + + private String payload; + public static final String _payload = "payload"; + + private UUID subjectId; + public static final String _subjectId = "subjectId"; + + private UUID threadId; + public static final String _threadId = "threadId"; + + private UUID parentId; + public static final String _parentId = "parentId"; + + private AnnotationProtectionType protectionType; + public static final String _protectionType = "protectionType"; + + private Instant timeStamp; + public static final String _timeStamp = "timeStamp"; + + public UUID getId() { + return id; + } + + public void setId(UUID id) { + this.id = id; + } + + public UUID getEntityId() { + return entityId; + } + + public void setEntityId(UUID entityId) { + this.entityId = entityId; + } + + public String getEntityType() { + return entityType; + } + + public void setEntityType(String entityType) { + this.entityType = entityType; + } + + public String getAnchor() { + return anchor; + } + + public void setAnchor(String anchor) { + this.anchor = anchor; + } + + public String getPayload() { + return payload; + } + + public void setPayload(String payload) { + this.payload = payload; + } + + public UUID getSubjectId() { + return subjectId; + } + + public void setSubjectId(UUID subjectId) { + this.subjectId = subjectId; + } + + public UUID getThreadId() { + return threadId; + } + + public void setThreadId(UUID threadId) { + this.threadId = threadId; + } + + public UUID getParentId() { + return parentId; + } + + public void setParentId(UUID parentId) { + this.parentId = parentId; + } + + public AnnotationProtectionType getProtectionType() { + return protectionType; + } + + public void setProtectionType(AnnotationProtectionType protectionType) { + this.protectionType = protectionType; + } + + public Instant getTimeStamp() { + return timeStamp; + } + + public void setTimeStamp(Instant timeStamp) { + this.timeStamp = timeStamp; + } + + @Component(AnnotationEntityCreatedIntegrationEventValidator.ValidatorName) + @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) + public static class AnnotationEntityCreatedIntegrationEventValidator extends BaseValidator { + + public static final String ValidatorName = "AnnotationEntityCreatedIntegrationEventValidator"; + + private final MessageSource messageSource; + + private final ValidatorFactory validatorFactory; + + protected AnnotationEntityCreatedIntegrationEventValidator(ConventionService conventionService, ErrorThesaurusProperties errors, MessageSource messageSource, ValidatorFactory validatorFactory) { + super(conventionService, errors); + this.messageSource = messageSource; + this.validatorFactory = validatorFactory; + } + + @Override + protected Class modelClass() { + return AnnotationEntityCreatedIntegrationEvent.class; + } + + @Override + protected List specifications(AnnotationEntityCreatedIntegrationEvent item) { + return Arrays.asList( + this.spec() + .must(() -> this.isValidGuid(item.getId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._id).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._id}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> this.isValidGuid(item.getSubjectId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._subjectId).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._subjectId}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isNull(item.getEntityId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._entityId).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._entityId}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isNull(item.getEntityId())) + .must(() -> this.isValidGuid(item.getEntityId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._entityId).failWith(messageSource.getMessage("validation.invalidid", new Object[]{AnnotationEntityCreatedIntegrationEvent._entityId}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isEmpty(item.getEntityType())) + .failOn(AnnotationEntityCreatedIntegrationEvent._entityType).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._entityType}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isEmpty(item.getPayload())) + .failOn(AnnotationEntityCreatedIntegrationEvent._payload).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._payload}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isNull(item.getThreadId())) + .must(() -> this.isValidGuid(item.getThreadId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._threadId).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{AnnotationEntityCreatedIntegrationEvent._threadId}, LocaleContextHolder.getLocale())), + this.spec() + .iff(() -> !this.isNull(item.getParentId())) + .must(() -> this.isValidGuid(item.getParentId())) + .failOn(AnnotationEntityCreatedIntegrationEvent._parentId).failWith(messageSource.getMessage("Validation_UnexpectedValue", new Object[]{AnnotationEntityCreatedIntegrationEvent._parentId}, LocaleContextHolder.getLocale())), + this.spec() + .must(() -> !this.isNull(item.getProtectionType())) + .failOn(AnnotationEntityCreatedIntegrationEvent._protectionType).failWith(messageSource.getMessage("Validation_Required", new Object[]{AnnotationEntityCreatedIntegrationEvent._protectionType}, LocaleContextHolder.getLocale())) + ); + } + } +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandler.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandler.java new file mode 100644 index 000000000..f2446d5d5 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandler.java @@ -0,0 +1,9 @@ +package org.opencdmp.integrationevent.inbox.annotationentitycreated; + +import org.opencdmp.integrationevent.inbox.IntegrationEventHandler; + +import javax.management.InvalidApplicationException; +import java.util.UUID; + +public interface AnnotationEntityCreatedIntegrationEventHandler extends IntegrationEventHandler { +} diff --git a/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandlerImpl.java b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandlerImpl.java new file mode 100644 index 000000000..85e0f7b36 --- /dev/null +++ b/backend/core/src/main/java/org/opencdmp/integrationevent/inbox/annotationentitycreated/AnnotationEntityCreatedIntegrationEventHandlerImpl.java @@ -0,0 +1,178 @@ +package org.opencdmp.integrationevent.inbox.annotationentitycreated; + +import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; +import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorProperties; +import gr.cite.tools.auditing.AuditService; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.exception.MyValidationException; +import gr.cite.tools.fieldset.BaseFieldSet; +import gr.cite.tools.logging.LoggerService; +import gr.cite.tools.validation.ValidatorFactory; +import org.opencdmp.audit.AuditableAction; +import org.opencdmp.commons.JsonHandlingService; +import org.opencdmp.commons.enums.IsActive; +import org.opencdmp.commons.notification.NotificationProperties; +import org.opencdmp.commons.scope.tenant.TenantScope; +import org.opencdmp.commons.scope.user.UserScope; +import org.opencdmp.commons.types.notification.DataType; +import org.opencdmp.commons.types.notification.FieldInfo; +import org.opencdmp.commons.types.notification.NotificationFieldData; +import org.opencdmp.data.*; +import org.opencdmp.errorcode.ErrorThesaurusProperties; +import org.opencdmp.integrationevent.inbox.EventProcessingStatus; +import org.opencdmp.integrationevent.inbox.InboxPrincipal; +import org.opencdmp.integrationevent.inbox.IntegrationEventProperties; +import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEvent; +import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler; +import org.opencdmp.model.Tenant; +import org.opencdmp.model.description.Description; +import org.opencdmp.query.DescriptionQuery; +import org.opencdmp.query.DmpUserQuery; +import org.opencdmp.query.TenantQuery; +import org.opencdmp.query.UserQuery; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.MessageSource; +import org.springframework.context.annotation.Scope; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Component; + +import javax.management.InvalidApplicationException; +import java.util.AbstractMap; +import java.util.ArrayList; +import java.util.List; +import java.util.Map; + + +@Component +@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class AnnotationEntityCreatedIntegrationEventHandlerImpl implements AnnotationEntityCreatedIntegrationEventHandler { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(AnnotationEntityCreatedIntegrationEventHandlerImpl.class)); + + private final QueryFactory queryFactory; + private final JsonHandlingService jsonHandlingService; + private final NotificationProperties notificationProperties; + private final TenantScope tenantScope; + private final NotifyIntegrationEventHandler notifyIntegrationEventHandler; + private final CurrentPrincipalResolver currentPrincipalResolver; + private final ClaimExtractorProperties claimExtractorProperties; + private final MessageSource messageSource; + private final UserScope userScope; + private final ErrorThesaurusProperties errors; + private final TenantEntityManager tenantEntityManager; + private final ValidatorFactory validatorFactory; + private final AuditService auditService; + + public AnnotationEntityCreatedIntegrationEventHandlerImpl(QueryFactory queryFactory, JsonHandlingService jsonHandlingService, NotificationProperties notificationProperties, TenantScope tenantScope, NotifyIntegrationEventHandler notifyIntegrationEventHandler, CurrentPrincipalResolver currentPrincipalResolver, ClaimExtractorProperties claimExtractorProperties, MessageSource messageSource, UserScope userScope, ErrorThesaurusProperties errors, TenantEntityManager tenantEntityManager, ValidatorFactory validatorFactory, AuditService auditService) { + this.queryFactory = queryFactory; + this.jsonHandlingService = jsonHandlingService; + this.notificationProperties = notificationProperties; + this.tenantScope = tenantScope; + this.notifyIntegrationEventHandler = notifyIntegrationEventHandler; + this.currentPrincipalResolver = currentPrincipalResolver; + this.claimExtractorProperties = claimExtractorProperties; + this.messageSource = messageSource; + this.userScope = userScope; + this.errors = errors; + this.tenantEntityManager = tenantEntityManager; + this.validatorFactory = validatorFactory; + this.auditService = auditService; + } + + @Override + public EventProcessingStatus handle(IntegrationEventProperties properties, String message) throws InvalidApplicationException { + AnnotationEntityCreatedIntegrationEvent event = this.jsonHandlingService.fromJsonSafe(AnnotationEntityCreatedIntegrationEvent.class, message); + if (event == null) + return EventProcessingStatus.Error; + + logger.debug("Handling {}", AnnotationEntityCreatedIntegrationEvent.class.getSimpleName()); + this.validatorFactory.validator(AnnotationEntityCreatedIntegrationEvent.AnnotationEntityCreatedIntegrationEventValidator.class).validateForce(event); + + EventProcessingStatus status = EventProcessingStatus.Success; + try { + + if (this.tenantScope.isMultitenant() && properties.getTenantId() != null) { + 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, properties.getTenantId(), tenant.getCode()); + } else if (this.tenantScope.isMultitenant()) { + this.tenantScope.setTempTenant(tenantEntityManager, null, this.tenantScope.getDefaultTenantCode()); + } + + currentPrincipalResolver.push(InboxPrincipal.build(properties, claimExtractorProperties)); + this.sendNotification(event); + auditService.track(AuditableAction.Annotation_Created_Notify, Map.ofEntries( + new AbstractMap.SimpleEntry("model", event) + )); + + } catch (Exception ex) { + status = EventProcessingStatus.Error; + logger.error("Problem getting list of queue outbox. Skipping: {}", ex.getMessage(), ex); + } finally { + currentPrincipalResolver.pop(); + try { + tenantScope.removeTempTenant(this.tenantEntityManager); + this.tenantEntityManager.reloadTenantFilters(); + } catch (InvalidApplicationException e) { + } + } + + return status; + } + + private void sendNotification(AnnotationEntityCreatedIntegrationEvent event) throws InvalidApplicationException { + + DescriptionEntity descriptionEntity = this.queryFactory.query(DescriptionQuery.class).disableTracking().ids(event.getEntityId()).first(); + + if (descriptionEntity == null) throw new MyNotFoundException(this.messageSource.getMessage("General_ItemNotFound", new Object[]{event.getEntityId(), Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + List existingUsers = this.queryFactory.query(DmpUserQuery.class).disableTracking() + .dmpIds(descriptionEntity.getDmpId()) + .isActives(IsActive.Active) + .collect(); + + if (existingUsers == null || existingUsers.size() <= 1){ + return; + } + + UserEntity sender = this.queryFactory.query(UserQuery.class).disableTracking().ids(event.getSubjectId()).first(); + + if (sender == null) throw new MyApplicationException("Sender user not found"); + + for (DmpUserEntity dmpUser : existingUsers) { + if (!dmpUser.getUserId().equals(event.getSubjectId())){ + UserEntity user = this.queryFactory.query(UserQuery.class).disableTracking().ids(dmpUser.getUserId()).first(); + if (user == null || user.getIsActive().equals(IsActive.Inactive)) throw new MyValidationException(this.errors.getDmpInactiveUser().getCode(), this.errors.getDmpInactiveUser().getMessage()); + this.createAnnotationNotificationEvent(user, descriptionEntity, sender.getName()); + } + } + + } + + private void createAnnotationNotificationEvent(UserEntity user, DescriptionEntity description, String reasonName) throws InvalidApplicationException, InvalidApplicationException { + NotifyIntegrationEvent notifyIntegrationEvent = new NotifyIntegrationEvent(); + notifyIntegrationEvent.setUserId(user.getId()); + + notifyIntegrationEvent.setNotificationType(notificationProperties.getDescriptionAnnotationCreated()); + + NotificationFieldData data = new NotificationFieldData(); + List fieldInfoList = new ArrayList<>(); + fieldInfoList.add(new FieldInfo("{recipient}", DataType.String, user.getName())); + fieldInfoList.add(new FieldInfo("{reasonName}", DataType.String, reasonName)); + fieldInfoList.add(new FieldInfo("{name}", DataType.String, description.getLabel())); + fieldInfoList.add(new FieldInfo("{id}", DataType.String, description.getId().toString())); + if(this.tenantScope.getTenantCode() != null && !this.tenantScope.getTenantCode().equals(this.tenantScope.getDefaultTenantCode())){ + fieldInfoList.add(new FieldInfo("{tenant-url-path}", DataType.String, String.format("/t/%s", this.tenantScope.getTenantCode()))); + } + data.setFields(fieldInfoList); + notifyIntegrationEvent.setData(this.jsonHandlingService.toJsonSafe(data)); + + this.notifyIntegrationEventHandler.handle(notifyIntegrationEvent); + } +} diff --git a/backend/core/src/main/java/org/opencdmp/service/deposit/DepositServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/deposit/DepositServiceImpl.java index 8e793f942..bf7c836a4 100644 --- a/backend/core/src/main/java/org/opencdmp/service/deposit/DepositServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/deposit/DepositServiceImpl.java @@ -345,15 +345,7 @@ public class DepositServiceImpl implements DepositService { private void createDmpDepositNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(user.getId()); - UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(user.getId()); - query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); - if (query.count() == 0) return; - - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); event.setNotificationType(this.notificationProperties.getDmpDepositType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); diff --git a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java index eb554aa54..ec1fcb363 100644 --- a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java @@ -388,16 +388,6 @@ public class DescriptionServiceImpl implements DescriptionService { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(user.getId()); - UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(user.getId()); - query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); - - if (query.count() == 0) throw new MyValidationException(this.errors.getDmpMissingUserContactInfo().getCode(), this.errors.getDmpMissingUserContactInfo().getMessage()); - - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); - this.applyNotificationType(description.getStatus(), event); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); diff --git a/backend/web/src/main/resources/config/notification-devel.yml b/backend/web/src/main/resources/config/notification-devel.yml index 9fcb3db83..91df5d19b 100644 --- a/backend/web/src/main/resources/config/notification-devel.yml +++ b/backend/web/src/main/resources/config/notification-devel.yml @@ -5,6 +5,7 @@ notification: dmpFinalisedType: 90DB0B46-42DE-BD89-AEBF-6F27EFEB256E descriptionModifiedType: 4FDBFA80-7A71-4A69-B854-67CBB70648F1 descriptionFinalisedType: 33790bad-94d4-488a-8ee2-7f6295ca18ea + descriptionAnnotationCreated: db1e99d2-a240-4e75-9bb2-ef25b234c1f0 mergeAccountConfirmationType: BFE68845-CB05-4C5A-A03D-29161A7C9660 removeCredentialConfirmationType: C9BC3F16-057E-4BBA-8A5F-36BD835E5604 dmpDepositType: 55736F7A-83AB-4190-AF43-9D031A6F9612 diff --git a/backend/web/src/main/resources/config/queue.yml b/backend/web/src/main/resources/config/queue.yml index 444ac0507..a3d217e24 100644 --- a/backend/web/src/main/resources/config/queue.yml +++ b/backend/web/src/main/resources/config/queue.yml @@ -54,6 +54,7 @@ queue: enable: true options: exchange: null + annotation-created-topic: annotation.created rabbitmq: enable: true interval-seconds: 3 From 740bf41bfae373eba3041951582be81bb4123602 Mon Sep 17 00:00:00 2001 From: amentis Date: Tue, 11 Jun 2024 18:49:31 +0300 Subject: [PATCH 5/7] notification event changes --- .../DescriptionTemplateServiceImpl.java | 8 -------- .../org/opencdmp/service/dmp/DmpServiceImpl.java | 14 -------------- .../org/opencdmp/service/user/UserServiceImpl.java | 6 +----- 3 files changed, 1 insertion(+), 27 deletions(-) diff --git a/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index 9aced79de..ea6378e01 100644 --- a/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -271,14 +271,6 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic if (user.getIsActive().equals(IsActive.Inactive)) throw new MyValidationException(this.errors.getDescriptionTemplateInactiveUser().getCode(), this.errors.getDescriptionTemplateInactiveUser().getMessage()); event.setUserId(user.getId()); - UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(user.getId()); - query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); - - if (query.count() == 0) throw new MyValidationException(this.errors.getDescriptionTemplateMissingUserContactInfo().getCode(), this.errors.getDescriptionTemplateMissingUserContactInfo().getMessage()); - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); event.setNotificationType(this.notificationProperties.getDescriptionTemplateInvitationType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); diff --git a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java index 0a5d11a45..f7858f93a 100644 --- a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java @@ -69,7 +69,6 @@ import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEvent; import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler; import org.opencdmp.model.DmpUser; import org.opencdmp.model.DmpValidationResult; -import org.opencdmp.model.UserContactInfo; import org.opencdmp.model.builder.DmpUserBuilder; import org.opencdmp.model.builder.description.DescriptionBuilder; import org.opencdmp.model.builder.dmp.DmpBuilder; @@ -313,15 +312,6 @@ public class DmpServiceImpl implements DmpService { private void createDmpNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(user.getId()); - UserContactInfoQuery query = this.queryFactory.query(UserContactInfoQuery.class).disableTracking().userIds(user.getId()); - query.setOrder(new Ordering().addAscending(UserContactInfo._ordinal)); - - if (query.count() == 0) throw new MyValidationException(this.errors.getDmpMissingUserContactInfo().getCode(), this.errors.getDmpMissingUserContactInfo().getMessage()); - - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, query.first().getValue())); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); this.applyNotificationType(dmp.getStatus(), event); NotificationFieldData data = new NotificationFieldData(); @@ -1493,10 +1483,6 @@ public class DmpServiceImpl implements DmpService { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(recipient.getId()); - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, email)); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); event.setNotificationType(this.notificationProperties.getDmpInvitationExistingUserType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); 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 cdf75cf87..822c4816e 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 @@ -525,11 +525,7 @@ public class UserServiceImpl implements UserService { NotifyIntegrationEvent event = new NotifyIntegrationEvent(); event.setUserId(user.getId()); - List contactPairs = new ArrayList<>(); - contactPairs.add(new ContactPair(ContactInfoType.Email, email)); - NotificationContactData contactData = new NotificationContactData(contactPairs, null, null); - event.setContactHint(this.jsonHandlingService.toJsonSafe(contactData)); - event.setContactTypeHint(NotificationContactType.EMAIL); + event.setNotificationType(this.notificationProperties.getMergeAccountConfirmationType()); NotificationFieldData data = new NotificationFieldData(); List fieldInfoList = new ArrayList<>(); From f75428595f705ec04d0a2d8b93aebf45aeb98d62 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Wed, 12 Jun 2024 10:43:32 +0300 Subject: [PATCH 6/7] fixes --- .../controllers/PrincipalController.java | 6 ++- .../java/org/opencdmp/models/Account.java | 25 +++++----- .../org/opencdmp/models/AccountBuilder.java | 33 +++++++++++-- .../src/app/core/model/auth/principal.ts | 4 +- .../app/core/services/auth/auth.service.ts | 46 ++++--------------- .../services/utilities/enum-utils.service.ts | 17 ++++--- .../single/single-auto-complete.component.ts | 6 +-- .../src/app/ui/navbar/navbar.component.ts | 7 +-- .../src/app/ui/sidebar/sidebar.component.ts | 16 ++----- 9 files changed, 71 insertions(+), 89 deletions(-) diff --git a/backend/web/src/main/java/org/opencdmp/controllers/PrincipalController.java b/backend/web/src/main/java/org/opencdmp/controllers/PrincipalController.java index 30df186aa..c687070d1 100644 --- a/backend/web/src/main/java/org/opencdmp/controllers/PrincipalController.java +++ b/backend/web/src/main/java/org/opencdmp/controllers/PrincipalController.java @@ -63,8 +63,10 @@ public class PrincipalController { BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._language), BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._culture), BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._timezone), - Account._roles, - Account._permissions); + Account._permissions, + BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._id), + BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._name), + BaseFieldSet.asIndexer(Account._selectedTenant, Tenant._code)); } MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal(); diff --git a/backend/web/src/main/java/org/opencdmp/models/Account.java b/backend/web/src/main/java/org/opencdmp/models/Account.java index 1d004e1bb..e4fdf06dc 100644 --- a/backend/web/src/main/java/org/opencdmp/models/Account.java +++ b/backend/web/src/main/java/org/opencdmp/models/Account.java @@ -1,6 +1,8 @@ package org.opencdmp.models; import gr.cite.tools.logging.annotation.LogSensitive; +import org.opencdmp.commons.scope.tenant.TenantScope; +import org.opencdmp.model.Tenant; import java.time.Instant; import java.util.List; @@ -187,6 +189,9 @@ public class Account { public final static String _permissions = "permissions"; private List permissions; + public final static String _selectedTenant = "selectedTenant"; + public Tenant selectedTenant; + public PrincipalInfo getPrincipal() { return principal; } @@ -195,22 +200,10 @@ public class Account { this.principal = principal; } - public final static String _roles = "roles"; - private List roles; - public Boolean getAuthenticated() { return isAuthenticated; } - - public List getRoles() { - return roles; - } - - public void setRoles(List roles) { - this.roles = roles; - } - public void setAuthenticated(Boolean authenticated) { isAuthenticated = authenticated; } @@ -230,4 +223,12 @@ public class Account { public void setProfile(UserProfileInfo profile) { this.profile = profile; } + + public Tenant getSelectedTenant() { + return selectedTenant; + } + + public void setSelectedTenant(Tenant selectedTenant) { + this.selectedTenant = selectedTenant; + } } diff --git a/backend/web/src/main/java/org/opencdmp/models/AccountBuilder.java b/backend/web/src/main/java/org/opencdmp/models/AccountBuilder.java index 2bae2acd5..0913f6b3e 100644 --- a/backend/web/src/main/java/org/opencdmp/models/AccountBuilder.java +++ b/backend/web/src/main/java/org/opencdmp/models/AccountBuilder.java @@ -6,19 +6,30 @@ import gr.cite.commons.web.oidc.principal.CurrentPrincipalResolver; import gr.cite.commons.web.oidc.principal.MyPrincipal; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor; import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorKeys; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; import org.opencdmp.commons.JsonHandlingService; +import org.opencdmp.commons.scope.tenant.TenantScope; import org.opencdmp.commons.scope.user.UserScope; import org.opencdmp.commons.types.user.AdditionalInfoEntity; +import org.opencdmp.data.DmpEntity; import org.opencdmp.data.TenantEntityManager; import org.opencdmp.data.UserEntity; +import org.opencdmp.model.builder.BaseBuilder; +import org.opencdmp.model.builder.TenantBuilder; +import org.opencdmp.model.builder.dmpreference.DmpReferenceBuilder; +import org.opencdmp.model.dmp.Dmp; +import org.opencdmp.query.DmpReferenceQuery; +import org.opencdmp.query.TenantQuery; 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.*; +import java.util.stream.Collectors; @Component @Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE) @@ -31,13 +42,20 @@ public class AccountBuilder { private final JsonHandlingService jsonHandlingService; private final UserScope userScope; private final TenantEntityManager entityManager; - public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, AuthorizationConfiguration authorizationConfiguration, JsonHandlingService jsonHandlingService, UserScope userScope, TenantEntityManager entityManager) { + private final TenantScope tenantScope; + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + + public AccountBuilder(ClaimExtractor claimExtractor, CurrentPrincipalResolver currentPrincipalResolver, AuthorizationConfiguration authorizationConfiguration, JsonHandlingService jsonHandlingService, UserScope userScope, TenantEntityManager entityManager, TenantScope tenantScope, QueryFactory queryFactory, BuilderFactory builderFactory) { this.claimExtractor = claimExtractor; this.currentPrincipalResolver = currentPrincipalResolver; this.authorizationConfiguration = authorizationConfiguration; this.jsonHandlingService = jsonHandlingService; this.userScope = userScope; this.entityManager = entityManager; + this.tenantScope = tenantScope; + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; this.excludeMoreClaim = Set.of( ClaimExtractorKeys.Subject, ClaimExtractorKeys.Name, @@ -90,10 +108,6 @@ public class AccountBuilder { model.getPrincipal().getMore().get(key).addAll(values); } } - if (fields.hasField(Account._roles)) { - List roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal()); - model.setRoles(roles); - } if (fields.hasField(Account._permissions)) { List roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal()); Set permissions = this.authorizationConfiguration.permissionsOfRoles(roles); @@ -105,6 +119,15 @@ public class AccountBuilder { model.setPermissions(new ArrayList<>(permissions)); } + FieldSet selectedTenantFields = fields.extractPrefixed(BaseFieldSet.asIndexerPrefix(Account._selectedTenant)); + if (!selectedTenantFields.isEmpty() && this.tenantScope.isSet()) { + + if (!this.tenantScope.getTenantCode().equalsIgnoreCase(this.tenantScope.getDefaultTenantCode())) { + TenantQuery query = this.queryFactory.query(TenantQuery.class).disableTracking().ids(this.tenantScope.getTenant()); + model.setSelectedTenant(this.builderFactory.builder(TenantBuilder.class).build(selectedTenantFields, query.first())); + } + } + FieldSet profileFields = fields.extractPrefixed(BaseFieldSet.asIndexerPrefix(Account._profile)); if (!profileFields.isEmpty() && this.userScope.getUserIdSafe() != null){ model.setProfile(new Account.UserProfileInfo()); diff --git a/dmp-frontend/src/app/core/model/auth/principal.ts b/dmp-frontend/src/app/core/model/auth/principal.ts index 380b8d68c..b06f91ee0 100644 --- a/dmp-frontend/src/app/core/model/auth/principal.ts +++ b/dmp-frontend/src/app/core/model/auth/principal.ts @@ -1,13 +1,13 @@ -import { AppRole } from "@app/core/common/enum/app-role"; import { AppPermission } from "@app/core/common/enum/permission.enum"; import { Guid } from "@common/types/guid"; +import { Tenant } from "../tenant/tenant"; export interface AppAccount { isAuthenticated: boolean; - roles: AppRole[]; permissions: AppPermission[]; principal: AppPrincipalInfo; profile: UserProfileInfo; + selectedTenant: Tenant; } export interface AppPrincipalInfo { diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index 2e04bdd80..d4451150e 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -2,11 +2,12 @@ import { HttpErrorResponse } from '@angular/common/http'; import { Injectable, NgZone } from '@angular/core'; import { Router } from '@angular/router'; -import { AppRole } from '@app/core/common/enum/app-role'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { AppAccount } from '@app/core/model/auth/principal'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { BaseService } from '@common/base/base.service'; +import { BaseHttpParams } from '@common/http/base-http-params'; +import { InterceptorType } from '@common/http/interceptors/interceptor-type'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { KeycloakEventType, KeycloakService } from 'keycloak-angular'; @@ -14,12 +15,9 @@ import { Observable, Subject, forkJoin, from, of } from 'rxjs'; import { exhaustMap, map, takeUntil } from 'rxjs/operators'; import { ConfigurationService } from '../configuration/configuration.service'; import { PrincipalService } from '../http/principal.service'; -import { BaseHttpParams } from '@common/http/base-http-params'; -import { InterceptorType } from '@common/http/interceptors/interceptor-type'; import { TenantHandlingService } from '../tenant/tenant-handling.service'; export interface ResolutionContext { - roles: AppRole[]; permissions: AppPermission[]; } export interface AuthenticationState { @@ -194,6 +192,7 @@ export class AuthService extends BaseService { map( (myTenants) => { if (myTenants) { + if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) { this.selectedTenant(tenantCode); } else { @@ -228,12 +227,13 @@ export class AuthService extends BaseService { return null; } - public getRoles(): AppRole[] { - if (this.appAccount && this.appAccount.roles) { - return this.appAccount.roles; + public getSelectedTenantName(): string { + if (this.appAccount && this.appAccount.selectedTenant) { + return this.appAccount.selectedTenant.name; } return null; } + public getUserProfileEmail(): string { if (this.appAccount && this.appAccount.profile) { return this.appAccount.profile.email; @@ -248,28 +248,6 @@ export class AuthService extends BaseService { return null; } - public hasAnyRole(roles: AppRole[]): boolean { - if (!roles) { - return false; - } - return roles.filter((r) => this.hasRole(r)).length > 0; - } - - public hasRole(role: AppRole): boolean { - if (role === undefined) { - return false; - } - if ( - !this.appAccount || - !this.appAccount.roles || - this.appAccount.roles.length === 0 - ) { - return false; - } - return this.appAccount.roles - .includes(role); - } - public getUserProfileCulture(): string { if (this.appAccount && this.appAccount.profile) { return this.appAccount.profile.culture; @@ -388,7 +366,6 @@ export class AuthService extends BaseService { } private evaluatePermission(availablePermissions: string[], permissionToCheck: string): boolean { if (!permissionToCheck) { return false; } - // if (this.hasRole(AppRole.Admin)) { return true; } return availablePermissions.map(x => x.toLowerCase()).includes(permissionToCheck.toLowerCase()); } public hasAnyPermission(permissions: AppPermission[]): boolean { @@ -398,19 +375,14 @@ export class AuthService extends BaseService { public authorize(context: ResolutionContext): boolean { - if (!context || this.hasRole(AppRole.Admin)) { return true; } - - let roleAuthorized = false; - if (context.roles && context.roles.length > 0) { - roleAuthorized = this.hasAnyRole(context.roles); - } + if (!context) { return true; } let permissionAuthorized = false; if (context.permissions && context.permissions.length > 0) { permissionAuthorized = this.hasAnyPermission(context.permissions); } - if (roleAuthorized || permissionAuthorized) { return true; } + if (permissionAuthorized) { return true; } return false; } diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 7b9924c19..225303af1 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -1,35 +1,34 @@ import { Injectable } from '@angular/core'; +import { AnnotationProtectionType } from '@app/core/common/enum/annotation-protection-type.enum'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; +import { DescriptionTemplateExternalSelectAuthType } from '@app/core/common/enum/description-template-external-select-auth-type'; import { DescriptionTemplateExternalSelectHttpMethodType } from '@app/core/common/enum/description-template-external-select-http-method-type'; import { DescriptionTemplateFieldDataExternalDatasetType } from '@app/core/common/enum/description-template-field-data-external-dataset-type'; import { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type'; import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status'; import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; +import { DmpBlueprintFieldCategory } from '@app/core/common/enum/dmp-blueprint-field-category'; import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; +import { DmpUserType } from '@app/core/common/enum/dmp-user-type'; +import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type'; +import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type'; import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { LockTargetType } from '@app/core/common/enum/lock-target-type'; +import { PrefillingSourceSystemTargetType } from '@app/core/common/enum/prefilling-source-system-target-type'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type'; -import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type'; -import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type'; import { RoleOrganizationType } from '@app/core/common/enum/role-organization-type'; import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type'; import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role'; import { TranslateService } from '@ngx-translate/core'; import { AppRole } from '../../common/enum/app-role'; import { DmpBlueprintExtraFieldDataType } from '../../common/enum/dmp-blueprint-field-type'; -import { DmpBlueprintType } from '../../common/enum/dmp-blueprint-type'; import { DmpStatus } from '../../common/enum/dmp-status'; import { ValidationType } from '../../common/enum/validation-type'; -import { DescriptionTemplateExternalSelectAuthType } from '@app/core/common/enum/description-template-external-select-auth-type'; -import { DmpBlueprintFieldCategory } from '@app/core/common/enum/dmp-blueprint-field-category'; -import { DmpUserType } from '@app/core/common/enum/dmp-user-type'; -import { PrefillingSourceSystemTargetType } from '@app/core/common/enum/prefilling-source-system-target-type'; -import { AnnotationProtectionType } from '@app/core/common/enum/annotation-protection-type.enum'; -import { LockTargetType } from '@app/core/common/enum/lock-target-type'; @Injectable() export class EnumUtils { diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts index 9b354dd59..ad6fb6e24 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.ts @@ -313,9 +313,9 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple } ngOnDestroy() { - this.panelClosedSubscription.unsubscribe(); - this.stateChanges.complete(); - this.fm.stopMonitoring(this.elRef.nativeElement); + this.panelClosedSubscription?.unsubscribe(); + this.stateChanges?.complete(); + this.fm?.stopMonitoring(this.elRef?.nativeElement); } //Configuration getters diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.ts b/dmp-frontend/src/app/ui/navbar/navbar.component.ts index a756866ff..17208d1b0 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.ts +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.ts @@ -4,7 +4,6 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog'; import { MatMenuTrigger } from '@angular/material/menu'; import { DomSanitizer, SafeUrl } from '@angular/platform-browser'; import { Router } from '@angular/router'; -import { AppRole } from '@app/core/common/enum/app-role'; import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type'; import { StorageFile } from '@app/core/model/storage-file/storage-file'; import { LogoTenantConfiguration, TenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration'; @@ -17,6 +16,7 @@ import { ProgressIndicationService } from '@app/core/services/progress-indicatio import { SideNavService } from '@app/core/services/sidenav/side-nav.sevice'; import { StorageFileService } from '@app/core/services/storage-file/storage-file.service'; import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service'; +import { UserService } from '@app/core/services/user/user.service'; import { BaseComponent } from '@common/base/base.component'; import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service'; import { MineInAppNotificationListingDialogComponent } from '@notification-service/ui/inapp-notification/listing-dialog/mine-inapp-notification-listing-dialog.component'; @@ -26,7 +26,6 @@ import { nameof } from 'ts-simple-nameof'; import { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component'; import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component'; import { UserDialogComponent } from './user-dialog/user-dialog.component'; -import { UserService } from '@app/core/services/user/user.service'; @Component({ selector: 'app-navbar', @@ -270,10 +269,6 @@ export class NavbarComponent extends BaseComponent implements OnInit { (ev.target as HTMLImageElement).src = this.getDefaultAvatar(); } - public isAdmin(): boolean { - return this.authentication.hasRole(AppRole.Admin); - } - openProfile() { const dialogRef = this.dialog.open(UserDialogComponent, { hasBackdrop: true, diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index 9f8460a7e..9c7e235a3 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -3,14 +3,12 @@ import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { Router } from '@angular/router'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { TranslateService } from '@ngx-translate/core'; -import { AppRole } from '../../core/common/enum/app-role'; -import { AuthService, LoginStatus } from '../../core/services/auth/auth.service'; +import { AuthService } from '../../core/services/auth/auth.service'; import { LanguageDialogComponent } from '../language/dialog/language-dialog.component'; 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; @@ -151,14 +149,6 @@ export class SidebarComponent implements OnInit { return this.authentication.currentAccountIsAuthenticated(); } - public isAdmin(): boolean { - return this.authentication.hasRole(AppRole.Admin); - } - - public hasPermission(role: AppRole): boolean { - return this.authentication.hasRole(role); - } - isLoginRouteActivated(): boolean { return this.location.path().indexOf('/login') > -1; } From 947a4cc087b34d65bf325e829a9b8155f770ae05 Mon Sep 17 00:00:00 2001 From: Diamantis Tziotzios Date: Wed, 12 Jun 2024 11:36:25 +0300 Subject: [PATCH 7/7] cleanup --- .../user-settings/user-settings.service.ts | 27 +- .../services/utilities/enum-utils.service.ts | 4 - .../multiple-auto-complete.component.scss | 14 - .../single-auto-complete.component.scss | 10 - .../guided-tour/guided-tour.component.scss | 49 -- ...plate-editor-section-fieldset.component.ts | 3 - .../description-template-editor.component.ts | 102 ++--- .../description-template-table-of-contents.ts | 427 +----------------- .../prefilling-source-editor.component.ts | 37 +- .../editor/reference-type-editor.component.ts | 35 +- .../editor/reference-editor.component.ts | 21 +- .../default-user-locale-editor.component.ts | 44 +- .../tenant-configuration-editor.component.ts | 1 - .../tenant/editor/tenant-editor.component.ts | 17 +- .../annotation-dialog.component.ts | 5 - .../editor/description-editor.resolver.ts | 31 +- .../editor/description-editor.routing.ts | 79 +--- .../form-field-set.component.ts | 8 - .../criteria/dataset-criteria.component.ts | 11 - .../listing/description-listing.component.ts | 137 ++---- .../description-overview.component.ts | 102 ++--- .../dmp-editor.component.ts | 5 - .../dmp-editor.resolver.ts | 8 - .../dataset-info/dataset-info.component.html | 33 -- .../dataset-info/dataset-info.component.scss | 84 ---- .../dataset-info/dataset-info.component.ts | 258 ----------- .../ui/dmp/listing/dmp-listing.component.ts | 198 +++----- .../ui/dmp/overview/dmp-overview.component.ts | 172 +------ .../src/app/ui/navbar/navbar.component.ts | 15 - .../reference-field.component.ts | 7 - .../src/app/ui/splash/splash.component.ts | 22 +- .../user-guide-content.component.ts | 28 +- dmp-frontend/src/common/base/base-editor.ts | 50 +- ...form-validation-errors-dialog.component.ts | 9 - .../src/common/http/common-http.module.ts | 6 - .../response-payload.interceptor.ts | 43 -- .../user-settings-picker.component.ts | 32 +- .../user-settings-selector.component.ts | 22 +- .../inapp-notification-editor.component.ts | 22 +- ...ser-profile-notifier-list-editor.module.ts | 2 - dmp-frontend/src/styles.scss | 71 --- 41 files changed, 334 insertions(+), 1917 deletions(-) delete mode 100644 dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html delete mode 100644 dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss delete mode 100644 dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts delete mode 100644 dmp-frontend/src/common/http/interceptors/response-payload.interceptor.ts diff --git a/dmp-frontend/src/app/core/services/user-settings/user-settings.service.ts b/dmp-frontend/src/app/core/services/user-settings/user-settings.service.ts index 29be51350..1cf18e6d6 100644 --- a/dmp-frontend/src/app/core/services/user-settings/user-settings.service.ts +++ b/dmp-frontend/src/app/core/services/user-settings/user-settings.service.ts @@ -1,15 +1,14 @@ import { Injectable } from '@angular/core'; import { UserSettingPersist, UserSettingsInformation, UserSettings as UserSettingsObject } from '@app/core/model/user-settings/user-settings.model'; import { BaseService } from '@common/base/base.service'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { Guid } from '@common/types/guid'; -import moment from 'moment'; -import { Moment } from 'moment'; +import moment, { Moment } from 'moment'; import { Observable, Subject, of as observableOf } from 'rxjs'; import { map, takeUntil } from 'rxjs/operators'; import { AuthService, LoginStatus } from '../auth/auth.service'; import { ConfigurationService } from '../configuration/configuration.service'; import { UserSettingsHttpService } from './user-settings-http.service'; -import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; export enum UserSettingsType { Setting = 0, @@ -117,7 +116,7 @@ export class UserSettingsService extends BaseService { this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false); this.userSettingUpdated.next(userSettingsInformation.key); }, - error => this.httpErrorHandlingService.handleBackedRequestError(error)); + error => this.httpErrorHandlingService.handleBackedRequestError(error)); } private buildUserSettings(setting: UserSetting, key: string): UserSettings { @@ -264,7 +263,7 @@ export class UserSettingsService extends BaseService { }); } }, - error => this.httpErrorHandlingService.handleBackedRequestError(error)); + error => this.httpErrorHandlingService.handleBackedRequestError(error)); } private clearSetting(key: string) { @@ -289,24 +288,6 @@ export class UserSettingsService extends BaseService { return `${this.getUserSettingsVersion()}_${this.getUserId()}_${key}`; } - // private defaultValue(userSettingsInformation: UserSettingsInformation): UserSettings { - // const defaultSetting: UserSetting = { - // id: null, - // name: null, - // userId: this.getUserId(), - // key: userSettingsInformation.key, - // type: UserSettingsType.Config, - // isDefault: true, - // value: new userSettingsInformation.type() - // }; - // const userSettings: UserSettings = { - // defaultSetting: defaultSetting, - // key: userSettingsInformation.key, - // settings: [defaultSetting] - // }; - // return userSettings; - // } - private getUserId(): Guid { return this.authService.userId(); } diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 225303af1..50ceedc9d 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -226,12 +226,8 @@ export class EnumUtils { toRecentActivityOrderString(status: RecentActivityOrder): string { switch (status) { - // case RecentActivityOrder.CREATED: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.CREATED'); case RecentActivityOrder.Label: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.LABEL'); case RecentActivityOrder.UpdatedAt: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.MODIFIED'); - // case RecentActivityOrder.FINALIZED: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.FINALIZED'); - // case RecentActivityOrder.PUBLISHED: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.PUBLISHED'); - // case RecentActivityOrder.DATASETPUBLISHED: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.PUBLISHED'); case RecentActivityOrder.Status: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.STATUS'); } } diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss index e5bd081e3..f96c6f21e 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.scss @@ -1,6 +1,4 @@ .multiple-auto-complete { - // margin-left: inherit; - // margin-right: inherit; .not-loading { display: none; @@ -8,10 +6,7 @@ .align-arrow-right { - // position: absolute; right: 0; - // bottom: 0; - // vertical-align: middle; cursor: pointer; align-self: center; color: rgba(0, 0, 0, 0.54); @@ -25,19 +20,10 @@ } .chip-text { - // text-overflow: ellipsis; - // white-space: nowrap; - // overflow: hidden; white-space: normal; word-break: break-word; } - -// .chip-list { -// max-width: calc(100% - 30px); -// padding-left: 0.8em; -// } - .title-subtitle-fn { height: auto; width: calc(100% - 46px); diff --git a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss index 225bfa09d..cf7452f6a 100644 --- a/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss +++ b/dmp-frontend/src/app/library/auto-complete/single/single-auto-complete.component.scss @@ -57,11 +57,6 @@ line-height: 1.2em; } -// .two-line-mat-option { -// height: 3.5em; -// line-height: 1.2em; -// } - .mat-standard-chip:hover::after { opacity: 0; } @@ -70,11 +65,6 @@ opacity: 0; } - -// .mat-form-field-type-single-autocomplete:not(.mat-form-field-disabled) .mat-form-field-flex { -// cursor: pointer; -// } - .option-text-container { min-width: 0; } diff --git a/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss b/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss index 19fe28028..7779678d4 100644 --- a/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss +++ b/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss @@ -17,42 +17,6 @@ ngx-guided-tour { border-radius: 44px; /*custom add*/ } - .tour-orb { - position: fixed; - width: 20px; - height: 20px; - border-radius: 50%; - - .tour-orb-ring { - width: 35px; - height: 35px; - position: relative; - top: 50%; - left: 50%; - transform: translate(-50%, -50%); - animation: pulse 2s linear infinite; - - &:after { - content: ""; - display: inline-block; - height: 100%; - width: 100%; - border-radius: 50%; - } - } - - @keyframes pulse { - from { - transform: translate(-50%, -50%) scale(0.45); - opacity: 1; - } - to { - transform: translate(-50%, -50%) scale(1); - opacity: 0; - } - } - } - .tour-step { position: fixed; &.page-tour-step { @@ -154,9 +118,6 @@ ngx-guided-tour { } .tour-title { - // font-weight: bold !important; - // padding-bottom: 20px; - /*custom add*/ font-weight: lighter !important; font-size: 16px !important; @@ -166,7 +127,6 @@ ngx-guided-tour { color: #212121; line-height: 26px; white-space: pre-line; - // height: 210px; } h3.tour-title { @@ -201,14 +161,11 @@ ngx-guided-tour { } button.skip-button.link-button { - // padding-left: 0; border-left: 0; /*custom add*/ - // padding: 0; padding-right: 1em; padding-left: 1em; - // float: right; min-width: 133px; height: 40px; border: 1px solid var(--primary-color); @@ -218,16 +175,10 @@ ngx-guided-tour { .next-button { cursor: pointer; - // border-radius: 1px; - // float: right; border: none; outline: none; - // padding-left: 10px; - // padding-right: 10px; /*custom add*/ - // float: left; - // padding: 10px 0px; padding-left: 1em; padding-right: 1em; min-width: 101px; diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/section-fieldset/description-template-editor-section-fieldset.component.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/components/section-fieldset/description-template-editor-section-fieldset.component.ts index ea96e861a..50ffd7ad4 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/section-fieldset/description-template-editor-section-fieldset.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/section-fieldset/description-template-editor-section-fieldset.component.ts @@ -40,7 +40,6 @@ export class DescriptionTemplateEditorSectionFieldSetComponent implements OnInit private initializer = new Subject(); private scroller = new Subject(); - // private $selectedFieldsetId = new Subject(); constructor( private dragulaService: DragulaService, private myElement: ElementRef @@ -52,8 +51,6 @@ export class DescriptionTemplateEditorSectionFieldSetComponent implements OnInit this.dragulaService.createGroup(this.FIELDSETS, { moves: (el, container, handle) => { - // if(this.viewOnly) return false; //uncomment if want to unable drag n drop in viewonly mode - // if (el.id != (this.dragula_prefix + this.tocentry.id)) return false; if (handle.className && handle.classList.contains('handle')) return true; return false; } 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 202c4e644..6722f125b 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 @@ -1,16 +1,16 @@ +import { CdkStep, StepperSelectionEvent } from '@angular/cdk/stepper'; +import { DatePipe } from '@angular/common'; import { Component, OnInit, QueryList, ViewChild } from '@angular/core'; import { FormArray, FormControl, FormGroup, UntypedFormArray, UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { CdkStep, StepperSelectionEvent } from '@angular/cdk/stepper'; -import { DatePipe } from '@angular/common'; import { MatStepper } from '@angular/material/stepper'; +import { Title } from '@angular/platform-browser'; +import { ActivatedRoute, Router } from '@angular/router'; import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status'; +import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { LockTargetType } from '@app/core/common/enum/lock-target-type'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; @@ -18,13 +18,19 @@ import { DescriptionTemplatePersist, NewVersionDescriptionTemplatePersist } from import { LanguageInfo } from '@app/core/model/language-info'; import { User } from '@app/core/model/user/user'; import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; 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 { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-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'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; import { BaseEditor } from '@common/base/base-editor'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; @@ -38,13 +44,6 @@ import { DescriptionTemplateEditorModel, DescriptionTemplateFieldEditorModel, De import { DescriptionTemplateEditorResolver } from './description-template-editor.resolver'; import { DescriptionTemplateEditorService } from './description-template-editor.service'; import { NewEntryType, ToCEntry, ToCEntryType } from './table-of-contents/description-template-table-of-contents-entry'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { LockService } from '@app/core/services/lock/lock.service'; -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({ @@ -79,7 +78,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor void): void { - if (this.isNewVersion == false){ + if (this.isNewVersion == false) { const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist; this.descriptionTemplateService.persist(formData) @@ -248,14 +247,14 @@ export class DescriptionTemplateEditorComponent extends BaseEditor onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), error => this.onCallbackError(error) ); - } else if (this.isNewVersion== true && this.isNew == false && this.isClone == false) { - const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist; + } else if (this.isNewVersion == true && this.isNew == false && this.isClone == false) { + const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist; - this.descriptionTemplateService.newVersion(formData) - .pipe(takeUntil(this._destroyed)).subscribe( - complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), - error => this.onCallbackError(error) - ); + this.descriptionTemplateService.newVersion(formData) + .pipe(takeUntil(this._destroyed)).subscribe( + complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), + error => this.onCallbackError(error) + ); } } @@ -269,10 +268,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor { this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - if(close){ + if (close) { this.formGroup = null; this.router.navigate(['/description-templates']); } else { @@ -325,7 +324,8 @@ export class DescriptionTemplateEditorComponent extends BaseEditor 0 ? tceIndex-1 : tceIndex+1); //if deleting the first field, find the next one, else find the previous + return sameLevelFields.at(tceIndex > 0 ? tceIndex - 1 : tceIndex + 1); //if deleting the first field, find the next one, else find the previous } private populateSections(sections: UntypedFormArray, existingNumbering: string, validationRootPath: string): ToCEntry[] { @@ -803,7 +803,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor { + dragulaService.over(this.DRAG_GROUP).subscribe(({ el, container, source }) => { try { this.overcontainer = container.id; } catch (error) { @@ -422,7 +422,7 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements } }) ); - + this.dragSubscriptions.push( dragulaService.dragend(this.DRAG_GROUP).subscribe(({ el }) => { this.isDragging = false; @@ -430,394 +430,9 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements this.overcontainer = null; }) ); - // if (this.dragulaService.find('TABLEDRAG')) { - // this.dragulaService.destroy('TABLEDRAG'); - // } - - // const dragula = this.dragulaService.createGroup('TABLEDRAG', {}); - - // const drake = dragula.drake; - - // drake.on('drop', (el, target, source, sibling) => { - - // if (this._dragStartedAt) { - // const timeNow = new Date().getTime(); - - // if (timeNow - this._dragStartedAt > this.VALID_DROP_TIME) { - // // console.log('timenow: ', timeNow); - // // console.log('timestarted', this._dragStartedAt); - // this._dragStartedAt = null; - - // } else { - // this.dataNeedsRefresh.emit();// even though the data is not changed the TABLE DRAG may has changed - // return; - // } - // } else { - // this.dataNeedsRefresh.emit();// even though the data is not changed the TABLE DRAG may has changed - // return; - - // } - - // const elementId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - // const targetId = target.id as string; - // const sourceId = source.id as string; - - - // if (!(elementId && targetId && sourceId)) { - // console.info('Elements do not have an id'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - - // const element: ToCEntry = this._findTocEntryById(elementId, this.links); - // const targetContainer: ToCEntry = this._findTocEntryById(targetId, this.links); - // const sourceContainer: ToCEntry = this._findTocEntryById(sourceId, this.links); - - // if (!(element && (targetContainer || ((element.type === ToCEntryType.Page) && (targetId === this.ROOT_ID))) && (sourceContainer || ((element.type === ToCEntryType.Page) && (sourceId === this.ROOT_ID))))) { - // // console.info('Could not find elements'); - // this.dataNeedsRefresh.emit(); - // //TODO: angular update //drake.cancel(true); - // return; - // } - - - // switch (element.type) { - // case ToCEntryType.FieldSet: { - // if (targetContainer.type != this.tocEntryType.Section) { - // // const message = 'Fieldset can only be child of Subsections'; - // const message = this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.FIELDSET-MUST-HAVE-PARENT-SECTION'); - // // console.error(message); - // this.notifyUser(message) - // this.dataNeedsRefresh.emit(); - // return; - // } - - // //check if target container has no sections - // if ((targetContainer.form.get('sections') as UntypedFormArray).length) { - // // const message = 'Cannot have inputs and sections on the same level'; - // const message = this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.INPUT-SECTION-SAME-LEVEL'); - // this.notifyUser(message); - // // console.error(message); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // const fieldsetForm = element.form; - // const targetFieldsets = targetContainer.form.get('fieldSets') as UntypedFormArray; - // const sourceFieldsets = sourceContainer.form.get('fieldSets') as UntypedFormArray; - - // if (!targetFieldsets) { - // console.info('Not target fieldsets container found'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // let sourceOrdinal = -1; - // let idx = -1; - // sourceFieldsets.controls.forEach((elem, index) => { - // if (elem.get('id').value === elementId) { - // sourceOrdinal = elem.get('ordinal').value; - // idx = index - // } - // }); - - // if (sourceOrdinal >= 0 && idx >= 0) { - // sourceFieldsets.removeAt(idx); - - // sourceFieldsets.controls.forEach(control => { - // const ordinal = control.get('ordinal'); - // if ((ordinal.value >= sourceOrdinal) && sourceOrdinal > 0) { - // const updatedOrdinalVal = ordinal.value - 1; - // ordinal.setValue(updatedOrdinalVal); - // } - // }); - // sourceFieldsets.controls.sort(this._compareOrdinals); - // } - - // let position: number = targetFieldsets.length; - - // if (!sibling || !sibling.id) { - // console.info('No sibling Id found'); - // } else { - // const siblingId = (sibling.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - // let siblingIndex = -1; - // targetFieldsets.controls.forEach((e, idx) => { - // if (e.get('id').value === siblingId) { - // siblingIndex = idx; - // position = e.get('ordinal').value; - // } - - // }); - - // if (siblingIndex >= 0) { //sibling found - - // targetFieldsets.controls.filter(control => control.get('ordinal').value >= position).forEach(control => { - // const ordinal = control.get('ordinal'); - // const updatedOrdinalVal = ordinal.value + 1; - // ordinal.setValue(updatedOrdinalVal); - // }) - // } - - // } - - - // fieldsetForm.get('ordinal').setValue(position); - // targetFieldsets.insert(position, fieldsetForm); - // targetFieldsets.controls.sort(this._compareOrdinals); - // this.dataNeedsRefresh.emit({ draggedItemId: elementId }); - - // break; - // } - // case ToCEntryType.Section: { - - // if (targetContainer.type == ToCEntryType.Section) { - // if ((targetContainer.form.get('fieldSets') as UntypedFormArray).length) { - // // const message = 'Cannot have inputs and sections on the same level'; - // const message = this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.INPUT-SECTION-SAME-LEVEL');; - // this.notifyUser(message); - // // console.info(message); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // const targetSections = targetContainer.form.get('sections') as UntypedFormArray; - // const elementSectionForm = element.form; - // const sourceSections = elementSectionForm.parent as UntypedFormArray; - - // if (!(targetSections && sourceSections && elementSectionForm)) { - // console.info('Could not load sections'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // let idx = -1; - // sourceSections.controls.forEach((section, i) => { - // if (section.get('id').value === elementId) { - // idx = i; - // } - // }); - - // if (!(idx >= 0)) { - // console.info('Could not find element in Parent container'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // sourceSections.controls.filter(control => control.get('ordinal').value >= elementSectionForm.get('ordinal').value).forEach(control => { - // const ordinal = control.get('ordinal'); - // const updatedOrdinalVal = ordinal.value ? ordinal.value - 1 : 0; - // ordinal.setValue(updatedOrdinalVal); - // }); - - - // sourceSections.removeAt(idx); - - // let targetOrdinal = targetSections.length; - - // if (sibling && sibling.id) { - // const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - - // targetSections.controls.forEach((section, i) => { - // if (section.get('id').value === siblingId) { - // targetOrdinal = section.get('ordinal').value; - // } - // }) - - // targetSections.controls.filter(control => control.get('ordinal').value >= targetOrdinal).forEach(control => { - // const ordinal = control.get('ordinal'); - // const updatedOrdinalVal = ordinal.value + 1; - // ordinal.setValue(updatedOrdinalVal); - // }); - - // } else { - // console.info('no siblings found'); - // } - // elementSectionForm.get('ordinal').setValue(targetOrdinal); - // targetSections.insert(targetOrdinal, elementSectionForm); - - // } else if (targetContainer.type === ToCEntryType.Page) { - - // const rootform = targetContainer.form.root; - // const sectionForm = element.form; - // const parentSections = sectionForm.parent as UntypedFormArray; - - // let parentIndex = -1; - // parentSections.controls.forEach((section, i) => { - // if (section.get('id').value === elementId) { - // parentIndex = i - // } - // }) - - - // if (parentIndex < 0) { - // console.info('could not locate section in parents array'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // //update parent sections ordinal - // parentSections.controls.filter(section => section.get('ordinal').value >= sectionForm.get('ordinal').value).forEach(section => { - // const ordinal = section.get('ordinal'); - // const updatedOrdinalVal = ordinal.value ? ordinal.value - 1 : 0; - // ordinal.setValue(updatedOrdinalVal); - // }) - - // parentSections.removeAt(parentIndex); - - - - // let position = 0; - // if (targetContainer.subEntries) { - // position = targetContainer.subEntries.length; - // } - // //populate sections - // const targetSectionsArray = rootform.get('sections') as UntypedFormArray; - - - // if (sibling && sibling.id) { - // const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - // let indx = -1; - - // targetContainer.subEntries.forEach((e, i) => { - // if (e.form.get('id').value === siblingId) { - // indx = i; - // position = e.form.get('ordinal').value; - // } - // }); - // if (indx >= 0) { - - // // e.form.get('ordinal').setValue(i+1); - // targetContainer.subEntries.filter(e => e.form.get('ordinal').value >= position).forEach(e => { - // const ordinal = e.form.get('ordinal'); - // const updatedOrdinalVal = ordinal.value + 1; - // ordinal.setValue(updatedOrdinalVal); - // }); - // } - - // } else { - // console.info('No sibling found'); - // } - - // sectionForm.get('ordinal').setValue(position); - // sectionForm.get('page').setValue(targetContainer.id); - // targetSectionsArray.push(sectionForm); - - // } else { - // // const message = 'Drag not support to specific container'; - // const message = this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.DRAG-NOT-SUPPORTED'); - // this.notifyUser(message); - // // console.info(message); - // this.dataNeedsRefresh.emit(); - // return; - // } - - - - // this.dataNeedsRefresh.emit({ draggedItemId: elementId }); - // break; - // } - // case ToCEntryType.Page: { - // if (targetId != this.ROOT_ID) { - // // const message = 'A page element can only be at top level'; - // const message = this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TABLE-OF-CONTENTS.ERROR-MESSAGES.PAGE-ELEMENT-ONLY-TOP-LEVEL'); - // this.notifyUser(message); - // // console.info(message); - // this.dataNeedsRefresh.emit(); - // return; - // } - - // const rootForm = element.form.root; - // if (!rootForm) { - // console.info('Could not find root!') - // this.dataNeedsRefresh.emit(); - // return; - // } - - - // const pages = rootForm.get('pages') as UntypedFormArray; - // const pageForm = element.form; - - // let index = -1; - - // pages.controls.forEach((page, i) => { - // if (page.get('id').value === elementId) { - // index = i; - // } - // }); - - // if (index < 0) { - // console.info('Could not locate page on pages'); - // this.dataNeedsRefresh.emit(); - // return; - // } - - - // //ordinality - // pages.controls.filter(page => page.get('ordinal').value >= pageForm.get('ordinal').value).forEach(page => { - // const ordinal = page.get('ordinal'); - // const ordinalVal = ordinal.value ? ordinal.value - 1 : 0; - // ordinal.setValue(ordinalVal); - // }); - - // pages.removeAt(index); - - // let targetPosition = pages.length; - - // if (sibling) { - // const siblingId = sibling.id.replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - - // pages.controls.forEach((page, i) => { - // if (page.get('id').value === siblingId) { - // targetPosition = page.get('ordinal').value; - // } - // }); - // } - // pageForm.get('ordinal').setValue(targetPosition); - - // //update ordinality - // pages.controls.filter(page => page.get('ordinal').value >= targetPosition).forEach(page => { - // const ordinal = page.get('ordinal'); - // const ordinalVal = ordinal.value + 1; - // ordinal.setValue(ordinalVal); - // }); - - - // pages.insert(targetPosition, pageForm); - // this.dataNeedsRefresh.emit({ draggedItemId: elementId }); - // break; - // } - // default: - - // console.info('Could not support moving objects for specific type of element'); - // this.dataNeedsRefresh.emit(); - // return; - - // } - // }); - - - // drake.on('drag', (el, source) => { - // this._dragStartedAt = new Date().getTime(); - // // console.log('drag fired'); - // this.isDragging = true; - // this.draggingItemId = (el.id as string).replace(this.DRAGULA_ITEM_ID_PREFIX, ''); - // }); - // drake.on('over', (el, container, source) => { - // try { - // this.overcontainer = container.id; - // } catch (error) { - // this.overcontainer = null; - // } - // }); - // drake.on('dragend', (el) => { - // this.isDragging = false; - // this.draggingItemId = null; - // this.overcontainer = null; - // }); } - ngOnInit(): void {} + ngOnInit(): void { } ngAfterViewInit(): void { @@ -872,42 +487,6 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements this.dragSubscriptions.forEach(subscription => subscription.unsubscribe()) } - private _scrollIntoDragginItem(id: string) { - - // const table = document.getElementById('tocentrytable'); - // if(table){ - // // const element = document.getElementById('TABLE_ENTRY'+id); - // console.log('Table found!'); - // const element = document.getElementById('TABLE_ENTRY' + id); - // const elementFromTable = table.closest('#TABLE_ENTRY'+ id); - - - // if(elementFromTable){ - // console.log('found from table:', elementFromTable); - // } - // if(element){ - // console.log('Element found!'); - // // element.classList.add('text-danger'); - // // console.log(element); - - // const tableRect = table.getBoundingClientRect(); - // const elementRect = element.getBoundingClientRect(); - - - // console.log('tablerect :',tableRect); - // console.log('elementRect :',elementRect); - - // const dY = elementRect.top - tableRect.top; - // console.log('Distance from table is ', dY); - // // table.scroll({top:dY,behavior:'smooth'}); - // console.log('found from document ', element); - - // // element.scrollIntoView(); - // } - // // element.scrollIntoView(); - // } - } - private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry { if (!tocentries) { return null; diff --git a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts index f594bcfd0..f16cd52a8 100644 --- a/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/prefilling-source/editor/prefilling-source-editor.component.ts @@ -3,17 +3,22 @@ import { Component, OnInit } from '@angular/core'; import { FormArray, FormGroup, UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { PrefillingSourceService } from '@app/core/services/prefilling-source/prefilling-source.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { DatePipe } from '@angular/common'; +import { MatCheckboxChange } from '@angular/material/checkbox'; +import { Title } from '@angular/platform-browser'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { PrefillingSource, PrefillingSourcePersist } from '@app/core/model/prefilling-source/prefilling-source'; import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { ResultFieldsMappingConfigurationEditorModel } from '@app/ui/external-fetcher/external-fetcher-source-editor.model'; import { BaseEditor } from '@common/base/base-editor'; import { FormService } from '@common/forms/form-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; @@ -22,15 +27,9 @@ import { FilterService } from '@common/modules/text-filter/filter-service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; +import { PrefillingSourceDefinitionEditorModel, PrefillingSourceEditorModel } from './prefilling-source-editor.model'; import { PrefillingSourceEditorResolver } from './prefilling-source-editor.resolver'; import { PrefillingSourceEditorService } from './prefilling-source-editor.service'; -import { PrefillingSourceDefinitionEditorModel, PrefillingSourceEditorModel } from './prefilling-source-editor.model'; -import { ResultFieldsMappingConfigurationEditorModel } from '@app/ui/external-fetcher/external-fetcher-source-editor.model'; -import { MatCheckboxChange } from '@angular/material/checkbox'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { LockService } from '@app/core/services/lock/lock.service'; -import { Title } from '@angular/platform-browser'; -import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ selector: 'app-prefilling-source-editor-component', @@ -80,7 +79,7 @@ export class PrefillingSourceEditorComponent extends BaseEditor { - this.router.navigate(['/reference-type']); - this.httpErrorHandlingService.handleBackedRequestError(error); - }); + error => { + this.router.navigate(['/reference-type']); + this.httpErrorHandlingService.handleBackedRequestError(error); + }); } selectedReferenceTypeChanged(id: Guid): void { diff --git a/dmp-frontend/src/app/ui/admin/reference/editor/reference-editor.component.ts b/dmp-frontend/src/app/ui/admin/reference/editor/reference-editor.component.ts index e8486c881..4cb3ff656 100644 --- a/dmp-frontend/src/app/ui/admin/reference/editor/reference-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/reference/editor/reference-editor.component.ts @@ -1,21 +1,24 @@ +import { DatePipe } from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { FormArray, UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; +import { Title } from '@angular/platform-browser'; import { ActivatedRoute, Router } from '@angular/router'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { ReferenceService } from '@app/core/services/reference/reference.service'; -import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { DatePipe } from '@angular/common'; import { IsActive } from '@app/core/common/enum/is-active.enum'; import { AppPermission } from '@app/core/common/enum/permission.enum'; import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type'; import { Reference, ReferencePersist } from '@app/core/model/reference/reference'; import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-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'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.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,10 +32,6 @@ import { map, takeUntil } from 'rxjs/operators'; import { ReferenceEditorModel } from './reference-editor.model'; import { ReferenceEditorResolver } from './reference-editor.resolver'; import { ReferenceEditorService } from './reference-editor.service'; -import { LockService } from '@app/core/services/lock/lock.service'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { Title } from '@angular/platform-browser'; -import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; @Component({ @@ -92,8 +91,8 @@ export class ReferenceEditorComponent extends BaseEditor { @@ -115,16 +113,16 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen onCallbackError(errorResponse: HttpErrorResponse) { console.log("Error:", errorResponse); - + this.httpErrorHandlingService.handleBackedRequestError(errorResponse) - + const error: HttpError = this.httpErrorHandlingService.getError(errorResponse); if (error.statusCode === 400) { this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error); this.formService.validateAllFormFields(this.formGroup); } } - + onCallbackSuccess(data?: any): void { console.log("Success:", data); @@ -225,7 +223,7 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen if (culture == null || culture.displayName == null - || culture.nativeName == null) + || culture.nativeName == null) return undefined; return culture.displayName + '-' + culture.nativeName; diff --git a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/tenant-configuration-editor.component.ts b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/tenant-configuration-editor.component.ts index 18fa71318..9ee4434bf 100644 --- a/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/tenant-configuration-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/tenant-configuration/editor/tenant-configuration-editor.component.ts @@ -1,6 +1,5 @@ import { Component } from '@angular/core'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { BaseComponent } from '@common/base/base.component'; 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 e65d5dbc2..838eb6c41 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 @@ -1,18 +1,20 @@ +import { DatePipe } from '@angular/common'; import { Component, OnInit } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Router } from '@angular/router'; -import { TenantService } from '@app/core/services/tenant/tenant.service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { DatePipe } from '@angular/common'; import { IsActive } from '@app/core/common/enum/is-active.enum'; 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 { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { LockService } from '@app/core/services/lock/lock.service'; import { LoggingService } from '@app/core/services/logging/logging-service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { TenantService } from '@app/core/services/tenant/tenant.service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.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'; @@ -23,12 +25,9 @@ import { FilterService } from '@common/modules/text-filter/filter-service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; +import { TenantEditorModel } from './tenant-editor.model'; import { TenantEditorResolver } from './tenant-editor.resolver'; 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({ diff --git a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts index c50679dbe..d17c30cab 100644 --- a/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts +++ b/dmp-frontend/src/app/ui/annotations/annotation-dialog-component/annotation-dialog.component.ts @@ -159,11 +159,6 @@ export class AnnotationDialogComponent extends BaseComponent { this.threads.add(element.threadId); }); console.log(this.parentAnnotationsPerThread); - // console.log(this.comments); - // console.log(this.threads); - // console.log(this.parentAnnotationsPerThread); - // console.log(this.annotationsPerThread); - // this.annotationsChanged.emit(this.threads); }, error => this.onCallbackError(error), ); diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts index 1ae4fd35d..62d9dfa1a 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts @@ -2,7 +2,7 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { AppPermission } from '@app/core/common/enum/permission.enum'; -import { DescriptionTemplate, DescriptionTemplateBaseFieldData, DescriptionTemplateDefaultValue, DescriptionTemplateDefinition, DescriptionTemplateExternalDatasetData, DescriptionTemplateField, DescriptionTemplateFieldSet, DescriptionTemplateMultiplicity, DescriptionTemplatePage, DescriptionTemplateReferenceTypeData, DescriptionTemplateRule, DescriptionTemplateSection, DescriptionTemplateSelectData, DescriptionTemplateSelectOption, DescriptionTemplateUploadData, DescriptionTemplateUploadOption } from '@app/core/model/description-template/description-template'; +import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { Description, DescriptionExternalIdentifier, DescriptionField, DescriptionPropertyDefinition, DescriptionPropertyDefinitionFieldSet, DescriptionPropertyDefinitionFieldSetItem, DescriptionReference, DescriptionReferenceData, DescriptionTag } from '@app/core/model/description/description'; import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp'; @@ -131,10 +131,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver { (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.label)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.ordinal)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), - // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.id)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), - // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.label)].join('.'), - // (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.minMultiplicity)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.maxMultiplicity)].join('.'), (prefix ? prefix + '.' : '') + [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.prefillingSources), nameof(x => x.id)].join('.'), @@ -169,19 +166,19 @@ export class DescriptionEditorResolver extends BaseEditorResolver { return this.descriptionService.getSingle(Guid.parse(id), fields).pipe(tap(d => this.breadcrumbService.addIdResolvedValue(d.id.toString(), d.label))); } else if (dmpId != null && dmpSectionId != null && copyDmpId == null) { return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields()) - .pipe(tap(x => { - this.breadcrumbService.addIdResolvedValue(`${x.id}/${dmpSectionId}`, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW")); + .pipe(tap(x => { + this.breadcrumbService.addIdResolvedValue(`${x.id}/${dmpSectionId}`, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW")); - }), takeUntil(this._destroyed), map(dmp => { + }), takeUntil(this._destroyed), map(dmp => { - const description: Description = {}; - description.dmp = dmp; - description.dmpDescriptionTemplate = { - sectionId: Guid.parse(dmpSectionId) - } - return description; - })); - } else if (copyDmpId != null && id != null && dmpSectionId != null) { + const description: Description = {}; + description.dmp = dmp; + description.dmpDescriptionTemplate = { + sectionId: Guid.parse(dmpSectionId) + } + return description; + })); + } else if (copyDmpId != null && id != null && dmpSectionId != null) { return this.dmpService.getSingle(Guid.parse(copyDmpId), DescriptionEditorResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), concatMap(dmp => { return this.descriptionService.getSingle(Guid.parse(id), DescriptionEditorResolver.cloneLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), map(description => { @@ -197,9 +194,5 @@ export class DescriptionEditorResolver extends BaseEditorResolver { })); })); } - //TODO: check this - // else if (cloneid != null) { - // return this.descriptionService.clone(Guid.parse(cloneid), fields).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed)); - // } } } diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts index a390ee97f..634dfd2d8 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.routing.ts @@ -1,13 +1,10 @@ import { NgModule } from '@angular/core'; import { RouterModule, Routes } from '@angular/router'; -// import { DescriptionWizardComponent } from './description-wizard/description-wizard.component'; -import { AppPermission } from '@app/core/common/enum/permission.enum'; -import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service'; -// import { DescriptionOverviewComponent } from './overview/description-overview.component'; +import { AuthGuard } from '@app/core/auth-guard.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { PendingChangesGuard } from '@common/forms/pending-form-changes/pending-form-changes-guard.service'; import { DescriptionEditorComponent } from './description-editor.component'; import { DescriptionEditorResolver } from './description-editor.resolver'; -import { AuthGuard } from '@app/core/auth-guard.service'; const routes: Routes = [ { @@ -22,11 +19,7 @@ const routes: Routes = [ breadcrumbs: true, getFromTitleService: true, usePrefix: false - //title: 'DESCRIPTION-EDITOR.TITLE-EDIT-DESCRIPTION' - // , - // authContext: { - // permissions: [AppPermission.EditDescription] - // } + } }, { @@ -43,10 +36,6 @@ const routes: Routes = [ hideNavigationItem: true }), title: 'DESCRIPTION-EDITOR.TITLE-EDIT-DESCRIPTION', - // , - // authContext: { - // permissions: [AppPermission.EditDescription] - // } } }, { @@ -62,10 +51,6 @@ const routes: Routes = [ title: 'DESCRIPTION-EDITOR.TITLE-NEW', getFromTitleService: true, usePrefix: false - // , - // authContext: { - // permissions: [AppPermission.EditDescription] - // } } }, { @@ -81,66 +66,8 @@ const routes: Routes = [ title: 'DESCRIPTION-EDITOR.TITLE-NEW', getFromTitleService: true, usePrefix: false - // , - // authContext: { - // permissions: [AppPermission.EditDescription] - // } } }, - - // { - // path: 'edit/:id/finalize', - // component: DescriptionWizardComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumb: true, - // public: false, - // title: 'GENERAL.TITLES.DATASET-EDIT', - // finalize: true - // }, - // canDeactivate:[CanDeactivateGuard] - // }, - // { - // path: 'publicEdit/:publicId', - // component: DescriptionWizardComponent, - // //canActivate: [AuthGuard], - // data: { - // public: true, - // title: 'GENERAL.TITLES.DATASET-PUBLIC-EDIT' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, - // { - // path: 'new', - // component: DescriptionWizardComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-NEW' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, - // { - // path: 'copy/:id', - // component: DescriptionWizardComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-COPY' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, - // { - // path: 'profileupdate/:updateId', - // component: DescriptionWizardComponent, - // canActivate: [AuthGuard], - // data: { - // breadcrumb: true, - // title: 'GENERAL.TITLES.DATASET-UPDATE' - // }, - // canDeactivate:[CanDeactivateGuard] - // }, - ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts index 77251854e..3bad80402 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-form/components/form-field-set/form-field-set.component.ts @@ -35,18 +35,10 @@ export class DescriptionFormFieldSetComponent extends BaseComponent { return this.fieldSet.hasMultiplicity && this.fieldSet.multiplicity != null; } - - - - - isVisibleByVisibilityService: boolean = true; @Input() visibilityRulesService: VisibilityRulesService; @Input() path: String; - - @Input() datasetProfileId: String; - // @Input() form: UntypedFormGroup; @Input() isChild: Boolean = false; @Input() showDelete: Boolean = false; @Input() tocentry: ToCEntry; diff --git a/dmp-frontend/src/app/ui/description/listing/criteria/dataset-criteria.component.ts b/dmp-frontend/src/app/ui/description/listing/criteria/dataset-criteria.component.ts index 8181f59f8..7a1a11985 100644 --- a/dmp-frontend/src/app/ui/description/listing/criteria/dataset-criteria.component.ts +++ b/dmp-frontend/src/app/ui/description/listing/criteria/dataset-criteria.component.ts @@ -190,11 +190,6 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O ) { setTimeout(() => this.refreshCallback(true)); } - // if (this.refreshCallback != null && - // (this.criteria.like == null || this.criteria.like.length === 0 || this.criteria.like.length > 2) - // ) { - // this.refreshCallback(); - // } } filterTags(value: string): Observable { @@ -225,12 +220,6 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O const fields: Array = new Array(); fields.push('asc'); - // if (this.isPublic) { - // const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, null, { fields: fields }); - // dmpDataTableRequest.criteria = new ExploreDmpCriteriaModel(); - // dmpDataTableRequest.criteria.like = value; - // return this.dmpService.getPublicPaged(dmpDataTableRequest, "autocomplete"); - // } else { const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, null, { fields: fields }); dmpDataTableRequest.criteria = new DmpCriteria(); dmpDataTableRequest.criteria.like = value; 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 439db7b97..d6f01c4b8 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 @@ -12,6 +12,7 @@ import { AppPermission } from '@app/core/common/enum/permission.enum'; import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { Description } from '@app/core/model/description/description'; +import { DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp'; import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; @@ -20,36 +21,29 @@ import { DescriptionLookup } from '@app/core/query/description.lookup'; 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 { AnalyticsService } from '@app/core/services/matomo/analytics-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'; import { StartNewDmpDialogComponent } from '@app/ui/dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component'; -// import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { BaseComponent } from '@common/base/base.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; 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'; -import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @Component({ selector: 'app-description-listing-component', templateUrl: 'description-listing.component.html', styleUrls: ['./description-listing.component.scss'] }) -export class DescriptionListingComponent extends BaseComponent implements OnInit {//IBreadCrumbComponent +export class DescriptionListingComponent extends BaseComponent implements OnInit { @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; - // @ViewChild(DescriptionCriteriaComponent, { static: true }) criteria: DescriptionCriteriaComponent; - - // breadCrumbs: Observable; titlePrefix: String; dmpId: string; @@ -202,12 +196,12 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit this.refresh(this.lookup); } - orderByChanged(){ - if (this.formGroup.get('order').value == RecentActivityOrder.Status){ + orderByChanged() { + if (this.formGroup.get('order').value == RecentActivityOrder.Status) { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.status)] }; - } else if(this.formGroup.get('order').value == RecentActivityOrder.Label){ + } else if (this.formGroup.get('order').value == RecentActivityOrder.Label) { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.label)] }; - }else{ + } else { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.updatedAt)] }; } this.refresh(this.lookup); @@ -256,96 +250,35 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit [nameof(x => x.dmpDescriptionTemplate), nameof(x => x.sectionId)].join('.'), ] }; - if(this.isPublic){ + if (this.isPublic) { this.descriptionService.publicQuery(lookup).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (!result) { return []; } - this.totalCount = result.count; - if (lookup?.page?.offset === 0) this.listingItems = []; - this.listingItems.push(...result.items); - this.hasListingItems = true; - }, - (error) => this.httpErrorHandlingService.handleBackedRequestError(error)); - }else{ + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + this.listingItems.push(...result.items); + this.hasListingItems = true; + }, + (error) => this.httpErrorHandlingService.handleBackedRequestError(error)); + } else { this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (!result) { return []; } - this.totalCount = result.count; - if (lookup?.page?.offset === 0) this.listingItems = []; - result.items.forEach(description => { - if (description.status != DescriptionStatus.Canceled) this.listingItems.push(description); - }) - this.hasListingItems = true; - }, - (error) => this.httpErrorHandlingService.handleBackedRequestError(error)); + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + result.items.forEach(description => { + if (description.status != DescriptionStatus.Canceled) this.listingItems.push(description); + }) + this.hasListingItems = true; + }, + (error) => this.httpErrorHandlingService.handleBackedRequestError(error)); } } openFiltersDialog(): void { //TODO: Add filters dialog - - // const dialogRef = this.dialog.open(DescriptionCriteriaDialogComponent, { - // width: '456px', - // height: '100%', - // id: 'filters', - // restoreFocus: false, - // data: { - // isPublic: this.isPublic, - // status: this.status, - // criteria: this.criteria, - // formGroup: this.criteriaFormGroup, - // // criteria: this.grantId ? this.criteria : this.getDefaultCriteria(), - // updateDataFn: this.updateDataFn.bind(this) - // }, - // position: { right: '0px;' }, - // panelClass: 'dialog-side-panel' - // }); - - // dialogRef.afterClosed().subscribe(result => { - // }); } - // updateDataFn(criteria: DescriptionCriteriaComponent): void { - // this.criteriaFormGroup = criteria.formGroup; - // this.toDescriptionCriteria(criteria); - // this.refresh(); - // } - - // toDescriptionCriteria(criteria: DescriptionCriteriaComponent) { - // let formGroup = criteria.formGroup; - // this.criteria = { - // like: formGroup.get("like").value, - // status: formGroup.get("status").value, - // allVersions: formGroup.get("allVersions").value, - // role: formGroup.get("role").value - // } - // if (formGroup.get("tags") && formGroup.get("tags").value) { - // this.criteria.tags = formGroup.get("tags").value.map(x => (x)); - // } - // if (formGroup.get("collaborators") && formGroup.get("collaborators").value) { - // this.criteria.collaborators = formGroup.get("collaborators").value.map(x => x.id); - // } - // if (formGroup.get("dmpIds") && formGroup.get("dmpIds").value) { - // this.criteria.dmpIds = formGroup.get("dmpIds").value.map(x => x.id); - // } - // if (formGroup.get("groupIds") && formGroup.get("groupIds").value) { - // this.criteria.groupIds = formGroup.get("groupIds").value.map(x => x.groupId); - // } - // if (formGroup.get("grants") && formGroup.get("grants").value) { - // this.criteria.grants = formGroup.get("grants").value.map(x => x.id); - // } - // if (formGroup.get("organisations") && formGroup.get("organisations").value) { - // this.criteria.organisations = formGroup.get("organisations").value.map(x => x.id); - // } - // if (formGroup.get("descriptionTemplates") && formGroup.get("descriptionTemplates").value) { - // this.criteria.descriptionTemplates = formGroup.get("descriptionTemplates").value.map(x => x.id) - // } - // if (formGroup.get("grantStatus") && formGroup.get("grantStatus").value) { - // this.criteria.grantStatus = formGroup.get("grantStatus").value; - // } - // this.criteria.isPublic = this.isPublic; - // } - hasScrollbar(): boolean { return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight @@ -360,16 +293,16 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit public setDashboardTourDmpText(): void { this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' + - this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' + - this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' + - this.language.instant('DMP-LISTING.GET-IDEA'); + this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' + + this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' + + this.language.instant('DMP-LISTING.GET-IDEA'); this.dashboardTour.steps[0].title = this.dmpText; } public setDashboardTourDescriptionText(): void { this.descriptionText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' + - this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + - this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + + this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); this.dashboardTour.steps[1].title = this.descriptionText; } @@ -416,7 +349,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit } toggleSortDirection(): void { - this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; + this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; this.orderByChanged(); } } 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 0b3d6bf2d..b510b279c 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 @@ -1,6 +1,5 @@ -import { Component, OnInit } from '@angular/core'; -import { BaseComponent } from '@common/base/base.component'; import { Location } from '@angular/common'; +import { Component, OnInit } from '@angular/core'; import { UntypedFormBuilder, Validators } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; @@ -18,6 +17,7 @@ import { Dmp, DmpDescriptionTemplate, DmpUser, DmpUserRemovePersist } from '@app import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Reference } from '@app/core/model/reference/reference'; +import { User } from '@app/core/model/user/user'; import { AuthService } from '@app/core/services/auth/auth.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { DescriptionService } from '@app/core/services/description/description.service'; @@ -28,22 +28,21 @@ import { AnalyticsService } from '@app/core/services/matomo/analytics-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'; +import { UserService } from '@app/core/services/user/user.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; import { DescriptionValidationOutput } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.component'; import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dialog/dmp-invitation-dialog.component'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; +import { BaseComponent } from '@common/base/base.component'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { DescriptionCopyDialogComponent } from '../description-copy-dialog/description-copy-dialog.component'; -import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; -import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; -import { Observable, of } from 'rxjs'; -import { UserService } from '@app/core/services/user/user.service'; -import { User } from '@app/core/model/user/user'; @Component({ @@ -59,7 +58,6 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni isFinalized = false; isPublicView = true; hasPublishButton: boolean = true; - // breadCrumbs: Observable = observableOf(); expand = false; isLocked: Boolean; descriptionStatusEnum = DescriptionStatus; @@ -189,14 +187,14 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni } }); - if (this.isAuthenticated()) { - this.userService.getSingle(this.authentication.userId(), [ - nameof(x => x.id), - nameof(x => x.name)]) - .pipe(map(u => u.name)).subscribe(name => this.userName = name); - } else { - this.userName = ''; - } + if (this.isAuthenticated()) { + this.userService.getSingle(this.authentication.userId(), [ + nameof(x => x.id), + nameof(x => x.name)]) + .pipe(map(u => u.name)).subscribe(name => this.userName = name); + } else { + this.userName = ''; + } } get unauthorizedTootipText(): string { @@ -216,10 +214,10 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni }); } }, - error => { - this.router.navigate(['/descriptions']); - this.httpErrorHandlingService.handleBackedRequestError(error); - }); + error => { + this.router.navigate(['/descriptions']); + this.httpErrorHandlingService.handleBackedRequestError(error); + }); } onFetchingDeletedCallbackError(redirectRoot: string) { @@ -417,39 +415,39 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni finalize(description: Description) { this.descriptionService.validate([description.id]).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result[0].result == DescriptionValidationOutput.Invalid) { - this.router.navigate(['descriptions/edit/' + description.id + '/finalize']); - } else { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - restoreFocus: false, - data: { - message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'), - confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'), - cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'), - isDeleteConfirmation: false - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - const descriptionStatusPersist: DescriptionStatusPersist = { - id: description.id, - status: DescriptionStatus.Finalized, - hash: description.hash - }; - this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed)) - .subscribe(data => { - this.reloadPage(); - this.onUpdateCallbackSuccess() - }, (error: any) => { - this.onUpdateCallbackError(error) - }); - } - }, + .subscribe(result => { + if (result[0].result == DescriptionValidationOutput.Invalid) { + this.router.navigate(['descriptions/edit/' + description.id + '/finalize']); + } else { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'), + confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'), + cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'), + isDeleteConfirmation: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const descriptionStatusPersist: DescriptionStatusPersist = { + id: description.id, + status: DescriptionStatus.Finalized, + hash: description.hash + }; + this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.reloadPage(); + this.onUpdateCallbackSuccess() + }, (error: any) => { + this.onUpdateCallbackError(error) + }); + } + }, + error => this.httpErrorHandlingService.handleBackedRequestError(error)); + } + }, error => this.httpErrorHandlingService.handleBackedRequestError(error)); - } - }, - error => this.httpErrorHandlingService.handleBackedRequestError(error)); } hasReversableStatus(description: Description): boolean { 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 dcb261147..d498e5379 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 @@ -317,11 +317,6 @@ export class DmpEditorComponent extends BaseEditor implemen formSubmit(): void { this.formService.removeAllBackEndErrors(this.formGroup); - // this.formService.touchAllFormFields(this.formGroup); - // if (this.formGroup.get('label').valid && this.formGroup.get('blueprint').valid && this.formGroup.get('status').valid - // && this.formGroup.get('descriptionTemplates').valid) { - // this.persistEntity(); - // } this.persistEntity(); } diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts index e8aa731fe..df91b06c3 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.resolver.ts @@ -53,9 +53,6 @@ export class DmpEditorResolver extends BaseEditorResolver { [nameof(x => x.properties), nameof(x => x.contacts), nameof(x => x.email)].join('.'), - // [nameof(x => x.entityDois), nameof(x => x.id)].join('.'), - // [nameof(x => x.entityDois), nameof(x => x.repositoryId)].join('.'), - // [nameof(x => x.entityDois), nameof(x => x.doi)].join('.'), [nameof(x => x.descriptions), nameof(x => x.id)].join('.'), [nameof(x => x.descriptions), nameof(x => x.label)].join('.'), [nameof(x => x.descriptions), nameof(x => x.status)].join('.'), @@ -88,11 +85,6 @@ export class DmpEditorResolver extends BaseEditorResolver { [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.isActive)].join('.'), - // nameof(x => x.id), - // nameof(x => x.label), - // nameof(x => x.status), - // nameof(x => x.description), - // nameof(x => x.status), ...DmpEditorResolver.blueprintLookupFields(nameof(x => x.blueprint)), ] diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html deleted file mode 100644 index 3228e5b6a..000000000 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html +++ /dev/null @@ -1,33 +0,0 @@ -
-
-

{{'DMP-EDITOR.DATASET-INFO.SECOND-INTRO' | translate}}

-
-
-
-
-
4.1 {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}}*
-
-
{{'DMP-EDITOR.DATASET-INFO.HINT' | translate}}
-
info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
-
-
- - {{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}} - - - - {{formGroup.get('profiles').getError('backendError').message}} - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - - -
-
- {{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.SECOND-STEP.FIELDS.HELP' | translate}} -
-
-
-
-
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss deleted file mode 100644 index 4d5220f39..000000000 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss +++ /dev/null @@ -1,84 +0,0 @@ -.main-info { - // position: relative; - // left: 362px; - // width: calc(100% - 366px); - - .intro { - text-align: left; - font-weight: 400; - letter-spacing: 0px; - color: #212121; - opacity: 1; - margin: 3rem 0rem 3rem 0rem; - } - - .heading { - text-align: left; - font-weight: 700; - font-size: 18px; - letter-spacing: 0px; - color: #212121; - opacity: 0.81; - margin-top: 1.625rem; - margin-bottom: 0.625rem; - } - - .hint { - text-align: left; - font-weight: 400; - font-size: 16px; - letter-spacing: 0px; - color: #212121; - opacity: 0.81; - margin-bottom: 2.125rem; - } - - .title-form, - .description-form { - text-align: left; - font-weight: 400; - font-size: 16px; - letter-spacing: 0.15px; - color: #7d7d7d; - opacity: 1; - margin-bottom: 1rem; - } - - // textarea::placeholder { - // font-style: oblique; - // } - - .input-btn { - border: none; - color: #aaaaaa; - background-color: #ffffff00; - cursor: pointer; - } - - .input-btn :hover { - color: var(--primary-color-3) !important; - } - - .not-found { - font-size: 0.875rem; - font-weight: 400; - padding: 0rem 0.5rem 0rem 0rem; - } -} - -::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-outline { - background: #fafafa !important; -} - -::ng-deep .profile-form .mat-form-field-appearance-outline .mat-form-field-infix { - font-size: 1rem; - padding: 0.6em 0 1em 0 !important; -} - -::ng-deep .profile-form .mat-form-field-wrapper { - padding-bottom: 0rem; -} - -:host ::ng-deep .multiple-auto-complete .align-arrow-right { - bottom: 1rem !important; -} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts deleted file mode 100644 index d56a20819..000000000 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.ts +++ /dev/null @@ -1,258 +0,0 @@ -import { Component, EventEmitter, Input, OnInit, Output } from '@angular/core'; -import { UntypedFormGroup } from '@angular/forms'; -import { MatDialog } from '@angular/material/dialog'; -import { ActivatedRoute, Router } from '@angular/router'; -import { DmpBlueprintDefinition } from '@app/core/model/dmp-blueprint/dmp-blueprint'; -import { RequestItem } from '@app/core/query/request-item'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; -import { BaseComponent } from '@common/base/base.component'; -import { TranslateService } from '@ngx-translate/core'; -import { Observable } from 'rxjs'; -import { map, takeUntil } from 'rxjs/operators'; -import { AvailableProfilesComponent } from '../available-profiles/available-profiles.component'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; - -@Component({ - selector: 'dataset-info', - templateUrl: './dataset-info.component.html', - styleUrls: ['./dataset-info.component.scss'] -}) -export class DatasetInfoComponent extends BaseComponent implements OnInit { - - @Input() formGroup: UntypedFormGroup = null; - // @Input() datasetFormGroup: FormGroup = null; - @Input() isUserOwner: boolean; - @Input() dmp: DmpEditorModel; - @Input() hasDmpId: boolean; - @Input() isPublic: boolean; - @Input() isFinalized: boolean; - @Input() isNewVersion: boolean; - @Input() isClone: boolean; - @Output() onFormChanged: EventEmitter = new EventEmitter(); - - availableProfiles: DatasetProfileModel[] = []; - - selectedDmpBlueprintDefinition: DmpBlueprintDefinition; - profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; - - datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel; - datasetProfileDefinitionFormGroup: UntypedFormGroup; - - constructor( - private language: TranslateService, - private configurationService: ConfigurationService, - private externalSourcesService: ExternalSourcesService, - private datasetWizardService: DatasetWizardService, - private dialog: MatDialog, - private _service: DmpService, - private dmpBlueprintService: DmpBlueprintService, - private router: Router, - private route: ActivatedRoute, - private uiNotificationService: UiNotificationService - ) { - super(); - } - - ngOnInit() { - - try { - const profiles = this.formGroup.get('profiles').value as { id: string, label: string }[]; - profiles.sort((a, b) => a.label.localeCompare(b.label)); - } catch { - console.info('Could not sort profiles'); - } - - - - - this.profilesAutoCompleteConfiguration = { - filterFn: this.filterProfiles.bind(this), - initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'], - subtitleFn: (item) => item['description'], - popupItemActionIcon: 'visibility' - }; - - if (this.formGroup.get('definition')) { this.selectedDmpBlueprintDefinition = this.formGroup.get('definition').value; } - this.registerFormEventsForDmpBlueprint(); - - if (this.hasDmpId) { - this.loadDatasetProfiles(); - this.profilesAutoCompleteConfiguration = { - filterFn: this.filterProfiles.bind(this), - initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'], - subtitleFn: (item) => item['description'], - popupItemActionIcon: 'visibility' - }; - } - } - - // Researchers - filterProfiles(value: string): Observable { - const request = new DataTableRequest(null, null, { fields: ['+label'] }); - const criteria = new DatasetProfileCriteria(); - criteria.like = value; - request.criteria = criteria; - return this._service.searchDmpBlueprints(request); - } - - registerFormEventsForDmpBlueprint(definitionProperties?: DmpBlueprintDefinition): void { - this.formGroup.get('profile').valueChanges - .pipe( - takeUntil(this._destroyed)) - .subscribe(Option => { - if (Option instanceof Object) { - this.selectedDmpBlueprintDefinition = null; - this.dmpBlueprintService.getSingle(Option.id) - .pipe(takeUntil(this._destroyed)) - .subscribe(result => { - this.selectedDmpBlueprintDefinition = result.definition; - }); - } else { - this.selectedDmpBlueprintDefinition = null; - } - this.selectedDmpBlueprintDefinition = definitionProperties; - }) - } - - loadDatasetProfiles() { - const datasetProfileRequestItem: RequestItem = new RequestItem(); - datasetProfileRequestItem.criteria = new DatasetProfileCriteria(); - this.formGroup.get('id').value ? datasetProfileRequestItem.criteria.id = this.formGroup.get('id').value : datasetProfileRequestItem.criteria.id = this.formGroup.get('datasets')['controls'][0].get('dmp').value.id; - if (datasetProfileRequestItem.criteria.id) { - this.datasetWizardService.getAvailableProfiles(datasetProfileRequestItem) - .pipe(takeUntil(this._destroyed)) - .subscribe(items => { - this.availableProfiles = items; - }); - } - } - - allAvailableProfiles(event: MouseEvent) { - event.stopPropagation(); - const dialogRef = this.dialog.open(AvailableProfilesComponent, { - data: { - profiles: this.formGroup.get('profiles') - } - }); - - return false; - } - - // dmpValueChanged(dmp: DmpListingModel) { - // if (dmp) { - // this.formGroup.get('profile').enable(); - // this.loadDatasetProfiles(); - // } - // else { - // this.availableProfiles = []; - // this.formGroup.get('profile').reset(); - // this.formGroup.get('profile').disable(); - // this.formGroup.removeControl('datasetProfileDefinition'); - // } - // } - - // registerFormListeners() { - // this.formGroup.get('datasets')['controls'][0].get('dmp').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // this.dmpValueChanged(x); - // }); - // this.formGroup.get('profile').valueChanges - // .pipe(takeUntil(this._destroyed)) - // .subscribe(x => { - // //this.datasetProfileValueChanged(x); - // }); - // } - - // datasetProfileValueChanged(profiledId: string) { - // if (profiledId && profiledId.length > 0) { - // this.formGroup.removeControl('datasetProfileDefinition'); - // this.getDefinition(); - // } - // } - - // getDefinition() { - // this.datasetWizardService.getDefinition(this.formGroup.get('profile').value) - // .pipe(takeUntil(this._destroyed)) - // .subscribe(item => { - // this.formGroup.get('datasets')['controls'][0].datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item); - // this.datasetProfileDefinitionModel = this.formGroup.get('datasets')['controls'][0].datasetProfileDefinition; - // this.formGroup.addControl('datasetProfileDefinition', this.datasetProfileDefinitionModel.buildForm()); - // }); - // } - - onRemoveTemplate(event) { - let found = false; - const profiles = this.formGroup.get('profiles').value; - this.formGroup.get('datasets')['controls'].forEach(element => { - if (element.get('profile').value.id === event.id) { - found = true; - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success); - } - }); - if (found) { - this.formGroup.get('profiles').setValue(profiles); - this.profilesAutoCompleteConfiguration = { - filterFn: this.filterProfiles.bind(this), - initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'], - subtitleFn: (item) => item['description'], - popupItemActionIcon: 'visibility' - }; - - } - } - - onPreviewTemplate(event) { - const dialogRef = this.dialog.open(DatasetPreviewDialogComponent, { - width: '590px', - minHeight: '200px', - restoreFocus: false, - data: { - template: event - }, - panelClass: 'custom-modalbox' - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - let profiles = this.formGroup.get('profiles').value; - profiles.push(event); - this.formGroup.get('profiles').setValue(profiles); - this.profilesAutoCompleteConfiguration = { - filterFn: this.filterProfiles.bind(this), - initialItems: (excludedItems: any[]) => this.filterProfiles('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), - displayFn: (item) => item['label'], - titleFn: (item) => item['label'], - subtitleFn: (item) => item['description'], - popupItemActionIcon: 'visibility' - }; - } - }); - } - onOptionSelected() { - try { - const profiles = this.formGroup.get('profiles').value as { id: string, label: string }[]; - const profileCounts: Map = new Map(); - profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id) : 0) + 1)); - const duplicateProfiles = profiles.filter((value) => { - let isOk = profileCounts.get(value.id) > 1; - if (isOk) { - profileCounts.set(value.id, 0); - } - return isOk; - }); - duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); - profiles.sort((a, b) => a.label.localeCompare(b.label)); - } catch { - console.info('Could not sort Dataset Templates') - } - } -} 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 8a276ccc1..bfb75e732 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 @@ -6,43 +6,41 @@ import { MatDialog } from '@angular/material/dialog'; import { MatPaginator } from '@angular/material/paginator'; import { MatSort } from '@angular/material/sort'; 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 { 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'; -// import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; -// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; +import { DescriptionStatus } from '@app/core/common/enum/description-status'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { AppPermission } from '@app/core/common/enum/permission.enum'; +import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order'; +import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; import { Description } from '@app/core/model/description/description'; import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint'; import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp'; +import { DmpReference } from '@app/core/model/dmp/dmp-reference'; +import { ReferenceType } from '@app/core/model/reference-type/reference-type'; +import { Reference } from '@app/core/model/reference/reference'; import { DmpLookup } from '@app/core/query/dmp.lookup'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { AnalyticsService } from '@app/core/services/matomo/analytics-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'; import { BaseComponent } from '@common/base/base.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { SortDirection } from '@common/modules/hybrid-listing/hybrid-listing.component'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { NgDialogAnimationService } from "ng-dialog-animation"; import { debounceTime, takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; -import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; -import { DmpReference } from '@app/core/model/dmp/dmp-reference'; -import { Reference } from '@app/core/model/reference/reference'; -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'; -import { DescriptionTemplate } from '@app/core/model/description-template/description-template'; -import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; @Component({ selector: 'app-dmp-listing-component', templateUrl: 'dmp-listing.component.html', styleUrls: ['./dmp-listing.component.scss'], }) -export class DmpListingComponent extends BaseComponent implements OnInit { //IBreadCrumbComponent +export class DmpListingComponent extends BaseComponent implements OnInit { @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; @ViewChild(MatSort) sort: MatSort; @@ -174,8 +172,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr this.language.instant('DMP-LISTING.GET-IDEA'); this.dashboardTour.steps[1].title = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' + - this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + - this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + + this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); this.guidedTourService.startTour(this.dashboardTour); }); @@ -186,12 +184,12 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr this.refresh(this.lookup); } - orderByChanged(){ - if (this.formGroup.get('order').value == RecentActivityOrder.Status){ + orderByChanged() { + if (this.formGroup.get('order').value == RecentActivityOrder.Status) { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.status)] }; - } else if(this.formGroup.get('order').value == RecentActivityOrder.Label){ + } else if (this.formGroup.get('order').value == RecentActivityOrder.Label) { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.label)] }; - }else{ + } else { this.lookup.order = { items: [this.sortingDirectionPrefix + nameof(x => x.updatedAt)] }; } this.refresh(this.lookup); @@ -234,10 +232,6 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.hasTemplates)].join('.'), [nameof(x => x.blueprint), nameof(x => x.definition), nameof(x => x.sections), nameof(x => x.descriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), - // [nameof(x => x.descriptionTemplate), nameof(x => x.label)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.id)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.label)].join('.'), - // [nameof(x => x.dmp), nameof(x => x.accessType)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.user.id)].join('.'), [nameof(x => x.dmpUsers), nameof(x => x.role)].join('.'), @@ -253,43 +247,41 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.sectionId)].join('.'), [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.descriptionTemplateGroupId)].join('.'), [nameof(x => x.dmpDescriptionTemplates), nameof(x => x.isActive)].join('.'), - - // [nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), + ] }; - if(this.isPublic){ + if (this.isPublic) { this.dmpService.publicQuery(lookup).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (!result) { return []; } - this.totalCount = result.count; - if (lookup?.page?.offset === 0) this.listingItems = []; - this.listingItems.push(...result.items); - this.hasListingItems = true; - }, - error => this.httpErrorHandlingService.handleBackedRequestError(error)); + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + this.listingItems.push(...result.items); + this.hasListingItems = true; + }, + error => this.httpErrorHandlingService.handleBackedRequestError(error)); - }else{ + } else { this.dmpService.query(lookup).pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (!result) { return []; } - this.totalCount = result.count; - if (lookup?.page?.offset === 0) this.listingItems = []; - result.items.forEach(x=> { - if (x.descriptions) { - if (x.status == DmpStatus.Finalized) { - x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized); - } else { - x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled); + .subscribe(result => { + if (!result) { return []; } + this.totalCount = result.count; + if (lookup?.page?.offset === 0) this.listingItems = []; + result.items.forEach(x => { + if (x.descriptions) { + if (x.status == DmpStatus.Finalized) { + x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized); + } else { + x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled); + } } - } - x.dmpUsers = x.dmpUsers.filter(x=> x.isActive === IsActive.Active); - this.listingItems.push(x); - }) - // this.listingItems.push(...result.items); - this.hasListingItems = true; - }, - error => this.httpErrorHandlingService.handleBackedRequestError(error)); + x.dmpUsers = x.dmpUsers.filter(x => x.isActive === IsActive.Active); + this.listingItems.push(x); + }) + this.hasListingItems = true; + }, + error => this.httpErrorHandlingService.handleBackedRequestError(error)); } } @@ -303,92 +295,12 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr openShareDialog(rowId: any, rowName: any) { //TODO: add this - // const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - // autoFocus: false, - // data: { - // dmpId: rowId, - // dmpName: rowName - // } - // }); } openFiltersDialog(): void { //TODO: Add filters dialog - // const dialogRef = this.dialog.open(DmpCriteriaDialogComponent, { - // width: '456px', - // height: '100%', - // id: 'filters', - // restoreFocus: false, - // data: { - // showGrant: this.showGrant, - // isPublic: this.isPublic, - // criteria: this.criteria, - // formGroup: this.criteriaFormGroup, - // // criteria: this.grantId ? this.criteria : this.getDefaultCriteria(), - // updateDataFn: this.updateDataFn.bind(this) - // }, - // position: { right: '0px;' }, - // panelClass: 'dialog-side-panel', - // // may remove NgDialogAnimationService package - // // animation: { - // // to: "left", - // // incomingOptions: { - // // keyframeAnimationOptions: { duration: 300, easing: "ease-in-out" } - // // } - // // } - // }); - - // dialogRef.afterClosed().subscribe(result => { - // }); } - // updateDataFn(criteria: DmpCriteriaComponent): void { - // this.criteriaFormGroup = criteria.formGroup; - // this.toDmpCriteria(criteria); - // this.refresh(); - // } - - // toDmpCriteria(criteria: DmpCriteriaComponent): void { - // let formGroup = criteria.formGroup; - // this.criteria = { - // like: formGroup.get('like').value, - // grants: formGroup.get('grants').value, - // role: formGroup.get('role').value - // } - // this.criteria.status = formGroup.get('status').value; - // this.setPublicCriteria(formGroup); - // if (formGroup.get('datasetTemplates').value) - // this.criteria.datasetTemplates = formGroup.get('datasetTemplates').value.map(x => x.id); - // if (formGroup.get('collaborators').value) - // this.criteria.collaborators = formGroup.get('collaborators').value.map(x => x.id); - // if (formGroup.get('organisations').value) - // this.criteria.organisations = formGroup.get('organisations').value.map(x => x.id); - // if (this.itemId) { - // this.criteria.groupIds = [this.itemId]; - // this.criteria.allVersions = true; - // } - // this.criteria.grantStatus = formGroup.get('grantStatus').value; - // } - - // setPublicCriteria(formGroup?: UntypedFormGroup): void { - // if (!isNullOrUndefined(formGroup)) { - // if (formGroup.get('status').value == 2) { - // this.criteria.status = 1; - // this.criteria.isPublic = true; - // } else { - // this.criteria.isPublic = false; - // } - // } - - // this.criteria.onlyPublic = this.isPublic; - // if (this.isPublic) { - // this.criteria.isPublic = true; - // } - // // } else { - // // this.criteria.isPublic = false; - // // } - // } - hasScrollbar(): boolean { return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight } @@ -403,8 +315,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr public setDashboardTourDatasetText(): void { const datasetText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' + - this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + - this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); + this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' + + this.language.instant('DESCRIPTION-LISTING.GET-IDEA'); this.dashboardTour.steps[1].title = datasetText; } @@ -419,7 +331,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr } toggleSortDirection(): void { - this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; + this.sortDirection = this.isAscending ? this.sortDirection = SortDirection.Descending : this.sortDirection = SortDirection.Ascending; this.orderByChanged(); } } 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 645308910..2e2cef224 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 @@ -1,18 +1,10 @@ +import { Location } from '@angular/common'; import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, Params, Router } from '@angular/router'; -import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { DmpService } from '@app/core/services/dmp/dmp.service'; -import { - SnackBarNotificationLevel, - UiNotificationService -} from '@app/core/services/notification/ui-notification-service'; -import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; -// import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import { Location } from '@angular/common'; import { DescriptionStatus } from '@app/core/common/enum/description-status'; import { DmpAccessType } from '@app/core/common/enum/dmp-access-type'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { DmpUserRole } from '@app/core/common/enum/dmp-user-role'; import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status'; import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type'; @@ -27,18 +19,29 @@ import { DmpReference } from '@app/core/model/dmp/dmp-reference'; import { EntityDoi } from '@app/core/model/entity-doi/entity-doi'; import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Reference } from '@app/core/model/reference/reference'; +import { User } from '@app/core/model/user/user'; +import { AuthService } from '@app/core/services/auth/auth.service'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { DepositService } from '@app/core/services/deposit/deposit.service'; import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.service'; +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 { AnalyticsService } from '@app/core/services/matomo/analytics-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'; +import { UserService } from '@app/core/services/user/user.service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { FileUtils } from '@app/core/services/utilities/file-utils.service'; import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; +import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; import { BaseComponent } from '@common/base/base.component'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; @@ -49,11 +52,6 @@ import { DmpEditorResolver } from '../dmp-editor-blueprint/dmp-editor.resolver'; import { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component'; import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component'; import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-dialog.component'; -import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; -import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; -import { User } from '@app/core/model/user/user'; -import { UserService } from '@app/core/services/user/user.service'; -import { Observable, of } from 'rxjs'; @Component({ selector: 'app-dmp-overview', @@ -70,8 +68,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { isFinalized = false; isPublicView = true; hasPublishButton: boolean = true; - // breadCrumbs: Observable = observableOf(); - // isUserOwner: boolean; isLocked: Boolean; textMessage: any; selectedModel: EntityDoi; @@ -116,7 +112,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { ) { super(); } - + ngOnInit() { this.analyticsService.trackPageView(AnalyticsService.DmpOverview); // Gets dmp data using parameter id @@ -210,10 +206,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.depositRepos = repos; }, error => this.depositRepos = []); - + this.userService.getSingle(this.authentication.userId(), [ - nameof(x => x.id), - nameof(x => x.name)]) + nameof(x => x.id), + nameof(x => x.name)]) .pipe(map(u => u.name)).subscribe(name => this.userName = name); } else { this.userName = ''; @@ -324,90 +320,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { }); } - // private checkForGrant(blueprint: DmpBlueprintDefinition) { - // let hasGrant = false; - // blueprint.sections.forEach(section => section.fields.forEach( - // field => { - // if (field.category as unknown === DmpBlueprintFieldCategory.System && field.systemFieldType === DmpBlueprintSystemFieldType.GRANT) { - // hasGrant = true; - // } - // } - // )); - // if (!hasGrant) { - // this.formGroup.removeControl('grant'); - // } - // } - - // private checkForFunder(blueprint: DmpBlueprintDefinition) { - // let hasFunder = false; - // blueprint.sections.forEach(section => section.fields.forEach( - // field => { - // if (field.category as unknown === DmpBlueprintFieldCategory.System && field.systemFieldType === DmpBlueprintSystemFieldType.FUNDER) { - // hasFunder = true; - // } - // } - // )); - // if (!hasFunder) { - // this.formGroup.removeControl('funder'); - // } - // } - - // private checkForProject(blueprint: DmpBlueprintDefinition) { - // let hasProject = false; - // blueprint.sections.forEach(section => section.fields.forEach( - // field => { - // if (field.category as unknown === DmpBlueprintFieldCategory.System && field.systemFieldType === DmpBlueprintSystemFieldType.PROJECT) { - // hasProject = true; - // } - // } - // )); - // if (!hasProject) { - // this.formGroup.removeControl('project'); - // } - // } - - // openCloneDialog(isNewVersion: boolean) { - // const dialogRef = this.dialog.open(CloneDialogComponent, { - // maxWidth: '900px', - // maxHeight: '80vh', - // data: { - // formGroup: this.formGroup, - // descriptions: this.dmp.descriptions, - // isNewVersion: isNewVersion, - // confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), - // cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), - // } - // }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (result) { - // if (!isNewVersion) { - // this.dmpService.clone(this.formGroup.getRawValue(), this.dmp.id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => this.onCallbackSuccess(complete), - // error => this.onCallbackError(error) - // ); - // } else if (isNewVersion) { - // this.dmpService.newVersion(this.formGroup.getRawValue(), this.dmp.id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => this.onCallbackSuccess(complete), - // error => this.onCallbackError(error) - // ); - // } - // } - // }); - // } - - // onCallbackSuccess(dmpId: String): void { - // this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - // this.router.navigate(['/plans/edit/', dmpId]); - // } - - // onCallbackError(error: any) { - // this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Error); - // } - deleteClicked() { let dialogRef: any; if (this.dmp.descriptions && this.dmp.descriptions.length > 0) { @@ -520,38 +432,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } - // private checkIfAnyProfileIsUsedLessThanMin(dmp: Dmp): Observable { - // const blueprintId = dmp.profile.id; - // return this.dmpBlueprintService.getSingle(Guid.parse(blueprintId)) - // .pipe(map(result => { - // return result.definition.sections.some(section => { - // if (!section.hasTemplates) - // return false; - // return section.descriptionTemplates.some(template => { - // if (!(template.minMultiplicity > 0)) - // return false; - // let count = 0; - // dmp.descriptions.filter(description => description.dmpSectionIndex === (section.ordinal - 1)).forEach(description => { - // if (Guid.parse(description.profile.id) === template.descriptionTemplateId) { - // count++; - // } - // }) - // if (count < template.minMultiplicity) { - // this.dialog.open(PopupNotificationDialogComponent, { - // data: { - // title: this.language.instant('DMP-OVERVIEW.MIN-DESCRIPTIONS-DIALOG.TITLE', { 'minMultiplicity': template.minMultiplicity }), - // message: this.language.instant('DMP-OVERVIEW.MIN-DESCRIPTIONS-DIALOG.MESSAGE',) - // }, maxWidth: '30em' - // }); - // return true; - // } - // else - // return false; - // }) - // }) - // }), takeUntil(this._destroyed)); - // } - public isAuthenticated(): boolean { return this.authentication.currentAccountIsAuthenticated(); } @@ -630,16 +510,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { }); } - // updateUsers() { - // return this.dmpService.updateUsers(this.dmp.id, this.dmp.users).pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => { - // this.onUpdateCallbackSuccess(); - // }, - // error => this.onUpdateCallbackError(error) - // ); - // } - removeUserFromDmp(dmpUser: DmpUser) { const dialogRef = this.dialog.open(ConfirmationDialogComponent, { data: { @@ -714,10 +584,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { }); } }, - error => { - this.router.navigate(['/plans']); - this.httpErrorHandlingService.handleBackedRequestError(error); - }); + error => { + this.router.navigate(['/plans']); + this.httpErrorHandlingService.handleBackedRequestError(error); + }); } private lookupFields(): string[] { diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.ts b/dmp-frontend/src/app/ui/navbar/navbar.component.ts index 17208d1b0..9c53db064 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.ts +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.ts @@ -229,21 +229,6 @@ export class NavbarComponent extends BaseComponent implements OnInit { } }; - // getTitle() { - // var titlee = this.location.prepareExternalUrl(this.location.path()); - // if (titlee.charAt(0) === '#') { - // titlee = titlee.slice(2); - // } - // titlee = titlee.split('/').pop(); - - // for (var item = 0; item < this.listTitles.length; item++) { - // if (this.listTitles[item].path === titlee) { - // return this.listTitles[item].title; - // } - // } - // return 'Dashboard'; - // } - public getCurrentLanguage(): any { const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage()); return lang; diff --git a/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts b/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts index fff2af37c..664e044c0 100644 --- a/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts +++ b/dmp-frontend/src/app/ui/reference/reference-field/reference-field.component.ts @@ -113,13 +113,6 @@ export class ReferenceFieldComponent extends BaseComponent implements OnInit, On } else { this.referenceToUse = referenceToUse; } - // if (this.referenceToUseInitialized && (!referenceToUse.map(x => x.reference).every(x => this.referenceToUse.map(y => y.reference).includes(x)) || - // !this.referenceToUse.map(x => x.reference).every(x => referenceToUse.map(y => y.reference).includes(x)))) { - // this.form.setValue(null, {onlySelf: true, emitEvent: false}); - // } - - // this.referenceToUse = referenceToUse; - // this.referenceToUseInitialized = true; if (this.multiple) { this.multipleAutoCompleteSearchConfiguration = this.referenceService.getMultipleAutoCompleteSearchConfiguration(this.referenceType.id, this.referenceToUse); diff --git a/dmp-frontend/src/app/ui/splash/splash.component.ts b/dmp-frontend/src/app/ui/splash/splash.component.ts index c37bf8a48..41d26a156 100644 --- a/dmp-frontend/src/app/ui/splash/splash.component.ts +++ b/dmp-frontend/src/app/ui/splash/splash.component.ts @@ -1,9 +1,8 @@ -import { Component, OnInit } from '@angular/core'; import { HttpClient } from '@angular/common/http'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { Component, OnInit } from '@angular/core'; import { DomSanitizer } from '@angular/platform-browser'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { BaseComponent } from '@common/base/base.component'; -import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-splash', @@ -23,22 +22,8 @@ export class SplashComponent extends BaseComponent implements OnInit { } ngOnInit() { - // this.httpClient.get(this.configurationService.splashPath, {responseType: "text"}) - // .pipe(takeUntil(this._destroyed)).subscribe(response => { - // const blob = new Blob([response], { type: 'text/html' }); - // this.readBlob(blob); - // }); - // this.splashHTML = this.sanitizer.bypassSecurityTrustHtml(`${this.configurationService.app}/${this.configurationService.splashPath}`); - } - // readBlob(blob: Blob) { - // const fr = new FileReader(); - // fr.onload = ev => { - // this.splashHTML = this.sanitizer.bypassSecurityTrustHtml(fr.result as string); - // //this.parse(); - // }; - // fr.readAsText(blob); - // } + } resizeFrame() { const frame: HTMLIFrameElement = (document.getElementById('splash') as HTMLIFrameElement); @@ -46,7 +31,6 @@ export class SplashComponent extends BaseComponent implements OnInit { } getSplashUrl() { - // return this.sanitizer.bypassSecurityTrustHtml(this.configurationService.splashPath); } } diff --git a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts index f9b2a7dd0..73b06f84b 100644 --- a/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts +++ b/dmp-frontend/src/app/ui/user-guide/user-guide-content/user-guide-content.component.ts @@ -9,7 +9,7 @@ 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'; -import { interval, Subject } from 'rxjs'; +import { Subject, interval } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; @Component({ @@ -60,16 +60,7 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit { this.readBlob(blob); } else { this.guideHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); - //GK: In case the app is in localhost (dev/debug build) apply the following transformation - // in order to show the user guide's images - // if (this.guideHTMLUrl && this.configurationService.app.includes('localhost')) { - // interval(1000).pipe(takeUntil(this._transformed)).subscribe(() => this.transform()); - // } } - - // this.guideHTML = this.sanitizer.sanitize(SecurityContext.HTML, blob); - // this.sanitizedGuideUrl = this.sanitizer.sanitize(SecurityContext.URL, this.guideHTMLUrl); - // console.log(this.guideHTMLUrl); }); } @@ -161,18 +152,6 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit { onIFrameLoad(iframe: HTMLIFrameElement) { try { - // const contentDocument = iframe.contentDocument; - // const URI = contentDocument.URL; - // const refs = contentDocument.getElementsByTagName('a'); - // const navLinks:HTMLAnchorElement[] = [];//only navigation links - // for(let i =0; ia.href = URI+a.hash); - const images = iframe.contentWindow.document.getElementsByTagName('img'); for (let i = 0; i < images.length; i++) { @@ -181,11 +160,6 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit { tempDiv.innerHTML = currentImage.outerHTML.trim(); currentImage.src = (tempDiv.firstChild as HTMLImageElement).src; } - - // const elem = tempDiv.firstChild as HTMLImageElement; - // console.log('eleme', elem); - // firstimage.src = elem.src; - } catch { console.warn('Could not find contentDocument'); } diff --git a/dmp-frontend/src/common/base/base-editor.ts b/dmp-frontend/src/common/base/base-editor.ts index 5fd0493de..7a1f9f464 100644 --- a/dmp-frontend/src/common/base/base-editor.ts +++ b/dmp-frontend/src/common/base/base-editor.ts @@ -4,27 +4,26 @@ import { Component, OnInit } from '@angular/core'; import { UntypedFormGroup } from '@angular/forms'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { LockTargetType } from '@app/core/common/enum/lock-target-type'; +import { ResponseErrorCode } from '@app/core/common/enum/respone-error-code'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; import { BaseEntity } from '@common/base/base-entity.model'; import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component'; import { FormService } from '@common/forms/form-service'; import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { FilterService } from '@common/modules/text-filter/filter-service'; import { TranslateService } from '@ngx-translate/core'; -import { interval, Observable } from 'rxjs'; +import { isNullOrUndefined } from '@swimlane/ngx-datatable'; +import { Observable, interval } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { nameof } from 'ts-simple-nameof'; import { Guid } from '../types/guid'; import { BaseEditorModel } from './base-form-editor-model'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import { QueryParamsService } from '@app/core/services/utilities/query-params.service'; -import { LockService } from '@app/core/services/lock/lock.service'; -import { LockPersist } from '@app/core/model/lock/lock.model'; -import { LockTargetType } from '@app/core/common/enum/lock-target-type'; -import { isNullOrUndefined } from '@swimlane/ngx-datatable'; -import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; -import { ResponseErrorCode } from '@app/core/common/enum/respone-error-code'; @Component({ selector: 'app-base-editor-component', @@ -73,13 +72,13 @@ export abstract class BaseEditor { - // this.formGroup = null; - // this.editorModel = null; - // }); this.refreshData(); } @@ -221,6 +207,6 @@ export abstract class BaseEditor x.localName === 'input')[0] as any).getAttribute('placeholder'); } - - // Needs to have in in html in order to fill results - // let result = ''; - // try { - // result = (Array.from(formControl.nativeElement.parentElement.children).filter((x: any) => Array.from(x.classList).includes('mat-form-field-label-wrapper'))[0] as any).innerText; - // result = result.replace(' *', ''); - // } catch (error) { } - - // return result; } } diff --git a/dmp-frontend/src/common/http/common-http.module.ts b/dmp-frontend/src/common/http/common-http.module.ts index d84f55f41..abf67a9c3 100644 --- a/dmp-frontend/src/common/http/common-http.module.ts +++ b/dmp-frontend/src/common/http/common-http.module.ts @@ -5,7 +5,6 @@ import { JsonInterceptor } from './interceptors/json.interceptor'; import { LocaleInterceptor } from './interceptors/locale.interceptor'; import { ProgressIndicationInterceptor } from './interceptors/progress-indication.interceptor'; import { RequestTimingInterceptor } from './interceptors/request-timing.interceptor'; -import { ResponsePayloadInterceptor } from './interceptors/response-payload.interceptor'; import { UnauthorizedResponseInterceptor } from './interceptors/unauthorized-response.interceptor'; import { StatusCodeInterceptor } from './interceptors/status-code.interceptor'; import { TenantHeaderInterceptor } from './interceptors/tenant-header.interceptor'; @@ -51,11 +50,6 @@ import { TenantHeaderInterceptor } from './interceptors/tenant-header.intercepto useClass: ProgressIndicationInterceptor, multi: true, }, - { - provide: HTTP_INTERCEPTORS, - useClass: ResponsePayloadInterceptor, - multi: true, - }, { provide: HTTP_INTERCEPTORS, useClass: StatusCodeInterceptor, diff --git a/dmp-frontend/src/common/http/interceptors/response-payload.interceptor.ts b/dmp-frontend/src/common/http/interceptors/response-payload.interceptor.ts deleted file mode 100644 index dab8544f8..000000000 --- a/dmp-frontend/src/common/http/interceptors/response-payload.interceptor.ts +++ /dev/null @@ -1,43 +0,0 @@ -import { HttpHandler, HttpHeaderResponse, HttpProgressEvent, HttpRequest, HttpResponse, HttpSentEvent, HttpUserEvent } from '@angular/common/http'; -import { Injectable } from '@angular/core'; -import { MatSnackBar } from '@angular/material/snack-bar'; -import { Observable } from 'rxjs'; -import { map } from 'rxjs/operators'; -import { BaseInterceptor } from './base.interceptor'; -import { InterceptorType } from './interceptor-type'; -import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; - -@Injectable() -export class ResponsePayloadInterceptor extends BaseInterceptor { - - constructor( - private snackBar: MatSnackBar, - configurationService: ConfigurationService - ) { super(configurationService); } - - get type(): InterceptorType { return InterceptorType.ResponsePayload; } - - interceptRequest(req: HttpRequest, next: HttpHandler): Observable | HttpUserEvent> { - - return next.handle(req).pipe( - map(response => { - // if (!(response instanceof HttpResponse) || (response instanceof Blob)) { return response; } - // if (response.status == 200) { - // if (response.body.statusCode === ApiMessageCode.SUCCESS_MESSAGE) { - // //throw new Error('Request failed'); - // // this.snackBar.openFromComponent(SnackBarNotificationComponent, { - // // data: { message: response['message'], language: null }, - // // duration: 3000, - // // }); - // return response.body.payload; - - // } else if (response.body.statusCode === ApiMessageCode.NO_MESSAGE) { - // return response.body.payload; - // } else { - // return response.body.payload; - // } - // } - return response; - })); - } -} diff --git a/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.ts b/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.ts index 18c8e0558..a603bc320 100644 --- a/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.ts +++ b/dmp-frontend/src/common/modules/user-settings/user-settings-picker/user-settings-picker.component.ts @@ -111,24 +111,7 @@ export class UserSettingsPickerComponent extends BaseComponent implements OnInit } renameCurrentUserSetting(): void { - // this.dialog.open( - // FilterNameDialogComponent, - // { - // maxWidth: '600px', - // maxHeight: '400px', - // restoreFocus: false, - // data: { name: this.currentUserSetting.name}, - // disableClose: false - // } - // ).afterClosed() - // .pipe( - // filter(x => !!x), - // takeUntil(this._destroyed) - // ) - // .subscribe(newName => { - // this.currentUserSetting.name = newName; - // this.persistLookupChangesManually(this.currentUserSetting, true); - // }) + } settingDeleted(value: Guid = this.currentUserSetting.id) { @@ -149,21 +132,10 @@ export class UserSettingsPickerComponent extends BaseComponent implements OnInit } }); } - /* this.userSettingsService.remove(this.currentUserSetting.id, this.key); */ } saveFilter() { - // const saveDialogRef = this.dialog.open(FilterNameDialogComponent, { - // maxWidth: '600px', - // maxHeight: '400px', - // restoreFocus: false, - // data: { name: this.currentUserSetting ? this.currentUserSetting.name : '' }, - // disableClose: false - // }); - - // saveDialogRef.afterClosed().subscribe(result => { - // if (result) { this.createNewFilter(result); } - // }); + //TODO: implement } diff --git a/dmp-frontend/src/common/modules/user-settings/user-settings-selector/user-settings-selector.component.ts b/dmp-frontend/src/common/modules/user-settings/user-settings-selector/user-settings-selector.component.ts index f12c2ce49..0da636a4c 100644 --- a/dmp-frontend/src/common/modules/user-settings/user-settings-selector/user-settings-selector.component.ts +++ b/dmp-frontend/src/common/modules/user-settings/user-settings-selector/user-settings-selector.component.ts @@ -1,12 +1,12 @@ import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; +import { UserSetting, UserSettingsService } from '@app/core/services/user-settings/user-settings.service'; import { BaseComponent } from '@common/base/base.component'; import { Lookup } from '@common/model/lookup'; -import { takeUntil, filter } from 'rxjs/operators'; -import { TranslateService } from '@ngx-translate/core'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; import { isNullOrUndefined } from '@swimlane/ngx-datatable'; -import { UserSetting, UserSettingsService } from '@app/core/services/user-settings/user-settings.service'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-user-settings-selector', @@ -87,7 +87,6 @@ export class UserSettingsSelectorComponent extends BaseComponent implements OnIn if (setting === null) { return; } //Persist the active user setting - //this.onSettingSelected.emit(setting.value); this.userSettingsService.set(setting, true, this.key); } @@ -109,21 +108,10 @@ export class UserSettingsSelectorComponent extends BaseComponent implements OnIn } }); } - /* this.userSettingsService.remove(this.currentUserSetting.id, this.key); */ } saveFilter() { - // const saveDialogRef = this.dialog.open(FilterNameDialogComponent, { - // maxWidth: '600px', - // maxHeight: '400px', - // restoreFocus: false, - // data: { name: this.currentUserSetting ? this.currentUserSetting.name : '' }, - // disableClose: false - // }); - - // saveDialogRef.afterClosed().subscribe(result => { - // if (result) { this.createNewFilter(result); } - // }); + //TODO: implement } updateFilter() { @@ -147,7 +135,7 @@ export class UserSettingsSelectorComponent extends BaseComponent implements OnIn setting.updatedAt = null; setting.userId = null; this.currentUserSetting = setting; - + this.persistLookupChangesManually(this.currentUserSetting, true); } diff --git a/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts b/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts index 05fc7f02b..ff0af6114 100644 --- a/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts +++ b/dmp-frontend/src/notification-service/ui/inapp-notification/editor/inapp-notification-editor.component.ts @@ -1,23 +1,22 @@ -import { HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { LoggingService } from '@app/core/services/logging/logging-service'; +import { UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; import { FormService } from '@common/forms/form-service'; -import { LoggingService } from '@app/core/services/logging/logging-service'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; -import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; +import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service'; import { Guid } from '@common/types/guid'; import { TranslateService } from '@ngx-translate/core'; -import { IsActive } from '@app/core/common/enum/is-active.enum'; -import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; -import { map, takeUntil } from 'rxjs/operators'; -import { nameof } from 'ts-simple-nameof'; -import { AuthService } from '@app/core/services/auth/auth.service'; -import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service'; -import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { NotificationInAppTracking } from '@notification-service/core/enum/notification-inapp-tracking.enum'; import { InAppNotification } from '@notification-service/core/model/inapp-notification.model'; +import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service'; +import { map, takeUntil } from 'rxjs/operators'; +import { nameof } from 'ts-simple-nameof'; @Component({ selector: 'app-inapp-notification-editor', @@ -72,7 +71,7 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O this.isDeleted = this.inappNotification.isActive === IsActive.Inactive; this.isRead = this.inappNotification.trackingState === NotificationInAppTracking.Delivered; - if(!this.isDeleted && !this.isRead) this.markAsRead() + if (!this.isDeleted && !this.isRead) this.markAsRead() }, error => this.httpErrorHandlingService.handleBackedRequestError(error) ); @@ -89,7 +88,6 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O complete => this.onCallbackSuccess(), error => this.httpErrorHandlingService.handleBackedRequestError(error) ); - // this.clearErrorModel(); } public delete() { diff --git a/dmp-frontend/src/notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.module.ts b/dmp-frontend/src/notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.module.ts index 6c09110b9..db13db0af 100644 --- a/dmp-frontend/src/notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.module.ts +++ b/dmp-frontend/src/notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.module.ts @@ -2,8 +2,6 @@ import { DragDropModule } from '@angular/cdk/drag-drop'; import { NgModule } from '@angular/core'; import { CommonFormsModule } from '@common/forms/common-forms.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; -import { CoreNotificationServiceModule } from '@notification-service/services/core-service.module'; -// import { TotpModule } from '@idp-service/ui/totp/totp.module'; import { UserProfileNotifierListEditorComponent } from '@notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.component'; @NgModule({ diff --git a/dmp-frontend/src/styles.scss b/dmp-frontend/src/styles.scss index 5ca3a7ea0..e17cfa1ee 100644 --- a/dmp-frontend/src/styles.scss +++ b/dmp-frontend/src/styles.scss @@ -149,21 +149,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim filter: alpha(opacity=20); } -// Custom Theme -// @import "./assets/scss/blue-theme.scss"; - -// Define a theme. -// $primary: mat-palette($app-blue-theme-primary-palette); -// $accent: mat-palette($mat-pink, A200, A100, A400); -// $theme: mat-light-theme($primary, $accent); - -// Include all theme styles for the components. -// @include angular-material-theme($theme); -// @include covalent-theme($theme); - - - - .cc-btn { background-color: var(--primary-color-3) !important; } @@ -186,7 +171,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim .lightblue-btn { background-color: var(--primary-color) !important; color: white !important; - // background-color: rgba(0, 112, 192, 1) !important; } .listing-item { @@ -211,7 +195,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim padding: 0.1em 1em; border-radius: 10em; background-color: #0d7489; - // background-color: rgba(0, 112, 192, 1); color: #fff; text-transform: uppercase; font-weight: 500; @@ -227,8 +210,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim border-radius: 10em; background-color: rgb(236, 241, 249); color: var(--primary-color); - // color: rgba(0, 112, 192, 1); - // color: rgb(68, 114, 196); text-transform: uppercase; font-weight: 500; max-width: 160px; @@ -274,21 +255,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim margin-bottom: 0px; } - // .draft-bookmark { - // color: #e7e6e6; - // display: inline; - // position: absolute; - // padding-top: 3px; - // } - - // .finalized-bookmark { - // color: #08bd63; - // // color: #92d050; - // display: inline; - // position: absolute; - // padding-top: 3px; - // } - h4 span { color: #089dbb; font-weight: 600; @@ -387,43 +353,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim margin-top: 8px; } -//.angular-editor-textarea { -// min-height: 150px !important; -//} -// -//.editor-wrapper { -// border: 1px solid transparent !important; -// border-radius: 5px; -//} -// -//.angular-editor-toolbar { -// margin-left: 1px; -// margin-right: 1px; -//} -// -//.angular-editor-textarea, .angular-editor-toolbar { -// border: none !important; -//} -// -//.angular-editor { -// border: 1px solid #ddd !important; -// border-radius: 5px; -// background-color: #fff; -//} -// -//.editor-wrapper:hover, .angular-editor:hover { -// border: 1px solid #000 !important; -//} -// -//.editor-wrapper:focus-within, .angular-editor:focus-within { -// border: 1px solid #034459 !important; -//} -// -//.required.editor-wrapper, .required .editor .angular-editor { -// border: 1px solid #f44336 !important; -//} -// end of CSS for (@kolkov/angular-editor) - /* Transition Group */ .list-move { transition: transform 1s;