Merge branch 'dmp-refactoring' of code-repo.d4science.org:MaDgiK-CITE/argos into dmp-refactoring
This commit is contained in:
commit
626161bb3f
|
@ -25,6 +25,7 @@ queue:
|
||||||
enable: false
|
enable: false
|
||||||
options:
|
options:
|
||||||
exchange: null
|
exchange: null
|
||||||
|
annotation-created-topic: annotation.created
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
enable: false
|
enable: false
|
||||||
interval-seconds: 3
|
interval-seconds: 3
|
||||||
|
|
|
@ -2,41 +2,56 @@ package gr.cite.annotation.common;
|
||||||
|
|
||||||
import com.fasterxml.jackson.core.JsonProcessingException;
|
import com.fasterxml.jackson.core.JsonProcessingException;
|
||||||
import com.fasterxml.jackson.databind.ObjectMapper;
|
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 gr.cite.tools.logging.LoggerService;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
|
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
|
||||||
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
|
@Scope(ConfigurableBeanFactory.SCOPE_SINGLETON)
|
||||||
public class JsonHandlingService {
|
public class JsonHandlingService {
|
||||||
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(JsonHandlingService.class));
|
private final ObjectMapper objectMapper;
|
||||||
private final ObjectMapper objectMapper = new ObjectMapper();
|
|
||||||
|
public JsonHandlingService() {
|
||||||
|
this.objectMapper = new ObjectMapper();
|
||||||
|
this.objectMapper.registerModule(new JavaTimeModule());
|
||||||
|
}
|
||||||
|
|
||||||
public String toJson(Object item) throws JsonProcessingException {
|
public String toJson(Object item) throws JsonProcessingException {
|
||||||
if (item == null) return null;
|
if (item == null) return null;
|
||||||
return objectMapper.writeValueAsString(item);
|
return this.objectMapper.writeValueAsString(item);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String toJsonSafe(Object item) {
|
public String toJsonSafe(Object item) {
|
||||||
if (item == null) return null;
|
if (item == null) return null;
|
||||||
try {
|
try {
|
||||||
return objectMapper.writeValueAsString(item);
|
return this.objectMapper.writeValueAsString(item);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T fromJson(Class<T> type, String json) throws JsonProcessingException {
|
public <T> T fromJson(Class<T> type, String json) throws JsonProcessingException {
|
||||||
if (json == null) return null;
|
if (json == null) return null;
|
||||||
return objectMapper.readValue(json, type);
|
return this.objectMapper.readValue(json, type);
|
||||||
|
}
|
||||||
|
|
||||||
|
public HashMap<String, String> mapFromJson(String json) throws JsonProcessingException {
|
||||||
|
ObjectReader reader = this.objectMapper.readerFor(Map.class);
|
||||||
|
return reader.readValue(json);
|
||||||
}
|
}
|
||||||
|
|
||||||
public <T> T fromJsonSafe(Class<T> type, String json) {
|
public <T> T fromJsonSafe(Class<T> type, String json) {
|
||||||
if (json == null) return null;
|
if (json == null) return null;
|
||||||
try {
|
try {
|
||||||
return objectMapper.readValue(json, type);
|
return this.objectMapper.readValue(json, type);
|
||||||
} catch (Exception ex) {
|
} catch (Exception ex) {
|
||||||
logger.error("Json Parsing Error: " + ex.getLocalizedMessage(), ex);
|
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,9 +26,11 @@ import java.util.UUID;
|
||||||
@ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false)
|
@ConditionalOnProperty(prefix = "queue.task.publisher", name = "enable", matchIfMissing = false)
|
||||||
public class OutboxIntegrationEventConfigurer extends OutboxConfigurer {
|
public class OutboxIntegrationEventConfigurer extends OutboxConfigurer {
|
||||||
private final ApplicationContext applicationContext;
|
private final ApplicationContext applicationContext;
|
||||||
|
private final OutboxProperties outboxProperties;
|
||||||
|
|
||||||
public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext) {
|
public OutboxIntegrationEventConfigurer(ApplicationContext applicationContext, OutboxProperties outboxProperties) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
|
this.outboxProperties = outboxProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
|
@ -64,7 +66,7 @@ public class OutboxIntegrationEventConfigurer extends OutboxConfigurer {
|
||||||
|
|
||||||
@Bean
|
@Bean
|
||||||
public OutboxRepository outboxRepositoryCreator() {
|
public OutboxRepository outboxRepositoryCreator() {
|
||||||
return new OutboxRepositoryImpl(this.applicationContext);
|
return new OutboxRepositoryImpl(this.applicationContext, this.outboxProperties);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,8 @@ import gr.cite.rabbitmq.IntegrationEvent;
|
||||||
|
|
||||||
@JsonIgnoreProperties(ignoreUnknown = true)
|
@JsonIgnoreProperties(ignoreUnknown = true)
|
||||||
public class OutboxIntegrationEvent extends IntegrationEvent {
|
public class OutboxIntegrationEvent extends IntegrationEvent {
|
||||||
|
|
||||||
|
public static final String ANNOTATION_CREATED = "ANNOTATION_CREATED";
|
||||||
private TrackedEvent event;
|
private TrackedEvent event;
|
||||||
|
|
||||||
public TrackedEvent getEvent() {
|
public TrackedEvent getEvent() {
|
||||||
|
|
|
@ -7,13 +7,20 @@ public class OutboxProperties {
|
||||||
|
|
||||||
private final String exchange;
|
private final String exchange;
|
||||||
|
|
||||||
|
private final String annotationCreatedTopic;
|
||||||
|
|
||||||
public OutboxProperties(String exchange
|
|
||||||
) {
|
public OutboxProperties(String exchange,
|
||||||
|
String annotationCreatedTopic) {
|
||||||
this.exchange = exchange;
|
this.exchange = exchange;
|
||||||
|
this.annotationCreatedTopic = annotationCreatedTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExchange() {
|
public String getExchange() {
|
||||||
return exchange;
|
return exchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public String getAnnotationCreatedTopic() {
|
||||||
|
return annotationCreatedTopic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,12 +33,16 @@ public class OutboxRepositoryImpl implements OutboxRepository {
|
||||||
|
|
||||||
@PersistenceUnit
|
@PersistenceUnit
|
||||||
private EntityManagerFactory entityManagerFactory;
|
private EntityManagerFactory entityManagerFactory;
|
||||||
|
private final JsonHandlingService jsonHandlingService;
|
||||||
|
private final OutboxProperties outboxProperties;
|
||||||
|
|
||||||
|
|
||||||
public OutboxRepositoryImpl(
|
public OutboxRepositoryImpl(
|
||||||
ApplicationContext applicationContext
|
ApplicationContext applicationContext,
|
||||||
) {
|
OutboxProperties outboxProperties) {
|
||||||
this.applicationContext = applicationContext;
|
this.applicationContext = applicationContext;
|
||||||
|
this.jsonHandlingService = this.applicationContext.getBean(JsonHandlingService.class);
|
||||||
|
this.outboxProperties = outboxProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -370,10 +374,35 @@ public class OutboxRepositoryImpl implements OutboxRepository {
|
||||||
private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) {
|
private QueueOutboxEntity mapEvent(OutboxIntegrationEvent event) {
|
||||||
String routingKey;
|
String routingKey;
|
||||||
switch (event.getType()) {
|
switch (event.getType()) {
|
||||||
|
case OutboxIntegrationEvent.ANNOTATION_CREATED: {
|
||||||
|
routingKey = this.outboxProperties.getAnnotationCreatedTopic();
|
||||||
|
break;
|
||||||
|
}
|
||||||
default: {
|
default: {
|
||||||
logger.error("unrecognized outgoing integration event {}. Skipping...", event.getType());
|
logger.error("unrecognized outgoing integration event {}. Skipping...", event.getType());
|
||||||
return null;
|
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;
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,7 @@
|
||||||
|
package gr.cite.annotation.integrationevent.outbox.annotationcreated;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
|
||||||
|
public interface AnnotationCreatedIntegrationEventHandler {
|
||||||
|
void handle(AnnotationCreatedEvent event) throws InvalidApplicationException;
|
||||||
|
}
|
|
@ -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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -13,7 +13,7 @@ import java.util.UUID;
|
||||||
|
|
||||||
public interface AnnotationService {
|
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;
|
void deleteAndSave(UUID id) throws InvalidApplicationException;
|
||||||
|
|
||||||
|
|
|
@ -8,6 +8,8 @@ import gr.cite.annotation.common.enums.IsActive;
|
||||||
import gr.cite.annotation.common.scope.user.UserScope;
|
import gr.cite.annotation.common.scope.user.UserScope;
|
||||||
import gr.cite.annotation.data.AnnotationEntity;
|
import gr.cite.annotation.data.AnnotationEntity;
|
||||||
import gr.cite.annotation.data.TenantEntityManager;
|
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.Annotation;
|
||||||
import gr.cite.annotation.model.builder.AnnotationBuilder;
|
import gr.cite.annotation.model.builder.AnnotationBuilder;
|
||||||
import gr.cite.annotation.model.deleter.AnnotationDeleter;
|
import gr.cite.annotation.model.deleter.AnnotationDeleter;
|
||||||
|
@ -30,9 +32,7 @@ import org.springframework.stereotype.Service;
|
||||||
|
|
||||||
import javax.management.InvalidApplicationException;
|
import javax.management.InvalidApplicationException;
|
||||||
import java.time.Instant;
|
import java.time.Instant;
|
||||||
import java.util.EnumSet;
|
import java.util.*;
|
||||||
import java.util.List;
|
|
||||||
import java.util.UUID;
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
public class AnnotationServiceImpl implements AnnotationService {
|
public class AnnotationServiceImpl implements AnnotationService {
|
||||||
|
@ -52,12 +52,14 @@ public class AnnotationServiceImpl implements AnnotationService {
|
||||||
|
|
||||||
private final MessageSource messageSource;
|
private final MessageSource messageSource;
|
||||||
|
|
||||||
|
private final AnnotationCreatedIntegrationEventHandler annotationCreatedEventHandler;
|
||||||
|
|
||||||
|
|
||||||
public AnnotationServiceImpl(
|
public AnnotationServiceImpl(
|
||||||
AuthorizationService authorizationService,
|
AuthorizationService authorizationService,
|
||||||
DeleterFactory deleterFactory,
|
DeleterFactory deleterFactory,
|
||||||
TenantEntityManager entityManager,
|
TenantEntityManager entityManager,
|
||||||
BuilderFactory builderFactory, UserScope userScope, AuthorizationContentResolver authorizationContentResolver, MessageSource messageSource) {
|
BuilderFactory builderFactory, UserScope userScope, AuthorizationContentResolver authorizationContentResolver, MessageSource messageSource, AnnotationCreatedIntegrationEventHandler annotationCreatedEventHandler) {
|
||||||
this.authorizationService = authorizationService;
|
this.authorizationService = authorizationService;
|
||||||
this.deleterFactory = deleterFactory;
|
this.deleterFactory = deleterFactory;
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
|
@ -65,10 +67,11 @@ public class AnnotationServiceImpl implements AnnotationService {
|
||||||
this.userScope = userScope;
|
this.userScope = userScope;
|
||||||
this.authorizationContentResolver = authorizationContentResolver;
|
this.authorizationContentResolver = authorizationContentResolver;
|
||||||
this.messageSource = messageSource;
|
this.messageSource = messageSource;
|
||||||
|
this.annotationCreatedEventHandler = annotationCreatedEventHandler;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@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));
|
logger.debug(new MapLogEntry("persisting annotation").And("model", model).And("fields", fields));
|
||||||
|
|
||||||
this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.entityAffiliation(model.getEntityId())), Permission.NewAnnotation);
|
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.entityManager.flush();
|
||||||
|
|
||||||
|
this.sendAnnotationCreatedEvent(data);
|
||||||
|
|
||||||
return this.builderFactory.builder(AnnotationBuilder.class).authorize(EnumSet.of(AuthorizationFlags.None)).build(BaseFieldSet.build(fields, Annotation._id), 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
|
@Override
|
||||||
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException {
|
||||||
logger.debug("deleting Annotation: {}", id);
|
logger.debug("deleting Annotation: {}", id);
|
||||||
|
|
|
@ -173,6 +173,8 @@ public class AuditableAction {
|
||||||
public static final EventId TenantConfiguration_Persist = new EventId(270002, "TenantConfiguration_Persist");
|
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_Delete = new EventId(270003, "TenantConfiguration_Delete");
|
||||||
public static final EventId TenantConfiguration_LookupByType = new EventId(270004, "TenantConfiguration_LookupByType");
|
public static final EventId TenantConfiguration_LookupByType = new EventId(270004, "TenantConfiguration_LookupByType");
|
||||||
|
|
||||||
|
public static final EventId Annotation_Created_Notify = new EventId(280000, "Annotation_Created_Notify");
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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<Short> {
|
||||||
|
|
||||||
|
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<Short, AnnotationProtectionType> map = EnumUtils.getEnumValueMap(AnnotationProtectionType.class);
|
||||||
|
|
||||||
|
public static AnnotationProtectionType of(Short i) {
|
||||||
|
return map.get(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -13,6 +13,7 @@ public class NotificationProperties {
|
||||||
private UUID dmpFinalisedType;
|
private UUID dmpFinalisedType;
|
||||||
private UUID descriptionModifiedType;
|
private UUID descriptionModifiedType;
|
||||||
private UUID descriptionFinalisedType;
|
private UUID descriptionFinalisedType;
|
||||||
|
private UUID descriptionAnnotationCreated;
|
||||||
private UUID mergeAccountConfirmationType;
|
private UUID mergeAccountConfirmationType;
|
||||||
private UUID removeCredentialConfirmationType;
|
private UUID removeCredentialConfirmationType;
|
||||||
private UUID dmpDepositType;
|
private UUID dmpDepositType;
|
||||||
|
@ -133,4 +134,12 @@ public class NotificationProperties {
|
||||||
public void setContactSupportEmail(String contactSupportEmail) {
|
public void setContactSupportEmail(String contactSupportEmail) {
|
||||||
this.contactSupportEmail = contactSupportEmail;
|
this.contactSupportEmail = contactSupportEmail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public UUID getDescriptionAnnotationCreated() {
|
||||||
|
return descriptionAnnotationCreated;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setDescriptionAnnotationCreated(UUID descriptionAnnotationCreated) {
|
||||||
|
this.descriptionAnnotationCreated = descriptionAnnotationCreated;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,6 +9,7 @@ import gr.cite.rabbitmq.consumer.InboxCreator;
|
||||||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
|
||||||
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
import org.springframework.boot.context.properties.EnableConfigurationProperties;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
import org.springframework.context.annotation.Bean;
|
||||||
import org.springframework.context.annotation.Configuration;
|
import org.springframework.context.annotation.Configuration;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
@ -19,21 +20,23 @@ import java.util.List;
|
||||||
@ConditionalOnProperty(prefix = "queue.rabbitmq", name = "listenerEnabled")
|
@ConditionalOnProperty(prefix = "queue.rabbitmq", name = "listenerEnabled")
|
||||||
public class AppRabbitConfigurer extends RabbitConfigurer {
|
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.applicationContext = applicationContext;
|
||||||
|
this.inboxProperties = inboxProperties;
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Bean
|
@Bean
|
||||||
public InboxBindings inboxBindingsCreator() {
|
public InboxBindings inboxBindingsCreator() {
|
||||||
List<String> bindingItems = new ArrayList<>();
|
List<String> bindingItems = new ArrayList<>();
|
||||||
|
bindingItems.addAll(this.inboxProperties.getAnnotationCreatedTopic());
|
||||||
return new InboxBindings(bindingItems);
|
return new InboxBindings(bindingItems);
|
||||||
}
|
}
|
||||||
|
|
||||||
// @Bean
|
@Bean(name = "InboxCreator")
|
||||||
public InboxCreator inboxCreator() {
|
public InboxCreator inboxCreator() {
|
||||||
return (params) -> {
|
return (params) -> {
|
||||||
InboxRepository inboxRepository = this.applicationContext.getBean(InboxRepository.class);
|
InboxRepository inboxRepository = this.applicationContext.getBean(InboxRepository.class);
|
||||||
|
|
|
@ -4,6 +4,8 @@ import jakarta.validation.constraints.NotNull;
|
||||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||||
import org.springframework.validation.annotation.Validated;
|
import org.springframework.validation.annotation.Validated;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
@Validated
|
@Validated
|
||||||
@ConfigurationProperties(prefix = "queue.task.listener.options")
|
@ConfigurationProperties(prefix = "queue.task.listener.options")
|
||||||
//@ConstructorBinding
|
//@ConstructorBinding
|
||||||
|
@ -12,14 +14,19 @@ public class InboxProperties {
|
||||||
@NotNull
|
@NotNull
|
||||||
private final String exchange;
|
private final String exchange;
|
||||||
|
|
||||||
|
private final List<String> annotationCreatedTopic;
|
||||||
|
|
||||||
public InboxProperties(
|
public InboxProperties(
|
||||||
String exchange
|
String exchange, List<String> annotationCreatedTopic) {
|
||||||
) {
|
|
||||||
this.exchange = exchange;
|
this.exchange = exchange;
|
||||||
|
this.annotationCreatedTopic = annotationCreatedTopic;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getExchange() {
|
public String getExchange() {
|
||||||
return exchange;
|
return exchange;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public List<String> getAnnotationCreatedTopic() {
|
||||||
|
return annotationCreatedTopic;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@ import org.opencdmp.commons.enums.IsActive;
|
||||||
import org.opencdmp.commons.fake.FakeRequestScope;
|
import org.opencdmp.commons.fake.FakeRequestScope;
|
||||||
import org.opencdmp.data.QueueInboxEntity;
|
import org.opencdmp.data.QueueInboxEntity;
|
||||||
import org.opencdmp.data.TenantEntityManager;
|
import org.opencdmp.data.TenantEntityManager;
|
||||||
|
import org.opencdmp.integrationevent.inbox.annotationentitycreated.AnnotationEntityCreatedIntegrationEventHandler;
|
||||||
import org.opencdmp.query.QueueInboxQuery;
|
import org.opencdmp.query.QueueInboxQuery;
|
||||||
import org.slf4j.LoggerFactory;
|
import org.slf4j.LoggerFactory;
|
||||||
import org.springframework.context.ApplicationContext;
|
import org.springframework.context.ApplicationContext;
|
||||||
|
@ -359,12 +360,12 @@ public class InboxRepositoryImpl implements InboxRepository {
|
||||||
private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) {
|
private EventProcessingStatus processMessage(QueueInboxEntity queueInboxMessage) {
|
||||||
IntegrationEventHandler handler = null;
|
IntegrationEventHandler handler = null;
|
||||||
logger.debug("Processing message with routing key '{}'", queueInboxMessage.getRoute());
|
logger.debug("Processing message with routing key '{}'", queueInboxMessage.getRoute());
|
||||||
// if (this.routingKeyMatched(queueInboxMessage.getRoute(), this.inboxProperties.getTenantRemovalTopic()))
|
if (this.routingKeyMatched(queueInboxMessage.getRoute(), this.inboxProperties.getAnnotationCreatedTopic()))
|
||||||
// handler = this.applicationContext.getBean(TenantRemovalIntegrationEventHandler.class);
|
handler = this.applicationContext.getBean(AnnotationEntityCreatedIntegrationEventHandler.class);
|
||||||
// else {
|
else {
|
||||||
// logger.error("No handler found for message routing key '{}'. Discarding.", queueInboxMessage.getRoute());
|
logger.error("No handler found for message routing key '{}'. Discarding.", queueInboxMessage.getRoute());
|
||||||
// handler = null;
|
handler = null;
|
||||||
// }
|
}
|
||||||
|
|
||||||
if (handler == null)
|
if (handler == null)
|
||||||
return EventProcessingStatus.Discard;
|
return EventProcessingStatus.Discard;
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
package org.opencdmp.integrationevent.inbox;
|
package org.opencdmp.integrationevent.inbox;
|
||||||
|
|
||||||
|
import javax.management.InvalidApplicationException;
|
||||||
|
|
||||||
public interface IntegrationEventHandler {
|
public interface IntegrationEventHandler {
|
||||||
|
|
||||||
EventProcessingStatus handle(IntegrationEventProperties properties, String message);
|
EventProcessingStatus handle(IntegrationEventProperties properties, String message) throws InvalidApplicationException;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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<AnnotationEntityCreatedIntegrationEvent> {
|
||||||
|
|
||||||
|
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<AnnotationEntityCreatedIntegrationEvent> modelClass() {
|
||||||
|
return AnnotationEntityCreatedIntegrationEvent.class;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected List<Specification> 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()))
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 {
|
||||||
|
}
|
|
@ -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<String, Object>("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<DmpUserEntity> 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<FieldInfo> 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);
|
||||||
|
}
|
||||||
|
}
|
|
@ -345,15 +345,7 @@ public class DepositServiceImpl implements DepositService {
|
||||||
private void createDmpDepositNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException {
|
private void createDmpDepositNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException {
|
||||||
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
||||||
event.setUserId(user.getId());
|
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<ContactPair> 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());
|
event.setNotificationType(this.notificationProperties.getDmpDepositType());
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
||||||
|
|
|
@ -388,16 +388,6 @@ public class DescriptionServiceImpl implements DescriptionService {
|
||||||
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
||||||
event.setUserId(user.getId());
|
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<ContactPair> 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);
|
this.applyNotificationType(description.getStatus(), event);
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
||||||
|
|
|
@ -278,14 +278,6 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic
|
||||||
if (user.getIsActive().equals(IsActive.Inactive)) throw new MyValidationException(this.errors.getDescriptionTemplateInactiveUser().getCode(), this.errors.getDescriptionTemplateInactiveUser().getMessage());
|
if (user.getIsActive().equals(IsActive.Inactive)) throw new MyValidationException(this.errors.getDescriptionTemplateInactiveUser().getCode(), this.errors.getDescriptionTemplateInactiveUser().getMessage());
|
||||||
|
|
||||||
event.setUserId(user.getId());
|
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<ContactPair> 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());
|
event.setNotificationType(this.notificationProperties.getDescriptionTemplateInvitationType());
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
||||||
|
|
|
@ -69,7 +69,6 @@ import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEvent;
|
||||||
import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler;
|
import org.opencdmp.integrationevent.outbox.notification.NotifyIntegrationEventHandler;
|
||||||
import org.opencdmp.model.DmpUser;
|
import org.opencdmp.model.DmpUser;
|
||||||
import org.opencdmp.model.DmpValidationResult;
|
import org.opencdmp.model.DmpValidationResult;
|
||||||
import org.opencdmp.model.UserContactInfo;
|
|
||||||
import org.opencdmp.model.builder.DmpUserBuilder;
|
import org.opencdmp.model.builder.DmpUserBuilder;
|
||||||
import org.opencdmp.model.builder.description.DescriptionBuilder;
|
import org.opencdmp.model.builder.description.DescriptionBuilder;
|
||||||
import org.opencdmp.model.builder.dmp.DmpBuilder;
|
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 {
|
private void createDmpNotificationEvent(DmpEntity dmp, UserEntity user) throws InvalidApplicationException {
|
||||||
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
||||||
event.setUserId(user.getId());
|
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<ContactPair> 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);
|
this.applyNotificationType(dmp.getStatus(), event);
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
|
@ -1493,10 +1483,6 @@ public class DmpServiceImpl implements DmpService {
|
||||||
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
||||||
event.setUserId(recipient.getId());
|
event.setUserId(recipient.getId());
|
||||||
|
|
||||||
List<ContactPair> 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());
|
event.setNotificationType(this.notificationProperties.getDmpInvitationExistingUserType());
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
||||||
|
|
|
@ -525,11 +525,7 @@ public class UserServiceImpl implements UserService {
|
||||||
|
|
||||||
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
NotifyIntegrationEvent event = new NotifyIntegrationEvent();
|
||||||
event.setUserId(user.getId());
|
event.setUserId(user.getId());
|
||||||
List<ContactPair> 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());
|
event.setNotificationType(this.notificationProperties.getMergeAccountConfirmationType());
|
||||||
NotificationFieldData data = new NotificationFieldData();
|
NotificationFieldData data = new NotificationFieldData();
|
||||||
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
List<FieldInfo> fieldInfoList = new ArrayList<>();
|
||||||
|
|
|
@ -63,8 +63,10 @@ public class PrincipalController {
|
||||||
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._language),
|
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._language),
|
||||||
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._culture),
|
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._culture),
|
||||||
BaseFieldSet.asIndexer(Account._profile, Account.UserProfileInfo._timezone),
|
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();
|
MyPrincipal principal = this.currentPrincipalResolver.currentPrincipal();
|
||||||
|
|
|
@ -301,9 +301,7 @@ public class UserController {
|
||||||
public Boolean getUserTokenPermission(@PathVariable("token") String token) throws InvalidApplicationException, IOException {
|
public Boolean getUserTokenPermission(@PathVariable("token") String token) throws InvalidApplicationException, IOException {
|
||||||
logger.debug(new MapLogEntry("allow merge account to user").And("token", token));
|
logger.debug(new MapLogEntry("allow merge account to user").And("token", token));
|
||||||
|
|
||||||
this.auditService.track(AuditableAction.User_AllowMergeAccount, Map.ofEntries(
|
this.auditService.track(AuditableAction.User_AllowMergeAccount);
|
||||||
new AbstractMap.SimpleEntry<String, Object>("token", token)
|
|
||||||
));
|
|
||||||
|
|
||||||
return this.userTypeService.doesTokenBelongToLoggedInUser(token);
|
return this.userTypeService.doesTokenBelongToLoggedInUser(token);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
package org.opencdmp.models;
|
package org.opencdmp.models;
|
||||||
|
|
||||||
import gr.cite.tools.logging.annotation.LogSensitive;
|
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.time.Instant;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
@ -187,6 +189,9 @@ public class Account {
|
||||||
public final static String _permissions = "permissions";
|
public final static String _permissions = "permissions";
|
||||||
private List<String> permissions;
|
private List<String> permissions;
|
||||||
|
|
||||||
|
public final static String _selectedTenant = "selectedTenant";
|
||||||
|
public Tenant selectedTenant;
|
||||||
|
|
||||||
public PrincipalInfo getPrincipal() {
|
public PrincipalInfo getPrincipal() {
|
||||||
return principal;
|
return principal;
|
||||||
}
|
}
|
||||||
|
@ -195,22 +200,10 @@ public class Account {
|
||||||
this.principal = principal;
|
this.principal = principal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public final static String _roles = "roles";
|
|
||||||
private List<String> roles;
|
|
||||||
|
|
||||||
public Boolean getAuthenticated() {
|
public Boolean getAuthenticated() {
|
||||||
return isAuthenticated;
|
return isAuthenticated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<String> getRoles() {
|
|
||||||
return roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setRoles(List<String> roles) {
|
|
||||||
this.roles = roles;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void setAuthenticated(Boolean authenticated) {
|
public void setAuthenticated(Boolean authenticated) {
|
||||||
isAuthenticated = authenticated;
|
isAuthenticated = authenticated;
|
||||||
}
|
}
|
||||||
|
@ -230,4 +223,12 @@ public class Account {
|
||||||
public void setProfile(UserProfileInfo profile) {
|
public void setProfile(UserProfileInfo profile) {
|
||||||
this.profile = profile;
|
this.profile = profile;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Tenant getSelectedTenant() {
|
||||||
|
return selectedTenant;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setSelectedTenant(Tenant selectedTenant) {
|
||||||
|
this.selectedTenant = selectedTenant;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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.MyPrincipal;
|
||||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractor;
|
||||||
import gr.cite.commons.web.oidc.principal.extractor.ClaimExtractorKeys;
|
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.BaseFieldSet;
|
||||||
import gr.cite.tools.fieldset.FieldSet;
|
import gr.cite.tools.fieldset.FieldSet;
|
||||||
import org.opencdmp.commons.JsonHandlingService;
|
import org.opencdmp.commons.JsonHandlingService;
|
||||||
|
import org.opencdmp.commons.scope.tenant.TenantScope;
|
||||||
import org.opencdmp.commons.scope.user.UserScope;
|
import org.opencdmp.commons.scope.user.UserScope;
|
||||||
import org.opencdmp.commons.types.user.AdditionalInfoEntity;
|
import org.opencdmp.commons.types.user.AdditionalInfoEntity;
|
||||||
|
import org.opencdmp.data.DmpEntity;
|
||||||
import org.opencdmp.data.TenantEntityManager;
|
import org.opencdmp.data.TenantEntityManager;
|
||||||
import org.opencdmp.data.UserEntity;
|
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.beans.factory.config.ConfigurableBeanFactory;
|
||||||
import org.springframework.context.annotation.Scope;
|
import org.springframework.context.annotation.Scope;
|
||||||
import org.springframework.stereotype.Component;
|
import org.springframework.stereotype.Component;
|
||||||
|
|
||||||
import javax.management.InvalidApplicationException;
|
import javax.management.InvalidApplicationException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
@Component
|
@Component
|
||||||
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
@Scope(ConfigurableBeanFactory.SCOPE_PROTOTYPE)
|
||||||
|
@ -31,13 +42,20 @@ public class AccountBuilder {
|
||||||
private final JsonHandlingService jsonHandlingService;
|
private final JsonHandlingService jsonHandlingService;
|
||||||
private final UserScope userScope;
|
private final UserScope userScope;
|
||||||
private final TenantEntityManager entityManager;
|
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.claimExtractor = claimExtractor;
|
||||||
this.currentPrincipalResolver = currentPrincipalResolver;
|
this.currentPrincipalResolver = currentPrincipalResolver;
|
||||||
this.authorizationConfiguration = authorizationConfiguration;
|
this.authorizationConfiguration = authorizationConfiguration;
|
||||||
this.jsonHandlingService = jsonHandlingService;
|
this.jsonHandlingService = jsonHandlingService;
|
||||||
this.userScope = userScope;
|
this.userScope = userScope;
|
||||||
this.entityManager = entityManager;
|
this.entityManager = entityManager;
|
||||||
|
this.tenantScope = tenantScope;
|
||||||
|
this.queryFactory = queryFactory;
|
||||||
|
this.builderFactory = builderFactory;
|
||||||
this.excludeMoreClaim = Set.of(
|
this.excludeMoreClaim = Set.of(
|
||||||
ClaimExtractorKeys.Subject,
|
ClaimExtractorKeys.Subject,
|
||||||
ClaimExtractorKeys.Name,
|
ClaimExtractorKeys.Name,
|
||||||
|
@ -90,10 +108,6 @@ public class AccountBuilder {
|
||||||
model.getPrincipal().getMore().get(key).addAll(values);
|
model.getPrincipal().getMore().get(key).addAll(values);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (fields.hasField(Account._roles)) {
|
|
||||||
List<String> roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
|
||||||
model.setRoles(roles);
|
|
||||||
}
|
|
||||||
if (fields.hasField(Account._permissions)) {
|
if (fields.hasField(Account._permissions)) {
|
||||||
List<String> roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
List<String> roles = this.claimExtractor.roles(this.currentPrincipalResolver.currentPrincipal());
|
||||||
Set<String> permissions = this.authorizationConfiguration.permissionsOfRoles(roles);
|
Set<String> permissions = this.authorizationConfiguration.permissionsOfRoles(roles);
|
||||||
|
@ -105,6 +119,15 @@ public class AccountBuilder {
|
||||||
model.setPermissions(new ArrayList<>(permissions));
|
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));
|
FieldSet profileFields = fields.extractPrefixed(BaseFieldSet.asIndexerPrefix(Account._profile));
|
||||||
if (!profileFields.isEmpty() && this.userScope.getUserIdSafe() != null){
|
if (!profileFields.isEmpty() && this.userScope.getUserIdSafe() != null){
|
||||||
model.setProfile(new Account.UserProfileInfo());
|
model.setProfile(new Account.UserProfileInfo());
|
||||||
|
|
|
@ -5,6 +5,7 @@ notification:
|
||||||
dmpFinalisedType: 90DB0B46-42DE-BD89-AEBF-6F27EFEB256E
|
dmpFinalisedType: 90DB0B46-42DE-BD89-AEBF-6F27EFEB256E
|
||||||
descriptionModifiedType: 4FDBFA80-7A71-4A69-B854-67CBB70648F1
|
descriptionModifiedType: 4FDBFA80-7A71-4A69-B854-67CBB70648F1
|
||||||
descriptionFinalisedType: 33790bad-94d4-488a-8ee2-7f6295ca18ea
|
descriptionFinalisedType: 33790bad-94d4-488a-8ee2-7f6295ca18ea
|
||||||
|
descriptionAnnotationCreated: db1e99d2-a240-4e75-9bb2-ef25b234c1f0
|
||||||
mergeAccountConfirmationType: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
mergeAccountConfirmationType: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
||||||
removeCredentialConfirmationType: C9BC3F16-057E-4BBA-8A5F-36BD835E5604
|
removeCredentialConfirmationType: C9BC3F16-057E-4BBA-8A5F-36BD835E5604
|
||||||
dmpDepositType: 55736F7A-83AB-4190-AF43-9D031A6F9612
|
dmpDepositType: 55736F7A-83AB-4190-AF43-9D031A6F9612
|
||||||
|
|
|
@ -54,6 +54,7 @@ queue:
|
||||||
enable: true
|
enable: true
|
||||||
options:
|
options:
|
||||||
exchange: null
|
exchange: null
|
||||||
|
annotation-created-topic: annotation.created
|
||||||
rabbitmq:
|
rabbitmq:
|
||||||
enable: true
|
enable: true
|
||||||
interval-seconds: 3
|
interval-seconds: 3
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { AppRole } from "@app/core/common/enum/app-role";
|
|
||||||
import { AppPermission } from "@app/core/common/enum/permission.enum";
|
import { AppPermission } from "@app/core/common/enum/permission.enum";
|
||||||
import { Guid } from "@common/types/guid";
|
import { Guid } from "@common/types/guid";
|
||||||
|
import { Tenant } from "../tenant/tenant";
|
||||||
|
|
||||||
export interface AppAccount {
|
export interface AppAccount {
|
||||||
isAuthenticated: boolean;
|
isAuthenticated: boolean;
|
||||||
roles: AppRole[];
|
|
||||||
permissions: AppPermission[];
|
permissions: AppPermission[];
|
||||||
principal: AppPrincipalInfo;
|
principal: AppPrincipalInfo;
|
||||||
profile: UserProfileInfo;
|
profile: UserProfileInfo;
|
||||||
|
selectedTenant: Tenant;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AppPrincipalInfo {
|
export interface AppPrincipalInfo {
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { Injectable, NgZone } from '@angular/core';
|
import { Injectable, NgZone } from '@angular/core';
|
||||||
import { Router } from '@angular/router';
|
import { Router } from '@angular/router';
|
||||||
import { AppRole } from '@app/core/common/enum/app-role';
|
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { AppAccount } from '@app/core/model/auth/principal';
|
import { AppAccount } from '@app/core/model/auth/principal';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
import { BaseService } from '@common/base/base.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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { KeycloakEventType, KeycloakService } from 'keycloak-angular';
|
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 { exhaustMap, map, takeUntil } from 'rxjs/operators';
|
||||||
import { ConfigurationService } from '../configuration/configuration.service';
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
import { PrincipalService } from '../http/principal.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';
|
import { TenantHandlingService } from '../tenant/tenant-handling.service';
|
||||||
|
|
||||||
export interface ResolutionContext {
|
export interface ResolutionContext {
|
||||||
roles: AppRole[];
|
|
||||||
permissions: AppPermission[];
|
permissions: AppPermission[];
|
||||||
}
|
}
|
||||||
export interface AuthenticationState {
|
export interface AuthenticationState {
|
||||||
|
@ -194,6 +192,7 @@ export class AuthService extends BaseService {
|
||||||
map(
|
map(
|
||||||
(myTenants) => {
|
(myTenants) => {
|
||||||
if (myTenants) {
|
if (myTenants) {
|
||||||
|
|
||||||
if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) {
|
if (myTenants.some(x => x.code.toLocaleLowerCase() == tenantCode.toLocaleLowerCase())) {
|
||||||
this.selectedTenant(tenantCode);
|
this.selectedTenant(tenantCode);
|
||||||
} else {
|
} else {
|
||||||
|
@ -228,12 +227,13 @@ export class AuthService extends BaseService {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getRoles(): AppRole[] {
|
public getSelectedTenantName(): string {
|
||||||
if (this.appAccount && this.appAccount.roles) {
|
if (this.appAccount && this.appAccount.selectedTenant) {
|
||||||
return this.appAccount.roles;
|
return this.appAccount.selectedTenant.name;
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public getUserProfileEmail(): string {
|
public getUserProfileEmail(): string {
|
||||||
if (this.appAccount && this.appAccount.profile) {
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
return this.appAccount.profile.email;
|
return this.appAccount.profile.email;
|
||||||
|
@ -248,28 +248,6 @@ export class AuthService extends BaseService {
|
||||||
return null;
|
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 {
|
public getUserProfileCulture(): string {
|
||||||
if (this.appAccount && this.appAccount.profile) {
|
if (this.appAccount && this.appAccount.profile) {
|
||||||
return this.appAccount.profile.culture;
|
return this.appAccount.profile.culture;
|
||||||
|
@ -388,7 +366,6 @@ export class AuthService extends BaseService {
|
||||||
}
|
}
|
||||||
private evaluatePermission(availablePermissions: string[], permissionToCheck: string): boolean {
|
private evaluatePermission(availablePermissions: string[], permissionToCheck: string): boolean {
|
||||||
if (!permissionToCheck) { return false; }
|
if (!permissionToCheck) { return false; }
|
||||||
// if (this.hasRole(AppRole.Admin)) { return true; }
|
|
||||||
return availablePermissions.map(x => x.toLowerCase()).includes(permissionToCheck.toLowerCase());
|
return availablePermissions.map(x => x.toLowerCase()).includes(permissionToCheck.toLowerCase());
|
||||||
}
|
}
|
||||||
public hasAnyPermission(permissions: AppPermission[]): boolean {
|
public hasAnyPermission(permissions: AppPermission[]): boolean {
|
||||||
|
@ -398,19 +375,14 @@ export class AuthService extends BaseService {
|
||||||
|
|
||||||
public authorize(context: ResolutionContext): boolean {
|
public authorize(context: ResolutionContext): boolean {
|
||||||
|
|
||||||
if (!context || this.hasRole(AppRole.Admin)) { return true; }
|
if (!context) { return true; }
|
||||||
|
|
||||||
let roleAuthorized = false;
|
|
||||||
if (context.roles && context.roles.length > 0) {
|
|
||||||
roleAuthorized = this.hasAnyRole(context.roles);
|
|
||||||
}
|
|
||||||
|
|
||||||
let permissionAuthorized = false;
|
let permissionAuthorized = false;
|
||||||
if (context.permissions && context.permissions.length > 0) {
|
if (context.permissions && context.permissions.length > 0) {
|
||||||
permissionAuthorized = this.hasAnyPermission(context.permissions);
|
permissionAuthorized = this.hasAnyPermission(context.permissions);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (roleAuthorized || permissionAuthorized) { return true; }
|
if (permissionAuthorized) { return true; }
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +1,14 @@
|
||||||
import { Injectable } from '@angular/core';
|
import { Injectable } from '@angular/core';
|
||||||
import { UserSettingPersist, UserSettingsInformation, UserSettings as UserSettingsObject } from '@app/core/model/user-settings/user-settings.model';
|
import { UserSettingPersist, UserSettingsInformation, UserSettings as UserSettingsObject } from '@app/core/model/user-settings/user-settings.model';
|
||||||
import { BaseService } from '@common/base/base.service';
|
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 { Guid } from '@common/types/guid';
|
||||||
import moment from 'moment';
|
import moment, { Moment } from 'moment';
|
||||||
import { Moment } from 'moment';
|
|
||||||
import { Observable, Subject, of as observableOf } from 'rxjs';
|
import { Observable, Subject, of as observableOf } from 'rxjs';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { AuthService, LoginStatus } from '../auth/auth.service';
|
import { AuthService, LoginStatus } from '../auth/auth.service';
|
||||||
import { ConfigurationService } from '../configuration/configuration.service';
|
import { ConfigurationService } from '../configuration/configuration.service';
|
||||||
import { UserSettingsHttpService } from './user-settings-http.service';
|
import { UserSettingsHttpService } from './user-settings-http.service';
|
||||||
import { HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
|
||||||
|
|
||||||
export enum UserSettingsType {
|
export enum UserSettingsType {
|
||||||
Setting = 0,
|
Setting = 0,
|
||||||
|
@ -117,7 +116,7 @@ export class UserSettingsService extends BaseService {
|
||||||
this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false);
|
this.persistUserSettings(userSettingsInformation.key, result, userSettingsInformation, false);
|
||||||
this.userSettingUpdated.next(userSettingsInformation.key);
|
this.userSettingUpdated.next(userSettingsInformation.key);
|
||||||
},
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
private buildUserSettings<T>(setting: UserSetting<T>, key: string): UserSettings<T> {
|
private buildUserSettings<T>(setting: UserSetting<T>, key: string): UserSettings<T> {
|
||||||
|
@ -264,7 +263,7 @@ export class UserSettingsService extends BaseService {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}
|
}
|
||||||
|
|
||||||
private clearSetting(key: string) {
|
private clearSetting(key: string) {
|
||||||
|
@ -289,24 +288,6 @@ export class UserSettingsService extends BaseService {
|
||||||
return `${this.getUserSettingsVersion()}_${this.getUserId()}_${key}`;
|
return `${this.getUserSettingsVersion()}_${this.getUserId()}_${key}`;
|
||||||
}
|
}
|
||||||
|
|
||||||
// private defaultValue<T>(userSettingsInformation: UserSettingsInformation<T>): UserSettings<T> {
|
|
||||||
// const defaultSetting: UserSetting<T> = {
|
|
||||||
// id: null,
|
|
||||||
// name: null,
|
|
||||||
// userId: this.getUserId(),
|
|
||||||
// key: userSettingsInformation.key,
|
|
||||||
// type: UserSettingsType.Config,
|
|
||||||
// isDefault: true,
|
|
||||||
// value: new userSettingsInformation.type()
|
|
||||||
// };
|
|
||||||
// const userSettings: UserSettings<T> = {
|
|
||||||
// defaultSetting: defaultSetting,
|
|
||||||
// key: userSettingsInformation.key,
|
|
||||||
// settings: [defaultSetting]
|
|
||||||
// };
|
|
||||||
// return userSettings;
|
|
||||||
// }
|
|
||||||
|
|
||||||
private getUserId(): Guid {
|
private getUserId(): Guid {
|
||||||
return this.authService.userId();
|
return this.authService.userId();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,35 +1,34 @@
|
||||||
import { Injectable } from '@angular/core';
|
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 { 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 { 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 { 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 { DescriptionTemplateFieldType } from '@app/core/common/enum/description-template-field-type';
|
||||||
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
|
import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status';
|
||||||
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status';
|
||||||
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
|
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 { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status';
|
||||||
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
|
import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type';
|
||||||
import { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
|
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 { 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 { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
||||||
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
|
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
|
||||||
import { ReferenceSourceType } from '@app/core/common/enum/reference-source-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 { RoleOrganizationType } from '@app/core/common/enum/role-organization-type';
|
||||||
import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type';
|
import { SupportiveMaterialFieldType } from '@app/core/common/enum/supportive-material-field-type';
|
||||||
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
|
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { AppRole } from '../../common/enum/app-role';
|
import { AppRole } from '../../common/enum/app-role';
|
||||||
import { DmpBlueprintExtraFieldDataType } from '../../common/enum/dmp-blueprint-field-type';
|
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 { DmpStatus } from '../../common/enum/dmp-status';
|
||||||
import { ValidationType } from '../../common/enum/validation-type';
|
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()
|
@Injectable()
|
||||||
export class EnumUtils {
|
export class EnumUtils {
|
||||||
|
@ -227,12 +226,8 @@ export class EnumUtils {
|
||||||
|
|
||||||
toRecentActivityOrderString(status: RecentActivityOrder): string {
|
toRecentActivityOrderString(status: RecentActivityOrder): string {
|
||||||
switch (status) {
|
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.Label: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.LABEL');
|
||||||
case RecentActivityOrder.UpdatedAt: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.MODIFIED');
|
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');
|
case RecentActivityOrder.Status: return this.language.instant('TYPES.RECENT-ACTIVITY-ORDER.STATUS');
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
.multiple-auto-complete {
|
.multiple-auto-complete {
|
||||||
// margin-left: inherit;
|
|
||||||
// margin-right: inherit;
|
|
||||||
|
|
||||||
.not-loading {
|
.not-loading {
|
||||||
display: none;
|
display: none;
|
||||||
|
@ -8,10 +6,7 @@
|
||||||
|
|
||||||
|
|
||||||
.align-arrow-right {
|
.align-arrow-right {
|
||||||
// position: absolute;
|
|
||||||
right: 0;
|
right: 0;
|
||||||
// bottom: 0;
|
|
||||||
// vertical-align: middle;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
align-self: center;
|
align-self: center;
|
||||||
color: rgba(0, 0, 0, 0.54);
|
color: rgba(0, 0, 0, 0.54);
|
||||||
|
@ -25,19 +20,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.chip-text {
|
.chip-text {
|
||||||
// text-overflow: ellipsis;
|
|
||||||
// white-space: nowrap;
|
|
||||||
// overflow: hidden;
|
|
||||||
white-space: normal;
|
white-space: normal;
|
||||||
word-break: break-word;
|
word-break: break-word;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// .chip-list {
|
|
||||||
// max-width: calc(100% - 30px);
|
|
||||||
// padding-left: 0.8em;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.title-subtitle-fn {
|
.title-subtitle-fn {
|
||||||
height: auto;
|
height: auto;
|
||||||
width: calc(100% - 46px);
|
width: calc(100% - 46px);
|
||||||
|
|
|
@ -57,11 +57,6 @@
|
||||||
line-height: 1.2em;
|
line-height: 1.2em;
|
||||||
}
|
}
|
||||||
|
|
||||||
// .two-line-mat-option {
|
|
||||||
// height: 3.5em;
|
|
||||||
// line-height: 1.2em;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.mat-standard-chip:hover::after {
|
.mat-standard-chip:hover::after {
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
@ -70,11 +65,6 @@
|
||||||
opacity: 0;
|
opacity: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// .mat-form-field-type-single-autocomplete:not(.mat-form-field-disabled) .mat-form-field-flex {
|
|
||||||
// cursor: pointer;
|
|
||||||
// }
|
|
||||||
|
|
||||||
.option-text-container {
|
.option-text-container {
|
||||||
min-width: 0;
|
min-width: 0;
|
||||||
}
|
}
|
||||||
|
|
|
@ -313,9 +313,9 @@ export class SingleAutoCompleteComponent extends _CustomComponentMixinBase imple
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnDestroy() {
|
ngOnDestroy() {
|
||||||
this.panelClosedSubscription.unsubscribe();
|
this.panelClosedSubscription?.unsubscribe();
|
||||||
this.stateChanges.complete();
|
this.stateChanges?.complete();
|
||||||
this.fm.stopMonitoring(this.elRef.nativeElement);
|
this.fm?.stopMonitoring(this.elRef?.nativeElement);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Configuration getters
|
//Configuration getters
|
||||||
|
|
|
@ -17,42 +17,6 @@ ngx-guided-tour {
|
||||||
border-radius: 44px; /*custom add*/
|
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 {
|
.tour-step {
|
||||||
position: fixed;
|
position: fixed;
|
||||||
&.page-tour-step {
|
&.page-tour-step {
|
||||||
|
@ -154,9 +118,6 @@ ngx-guided-tour {
|
||||||
}
|
}
|
||||||
|
|
||||||
.tour-title {
|
.tour-title {
|
||||||
// font-weight: bold !important;
|
|
||||||
// padding-bottom: 20px;
|
|
||||||
|
|
||||||
/*custom add*/
|
/*custom add*/
|
||||||
font-weight: lighter !important;
|
font-weight: lighter !important;
|
||||||
font-size: 16px !important;
|
font-size: 16px !important;
|
||||||
|
@ -166,7 +127,6 @@ ngx-guided-tour {
|
||||||
color: #212121;
|
color: #212121;
|
||||||
line-height: 26px;
|
line-height: 26px;
|
||||||
white-space: pre-line;
|
white-space: pre-line;
|
||||||
// height: 210px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
h3.tour-title {
|
h3.tour-title {
|
||||||
|
@ -201,14 +161,11 @@ ngx-guided-tour {
|
||||||
}
|
}
|
||||||
|
|
||||||
button.skip-button.link-button {
|
button.skip-button.link-button {
|
||||||
// padding-left: 0;
|
|
||||||
border-left: 0;
|
border-left: 0;
|
||||||
|
|
||||||
/*custom add*/
|
/*custom add*/
|
||||||
// padding: 0;
|
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
// float: right;
|
|
||||||
min-width: 133px;
|
min-width: 133px;
|
||||||
height: 40px;
|
height: 40px;
|
||||||
border: 1px solid var(--primary-color);
|
border: 1px solid var(--primary-color);
|
||||||
|
@ -218,16 +175,10 @@ ngx-guided-tour {
|
||||||
|
|
||||||
.next-button {
|
.next-button {
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
// border-radius: 1px;
|
|
||||||
// float: right;
|
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
// padding-left: 10px;
|
|
||||||
// padding-right: 10px;
|
|
||||||
|
|
||||||
/*custom add*/
|
/*custom add*/
|
||||||
// float: left;
|
|
||||||
// padding: 10px 0px;
|
|
||||||
padding-left: 1em;
|
padding-left: 1em;
|
||||||
padding-right: 1em;
|
padding-right: 1em;
|
||||||
min-width: 101px;
|
min-width: 101px;
|
||||||
|
|
|
@ -40,7 +40,6 @@ export class DescriptionTemplateEditorSectionFieldSetComponent implements OnInit
|
||||||
|
|
||||||
private initializer = new Subject<void>();
|
private initializer = new Subject<void>();
|
||||||
private scroller = new Subject<string>();
|
private scroller = new Subject<string>();
|
||||||
// private $selectedFieldsetId = new Subject<string>();
|
|
||||||
constructor(
|
constructor(
|
||||||
private dragulaService: DragulaService,
|
private dragulaService: DragulaService,
|
||||||
private myElement: ElementRef
|
private myElement: ElementRef
|
||||||
|
@ -52,8 +51,6 @@ export class DescriptionTemplateEditorSectionFieldSetComponent implements OnInit
|
||||||
|
|
||||||
this.dragulaService.createGroup(this.FIELDSETS, {
|
this.dragulaService.createGroup(this.FIELDSETS, {
|
||||||
moves: (el, container, handle) => {
|
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;
|
if (handle.className && handle.classList.contains('handle')) return true;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { Component, OnInit, QueryList, ViewChild } from '@angular/core';
|
||||||
import { FormArray, FormControl, FormGroup, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
import { FormArray, FormControl, FormGroup, UntypedFormArray, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
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 { 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 { 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 { 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 { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
|
import { UserDescriptionTemplateRole } from '@app/core/common/enum/user-description-template-role';
|
||||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
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 { LanguageInfo } from '@app/core/model/language-info';
|
||||||
import { User } from '@app/core/model/user/user';
|
import { User } from '@app/core/model/user/user';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
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 { LanguageInfoService } from '@app/core/services/culture/language-info-service';
|
||||||
import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.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 { 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 { 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 { 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 { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.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 { BaseEditor } from '@common/base/base-editor';
|
||||||
import { FormService } from '@common/forms/form-service';
|
import { FormService } from '@common/forms/form-service';
|
||||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
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 { DescriptionTemplateEditorResolver } from './description-template-editor.resolver';
|
||||||
import { DescriptionTemplateEditorService } from './description-template-editor.service';
|
import { DescriptionTemplateEditorService } from './description-template-editor.service';
|
||||||
import { NewEntryType, ToCEntry, ToCEntryType } from './table-of-contents/description-template-table-of-contents-entry';
|
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({
|
@Component({
|
||||||
|
@ -79,7 +78,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
userFormControl = new FormControl();
|
userFormControl = new FormControl();
|
||||||
|
|
||||||
singleAutocompleteDescriptionTemplateTypeConfiguration: SingleAutoCompleteConfiguration;
|
singleAutocompleteDescriptionTemplateTypeConfiguration: SingleAutoCompleteConfiguration;
|
||||||
|
|
||||||
|
|
||||||
//Preview
|
//Preview
|
||||||
previewFieldSet: DescriptionTemplate = null;
|
previewFieldSet: DescriptionTemplate = null;
|
||||||
|
@ -94,7 +93,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
get fromStepperLabel(): string {
|
get fromStepperLabel(): string {
|
||||||
return '2 ' + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TITLE');
|
return '2 ' + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.STEPS.FORM.TITLE');
|
||||||
}
|
}
|
||||||
|
|
||||||
get previewLabel(): string {
|
get previewLabel(): string {
|
||||||
return '3 ' + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.PREVIEW-AND-FINALIZE');
|
return '3 ' + this.language.instant('DESCRIPTION-TEMPLATE-EDITOR.ACTIONS.PREVIEW-AND-FINALIZE');
|
||||||
}
|
}
|
||||||
|
@ -143,7 +142,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
public titleService: Title,
|
public titleService: Title,
|
||||||
private analyticsService: AnalyticsService
|
private analyticsService: AnalyticsService
|
||||||
) {
|
) {
|
||||||
const descriptionLabel:string = route.snapshot.data['entity']?.label;
|
const descriptionLabel: string = route.snapshot.data['entity']?.label;
|
||||||
if (descriptionLabel) {
|
if (descriptionLabel) {
|
||||||
titleService.setTitle(descriptionLabel);
|
titleService.setTitle(descriptionLabel);
|
||||||
} else {
|
} else {
|
||||||
|
@ -233,14 +232,14 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
} else if (this.isNew || this.isNewVersion || this.isClone) {
|
} else if (this.isNew || this.isNewVersion || this.isClone) {
|
||||||
route.push('/description-templates/' + id);
|
route.push('/description-templates/' + id);
|
||||||
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
this.router.navigate(route, { queryParams: { 'lookup': this.queryParamsService.serializeLookup(this.lookupParams), 'lv': ++this.lv }, replaceUrl: true, relativeTo: this.route });
|
||||||
} else{
|
} else {
|
||||||
this.refreshData();
|
this.refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
persistEntity(onSuccess?: (response) => void): void {
|
persistEntity(onSuccess?: (response) => void): void {
|
||||||
if (this.isNewVersion == false){
|
if (this.isNewVersion == false) {
|
||||||
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist;
|
const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist;
|
||||||
|
|
||||||
this.descriptionTemplateService.persist(formData)
|
this.descriptionTemplateService.persist(formData)
|
||||||
|
@ -248,14 +247,14 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
||||||
error => this.onCallbackError(error)
|
error => this.onCallbackError(error)
|
||||||
);
|
);
|
||||||
} else if (this.isNewVersion== true && this.isNew == false && this.isClone == false) {
|
} else if (this.isNewVersion == true && this.isNew == false && this.isClone == false) {
|
||||||
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist;
|
const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist;
|
||||||
|
|
||||||
this.descriptionTemplateService.newVersion(formData)
|
this.descriptionTemplateService.newVersion(formData)
|
||||||
.pipe(takeUntil(this._destroyed)).subscribe(
|
.pipe(takeUntil(this._destroyed)).subscribe(
|
||||||
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
complete => onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete),
|
||||||
error => this.onCallbackError(error)
|
error => this.onCallbackError(error)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,10 +268,10 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
this.persistEntity(onSuccess);
|
this.persistEntity(onSuccess);
|
||||||
}
|
}
|
||||||
|
|
||||||
saveWithClose(close: boolean){
|
saveWithClose(close: boolean) {
|
||||||
this.formSubmit((data) => {
|
this.formSubmit((data) => {
|
||||||
this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success);
|
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.formGroup = null;
|
||||||
this.router.navigate(['/description-templates']);
|
this.router.navigate(['/description-templates']);
|
||||||
} else {
|
} else {
|
||||||
|
@ -325,7 +324,8 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
if (result) {
|
if (result) {
|
||||||
this.formGroup.get('status').setValue(DescriptionTemplateStatus.Finalized);
|
this.formGroup.get('status').setValue(DescriptionTemplateStatus.Finalized);
|
||||||
this.persistEntity();
|
this.persistEntity();
|
||||||
}});
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -592,7 +592,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return sameLevelFields.at(tceIndex > 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[] {
|
private populateSections(sections: UntypedFormArray, existingNumbering: string, validationRootPath: string): ToCEntry[] {
|
||||||
|
@ -803,7 +803,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
field.ordinal = 0;//first filed in the fields list
|
field.ordinal = 0;//first filed in the fields list
|
||||||
|
|
||||||
const fieldSetsArray = parent.form.get('fieldSets') as UntypedFormArray
|
const fieldSetsArray = parent.form.get('fieldSets') as UntypedFormArray
|
||||||
const fieldForm = field.buildForm({ rootPath:'definition.pages[' + pageIndex + '].' + parentSectionRootPath + 'fieldSets[' + fieldSetsArray.length + '].' + 'fields[' + 0 + '].' });
|
const fieldForm = field.buildForm({ rootPath: 'definition.pages[' + pageIndex + '].' + parentSectionRootPath + 'fieldSets[' + fieldSetsArray.length + '].' + 'fields[' + 0 + '].' });
|
||||||
|
|
||||||
//give fieldset id and ordinal
|
//give fieldset id and ordinal
|
||||||
const fieldSet: DescriptionTemplateFieldSetEditorModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel);
|
const fieldSet: DescriptionTemplateFieldSetEditorModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel);
|
||||||
|
@ -1016,7 +1016,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cloneFieldSet(fieldset: FormGroup, validationRootPath: string){
|
cloneFieldSet(fieldset: FormGroup, validationRootPath: string) {
|
||||||
const values = fieldset.getRawValue();
|
const values = fieldset.getRawValue();
|
||||||
const parentArray = fieldset.parent as FormArray;
|
const parentArray = fieldset.parent as FormArray;
|
||||||
|
|
||||||
|
@ -1029,14 +1029,14 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
|
|
||||||
|
|
||||||
const clonedModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel).fromModel(values);
|
const clonedModel = new DescriptionTemplateFieldSetEditorModel(this.editorModel.validationErrorModel).fromModel(values);
|
||||||
const clonedForm = clonedModel.buildForm({rootPath: validationRootPath + '.fieldSets[' + parentArray.length + ']' + '.fields[' + 0 + '].'});
|
const clonedForm = clonedModel.buildForm({ rootPath: validationRootPath + '.fieldSets[' + parentArray.length + ']' + '.fields[' + 0 + '].' });
|
||||||
parentArray.push(clonedForm);
|
parentArray.push(clonedForm);
|
||||||
|
|
||||||
//update tocentries and make selected tocentry the cloedn
|
//update tocentries and make selected tocentry the cloedn
|
||||||
let entries = this.refreshToCEntries();
|
let entries = this.refreshToCEntries();
|
||||||
|
|
||||||
const entryfound = this._findTocEntryById(clonedForm.get('id').value, entries);
|
const entryfound = this._findTocEntryById(clonedForm.get('id').value, entries);
|
||||||
if(entryfound){
|
if (entryfound) {
|
||||||
this.selectedTocEntry = entryfound;
|
this.selectedTocEntry = entryfound;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1081,23 +1081,23 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
const previousField = this.getNextFieldAfterDeletingTocentry(tce);
|
const previousField = this.getNextFieldAfterDeletingTocentry(tce);
|
||||||
const tocentries = this.getTocEntries();
|
const tocentries = this.getTocEntries();
|
||||||
const previousFieldTocEntry = this._findTocEntryById(previousField?.id, tocentries);
|
const previousFieldTocEntry = this._findTocEntryById(previousField?.id, tocentries);
|
||||||
|
|
||||||
this.selectedTocEntry = previousFieldTocEntry;
|
this.selectedTocEntry = previousFieldTocEntry;
|
||||||
|
|
||||||
} else if (sameLevelFields?.length == 1) {
|
} else if (sameLevelFields?.length == 1) {
|
||||||
//scroll to parent
|
//scroll to parent
|
||||||
|
|
||||||
let parentId = null;
|
let parentId = null;
|
||||||
if (isFirstLevel) {
|
if (isFirstLevel) {
|
||||||
parentId = tce.form.get('page').value;
|
parentId = tce.form.get('page').value;
|
||||||
} else {
|
} else {
|
||||||
parentId = tce.form.parent.parent.get('id').value
|
parentId = tce.form.parent.parent.get('id').value
|
||||||
}
|
}
|
||||||
|
|
||||||
if (parentId) {
|
if (parentId) {
|
||||||
const tocentries = this.getTocEntries();
|
const tocentries = this.getTocEntries();
|
||||||
const parent = this._findTocEntryById(parentId, tocentries);
|
const parent = this._findTocEntryById(parentId, tocentries);
|
||||||
|
|
||||||
if (parent) {
|
if (parent) {
|
||||||
this.selectedTocEntry = parent;
|
this.selectedTocEntry = parent;
|
||||||
} else {
|
} else {
|
||||||
|
@ -1206,33 +1206,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor<DescriptionTe
|
||||||
//
|
//
|
||||||
//
|
//
|
||||||
private hasInvalidVisibilityRule(field: UntypedFormGroup): boolean {
|
private hasInvalidVisibilityRule(field: UntypedFormGroup): boolean {
|
||||||
// const renderStyle = field.get('viewStyle').get('renderStyle').value;
|
|
||||||
// if (renderStyle && ![
|
|
||||||
// DatasetProfileFieldViewStyle.TextArea,
|
|
||||||
// DatasetProfileFieldViewStyle.RichTextArea,
|
|
||||||
// DatasetProfileFieldViewStyle.Upload,
|
|
||||||
// DatasetProfileFieldViewStyle.FreeText,
|
|
||||||
// DatasetProfileFieldViewStyle.BooleanDecision,
|
|
||||||
// DatasetProfileFieldViewStyle.RadioBox,
|
|
||||||
// DatasetProfileFieldViewStyle.CheckBox,
|
|
||||||
// DatasetProfileFieldViewStyle.DatePicker,
|
|
||||||
// DatasetProfileFieldViewStyle.ComboBox,
|
|
||||||
// ].includes(renderStyle)) {
|
|
||||||
// if (((renderStyle === DatasetProfileFieldViewStyle) && (field.get('data').get('type').value === DatasetProfileComboBoxType.Select))) {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// try {
|
|
||||||
// if (field.get('visible').get('rules').value.length) {
|
|
||||||
// return true;
|
|
||||||
// }
|
|
||||||
// return false;
|
|
||||||
|
|
||||||
// } catch {
|
|
||||||
// return false;
|
|
||||||
// }
|
|
||||||
// } else {
|
|
||||||
return false;
|
return false;
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private removeFieldSetVisibilityRules(fieldsets: ToCEntry[]) {
|
private removeFieldSetVisibilityRules(fieldsets: ToCEntry[]) {
|
||||||
|
|
|
@ -414,7 +414,7 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements
|
||||||
);
|
);
|
||||||
|
|
||||||
this.dragSubscriptions.push(
|
this.dragSubscriptions.push(
|
||||||
dragulaService.over(this.DRAG_GROUP).subscribe(( {el, container, source }) => {
|
dragulaService.over(this.DRAG_GROUP).subscribe(({ el, container, source }) => {
|
||||||
try {
|
try {
|
||||||
this.overcontainer = container.id;
|
this.overcontainer = container.id;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@ -422,7 +422,7 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
this.dragSubscriptions.push(
|
this.dragSubscriptions.push(
|
||||||
dragulaService.dragend(this.DRAG_GROUP).subscribe(({ el }) => {
|
dragulaService.dragend(this.DRAG_GROUP).subscribe(({ el }) => {
|
||||||
this.isDragging = false;
|
this.isDragging = false;
|
||||||
|
@ -430,394 +430,9 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements
|
||||||
this.overcontainer = null;
|
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 {
|
ngAfterViewInit(): void {
|
||||||
|
|
||||||
|
@ -872,42 +487,6 @@ export class DescriptionTemplateTableOfContents extends BaseComponent implements
|
||||||
this.dragSubscriptions.forEach(subscription => subscription.unsubscribe())
|
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 {
|
private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry {
|
||||||
if (!tocentries) {
|
if (!tocentries) {
|
||||||
return null;
|
return null;
|
||||||
|
|
|
@ -3,17 +3,22 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { FormArray, FormGroup, UntypedFormGroup } from '@angular/forms';
|
import { FormArray, FormGroup, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
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 { 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 { 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 { 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 { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { PrefillingSource, PrefillingSourcePersist } from '@app/core/model/prefilling-source/prefilling-source';
|
import { PrefillingSource, PrefillingSourcePersist } from '@app/core/model/prefilling-source/prefilling-source';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
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 { 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 { 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 { BaseEditor } from '@common/base/base-editor';
|
||||||
import { FormService } from '@common/forms/form-service';
|
import { FormService } from '@common/forms/form-service';
|
||||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
|
import { PrefillingSourceDefinitionEditorModel, PrefillingSourceEditorModel } from './prefilling-source-editor.model';
|
||||||
import { PrefillingSourceEditorResolver } from './prefilling-source-editor.resolver';
|
import { PrefillingSourceEditorResolver } from './prefilling-source-editor.resolver';
|
||||||
import { PrefillingSourceEditorService } from './prefilling-source-editor.service';
|
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({
|
@Component({
|
||||||
selector: 'app-prefilling-source-editor-component',
|
selector: 'app-prefilling-source-editor-component',
|
||||||
|
@ -80,7 +79,7 @@ export class PrefillingSourceEditorComponent extends BaseEditor<PrefillingSource
|
||||||
private titleService: Title,
|
private titleService: Title,
|
||||||
private analyticsService: AnalyticsService
|
private analyticsService: AnalyticsService
|
||||||
) {
|
) {
|
||||||
const descriptionLabel:string = route.snapshot.data['entity']?.label;
|
const descriptionLabel: string = route.snapshot.data['entity']?.label;
|
||||||
if (descriptionLabel) {
|
if (descriptionLabel) {
|
||||||
titleService.setTitle(descriptionLabel);
|
titleService.setTitle(descriptionLabel);
|
||||||
} else {
|
} else {
|
||||||
|
@ -190,13 +189,13 @@ export class PrefillingSourceEditorComponent extends BaseEditor<PrefillingSource
|
||||||
this.formService.validateAllFormFields(this.formGroup);
|
this.formService.validateAllFormFields(this.formGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
getEnabledChanged(event: MatCheckboxChange){
|
getEnabledChanged(event: MatCheckboxChange) {
|
||||||
if(event.checked == true){
|
if (event.checked == true) {
|
||||||
const definition = new PrefillingSourceDefinitionEditorModel(this.editorModel.validationErrorModel);
|
const definition = new PrefillingSourceDefinitionEditorModel(this.editorModel.validationErrorModel);
|
||||||
definition.buildGetConfiguration(this.formGroup.get('definition') as UntypedFormGroup, "definition.");
|
definition.buildGetConfiguration(this.formGroup.get('definition') as UntypedFormGroup, "definition.");
|
||||||
|
|
||||||
this.submitFields();
|
this.submitFields();
|
||||||
}else{
|
} else {
|
||||||
const definition = this.formGroup.get('definition') as UntypedFormGroup;
|
const definition = this.formGroup.get('definition') as UntypedFormGroup;
|
||||||
if (definition.get('getConfiguration')) definition.removeControl('getConfiguration');
|
if (definition.get('getConfiguration')) definition.removeControl('getConfiguration');
|
||||||
this.submitFields();
|
this.submitFields();
|
||||||
|
@ -294,21 +293,21 @@ export class PrefillingSourceEditorComponent extends BaseEditor<PrefillingSource
|
||||||
}
|
}
|
||||||
const fieldsMapping = new ResultFieldsMappingConfigurationEditorModel(this.editorModel.validationErrorModel);
|
const fieldsMapping = new ResultFieldsMappingConfigurationEditorModel(this.editorModel.validationErrorModel);
|
||||||
fieldsMapping.code = code;
|
fieldsMapping.code = code;
|
||||||
formArray.push(fieldsMapping.buildForm({rootPath: "definition." + controlName + ".results.fieldsMapping[" + fieldMappingSize + "]."}));
|
formArray.push(fieldsMapping.buildForm({ rootPath: "definition." + controlName + ".results.fieldsMapping[" + fieldMappingSize + "]." }));
|
||||||
// formArray.at(fieldMappingSize).get('code').patchValue(code);
|
// formArray.at(fieldMappingSize).get('code').patchValue(code);
|
||||||
}
|
}
|
||||||
|
|
||||||
removeFieldMapping(baseFormGroup: any, fieldCode: string){
|
removeFieldMapping(baseFormGroup: any, fieldCode: string) {
|
||||||
if(baseFormGroup){
|
if (baseFormGroup) {
|
||||||
const fieldMappingFormArray = (baseFormGroup.get('results').get('fieldsMapping') as FormArray);
|
const fieldMappingFormArray = (baseFormGroup.get('results').get('fieldsMapping') as FormArray);
|
||||||
for (let j = 0; j < fieldMappingFormArray.length; j++) {
|
for (let j = 0; j < fieldMappingFormArray.length; j++) {
|
||||||
if (fieldCode == fieldMappingFormArray.at(j).get('code').getRawValue()) {
|
if (fieldCode == fieldMappingFormArray.at(j).get('code').getRawValue()) {
|
||||||
fieldMappingFormArray.removeAt(j);
|
fieldMappingFormArray.removeAt(j);
|
||||||
|
|
||||||
PrefillingSourceEditorModel.reApplyDefinitionValidators({
|
PrefillingSourceEditorModel.reApplyDefinitionValidators({
|
||||||
formGroup: this.formGroup,
|
formGroup: this.formGroup,
|
||||||
validationErrorModel: this.editorModel.validationErrorModel
|
validationErrorModel: this.editorModel.validationErrorModel
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,21 +1,23 @@
|
||||||
|
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormArray, UntypedFormGroup } from '@angular/forms';
|
import { FormArray, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
import { ExternalFetcherApiHTTPMethodType } from '@app/core/common/enum/external-fetcher-api-http-method-type';
|
||||||
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
import { ExternalFetcherSourceType } from '@app/core/common/enum/external-fetcher-source-type';
|
||||||
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 { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
|
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-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 { ReferenceType, ReferenceTypePersist } from '@app/core/model/reference-type/reference-type';
|
import { ReferenceType, ReferenceTypePersist } from '@app/core/model/reference-type/reference-type';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
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 { LoggingService } from '@app/core/services/logging/logging-service';
|
||||||
|
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
|
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
||||||
|
import { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||||
import { BaseEditor } from '@common/base/base-editor';
|
import { BaseEditor } from '@common/base/base-editor';
|
||||||
import { FormService } from '@common/forms/form-service';
|
import { FormService } from '@common/forms/form-service';
|
||||||
|
@ -25,12 +27,9 @@ import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||||
import { Guid } from '@common/types/guid';
|
import { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { ReferenceTypeEditorModel} from './reference-type-editor.model';
|
import { ReferenceTypeEditorModel } from './reference-type-editor.model';
|
||||||
import { ReferenceTypeEditorResolver } from './reference-type-editor.resolver';
|
import { ReferenceTypeEditorResolver } from './reference-type-editor.resolver';
|
||||||
import { ReferenceTypeEditorService } from './reference-type-editor.service';
|
import { ReferenceTypeEditorService } from './reference-type-editor.service';
|
||||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
|
||||||
import { LockService } from '@app/core/services/lock/lock.service';
|
|
||||||
import { Title } from '@angular/platform-browser';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-reference-type-editor-component',
|
selector: 'app-reference-type-editor-component',
|
||||||
|
@ -90,8 +89,8 @@ export class ReferenceTypeEditorComponent extends BaseEditor<ReferenceTypeEditor
|
||||||
private logger: LoggingService,
|
private logger: LoggingService,
|
||||||
private referenceTypeEditorService: ReferenceTypeEditorService,
|
private referenceTypeEditorService: ReferenceTypeEditorService,
|
||||||
private titleService: Title
|
private titleService: Title
|
||||||
) {
|
) {
|
||||||
const descriptionLabel:string = route.snapshot.data['entity']?.name;
|
const descriptionLabel: string = route.snapshot.data['entity']?.name;
|
||||||
if (descriptionLabel) {
|
if (descriptionLabel) {
|
||||||
titleService.setTitle(descriptionLabel);
|
titleService.setTitle(descriptionLabel);
|
||||||
} else {
|
} else {
|
||||||
|
@ -227,7 +226,7 @@ export class ReferenceTypeEditorComponent extends BaseEditor<ReferenceTypeEditor
|
||||||
fieldForm.markAsDirty();
|
fieldForm.markAsDirty();
|
||||||
|
|
||||||
const sourceFormArray = (this.formGroup.get('definition').get('sources') as FormArray);
|
const sourceFormArray = (this.formGroup.get('definition').get('sources') as FormArray);
|
||||||
if(sourceFormArray){
|
if (sourceFormArray) {
|
||||||
for (let i = 0; i < sourceFormArray.length; i++) {
|
for (let i = 0; i < sourceFormArray.length; i++) {
|
||||||
const fieldMappingFormArray = (sourceFormArray.at(i).get('results').get('fieldsMapping') as FormArray);
|
const fieldMappingFormArray = (sourceFormArray.at(i).get('results').get('fieldsMapping') as FormArray);
|
||||||
for (let j = 0; j < fieldMappingFormArray.length; j++) {
|
for (let j = 0; j < fieldMappingFormArray.length; j++) {
|
||||||
|
@ -334,10 +333,10 @@ export class ReferenceTypeEditorComponent extends BaseEditor<ReferenceTypeEditor
|
||||||
this.sourceKeysMap.set(referenceType.id, sourceKeys);
|
this.sourceKeysMap.set(referenceType.id, sourceKeys);
|
||||||
})
|
})
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.router.navigate(['/reference-type']);
|
this.router.navigate(['/reference-type']);
|
||||||
this.httpErrorHandlingService.handleBackedRequestError(error);
|
this.httpErrorHandlingService.handleBackedRequestError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
selectedReferenceTypeChanged(id: Guid): void {
|
selectedReferenceTypeChanged(id: Guid): void {
|
||||||
|
|
|
@ -1,21 +1,24 @@
|
||||||
|
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { FormArray, UntypedFormGroup } from '@angular/forms';
|
import { FormArray, UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
|
import { Title } from '@angular/platform-browser';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
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 { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
|
import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type';
|
||||||
import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type';
|
import { ReferenceSourceType } from '@app/core/common/enum/reference-source-type';
|
||||||
import { Reference, ReferencePersist } from '@app/core/model/reference/reference';
|
import { Reference, ReferencePersist } from '@app/core/model/reference/reference';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
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 { 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 { 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 { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||||
import { BaseEditor } from '@common/base/base-editor';
|
import { BaseEditor } from '@common/base/base-editor';
|
||||||
|
@ -29,10 +32,6 @@ import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { ReferenceEditorModel } from './reference-editor.model';
|
import { ReferenceEditorModel } from './reference-editor.model';
|
||||||
import { ReferenceEditorResolver } from './reference-editor.resolver';
|
import { ReferenceEditorResolver } from './reference-editor.resolver';
|
||||||
import { ReferenceEditorService } from './reference-editor.service';
|
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({
|
@Component({
|
||||||
|
@ -92,8 +91,8 @@ export class ReferenceEditorComponent extends BaseEditor<ReferenceEditorModel, R
|
||||||
public titleService: Title,
|
public titleService: Title,
|
||||||
private analyticsService: AnalyticsService
|
private analyticsService: AnalyticsService
|
||||||
) {
|
) {
|
||||||
|
|
||||||
const descriptionLabel:string = route.snapshot.data['entity']?.label;
|
const descriptionLabel: string = route.snapshot.data['entity']?.label;
|
||||||
if (descriptionLabel) {
|
if (descriptionLabel) {
|
||||||
titleService.setTitle(descriptionLabel);
|
titleService.setTitle(descriptionLabel);
|
||||||
} else {
|
} else {
|
||||||
|
|
|
@ -1,34 +1,32 @@
|
||||||
|
|
||||||
|
import { HttpErrorResponse } from '@angular/common/http';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
|
||||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
|
import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type';
|
||||||
|
import { CultureInfo } from '@app/core/model/culture-info';
|
||||||
|
import { TenantConfiguration, TenantConfigurationPersist } from '@app/core/model/tenant-configuaration/tenant-configuration';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
|
import { CultureService } from '@app/core/services/culture/culture-service';
|
||||||
|
import { DefaultUserLocaleService } from '@app/core/services/default-user-locale/default-user-locale.service';
|
||||||
|
import { LanguageService } from '@app/core/services/language/language.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 { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service';
|
||||||
|
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
||||||
|
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
||||||
import { FormService } from '@common/forms/form-service';
|
import { FormService } from '@common/forms/form-service';
|
||||||
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
|
import moment from 'moment';
|
||||||
|
import { Observable } from 'rxjs';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { TenantConfigurationEditorModel } from './default-user-locale-editor.model';
|
import { TenantConfigurationEditorModel } from './default-user-locale-editor.model';
|
||||||
import { TenantConfiguration, TenantConfigurationPersist } from '@app/core/model/tenant-configuaration/tenant-configuration';
|
|
||||||
import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.service';
|
|
||||||
import { DefaultUserLocaleEditorService } from './default-user-locale-editor.service';
|
|
||||||
import { DefaultUserLocaleEditorResolver } from './default-user-locale-editor.resolver';
|
import { DefaultUserLocaleEditorResolver } from './default-user-locale-editor.resolver';
|
||||||
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
import { DefaultUserLocaleEditorService } from './default-user-locale-editor.service';
|
||||||
import { Observable, of } from 'rxjs';
|
|
||||||
import { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type';
|
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
import { ResponseErrorCode } from '@app/core/common/enum/respone-error-code';
|
|
||||||
import { LoggingService } from '@app/core/services/logging/logging-service';
|
|
||||||
import { CultureInfo } from '@app/core/model/culture-info';
|
|
||||||
import moment from 'moment';
|
|
||||||
import { CultureService } from '@app/core/services/culture/culture-service';
|
|
||||||
import { LanguageService } from '@app/core/services/language/language.service';
|
|
||||||
import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration';
|
|
||||||
import { DefaultUserLocaleService } from '@app/core/services/default-user-locale/default-user-locale.service';
|
|
||||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-service';
|
|
||||||
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -93,7 +91,7 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen
|
||||||
ngOnInit(): void {
|
ngOnInit(): void {
|
||||||
this.singleTimezoneAutocompleteConfiguration = this.defaultUserLocaleService.singleTimezoneAutocompleteConfiguration;
|
this.singleTimezoneAutocompleteConfiguration = this.defaultUserLocaleService.singleTimezoneAutocompleteConfiguration;
|
||||||
this.singleCultureAutocompleteConfiguration = this.defaultUserLocaleService.singleCultureAutocompleteConfiguration;
|
this.singleCultureAutocompleteConfiguration = this.defaultUserLocaleService.singleCultureAutocompleteConfiguration;
|
||||||
|
|
||||||
this.analyticsService.trackPageView(AnalyticsService.TenantConfigurationsUserLocaleEditor);
|
this.analyticsService.trackPageView(AnalyticsService.TenantConfigurationsUserLocaleEditor);
|
||||||
|
|
||||||
this.getItem((entity) => {
|
this.getItem((entity) => {
|
||||||
|
@ -115,16 +113,16 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen
|
||||||
|
|
||||||
onCallbackError(errorResponse: HttpErrorResponse) {
|
onCallbackError(errorResponse: HttpErrorResponse) {
|
||||||
console.log("Error:", errorResponse);
|
console.log("Error:", errorResponse);
|
||||||
|
|
||||||
this.httpErrorHandlingService.handleBackedRequestError(errorResponse)
|
this.httpErrorHandlingService.handleBackedRequestError(errorResponse)
|
||||||
|
|
||||||
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
||||||
if (error.statusCode === 400) {
|
if (error.statusCode === 400) {
|
||||||
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
||||||
this.formService.validateAllFormFields(this.formGroup);
|
this.formService.validateAllFormFields(this.formGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onCallbackSuccess(data?: any): void {
|
onCallbackSuccess(data?: any): void {
|
||||||
|
|
||||||
console.log("Success:", data);
|
console.log("Success:", data);
|
||||||
|
@ -225,7 +223,7 @@ export class DefaultUserLocaleEditorComponent extends BasePendingChangesComponen
|
||||||
|
|
||||||
if (culture == null
|
if (culture == null
|
||||||
|| culture.displayName == null
|
|| culture.displayName == null
|
||||||
|| culture.nativeName == null)
|
|| culture.nativeName == null)
|
||||||
return undefined;
|
return undefined;
|
||||||
|
|
||||||
return culture.displayName + '-' + culture.nativeName;
|
return culture.displayName + '-' + culture.nativeName;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
|
|
||||||
import { Component } from '@angular/core';
|
import { Component } from '@angular/core';
|
||||||
// import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item';
|
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,20 @@
|
||||||
|
|
||||||
|
import { DatePipe } from '@angular/common';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
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 { IsActive } from '@app/core/common/enum/is-active.enum';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { Tenant, TenantPersist } from '@app/core/model/tenant/tenant';
|
import { Tenant, TenantPersist } from '@app/core/model/tenant/tenant';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
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 { 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 { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||||
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
import { QueryParamsService } from '@app/core/services/utilities/query-params.service';
|
||||||
import { BaseEditor } from '@common/base/base-editor';
|
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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
|
import { TenantEditorModel } from './tenant-editor.model';
|
||||||
import { TenantEditorResolver } from './tenant-editor.resolver';
|
import { TenantEditorResolver } from './tenant-editor.resolver';
|
||||||
import { TenantEditorService } from './tenant-editor.service';
|
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({
|
@Component({
|
||||||
|
|
|
@ -159,11 +159,6 @@ export class AnnotationDialogComponent extends BaseComponent {
|
||||||
this.threads.add(element.threadId);
|
this.threads.add(element.threadId);
|
||||||
});
|
});
|
||||||
console.log(this.parentAnnotationsPerThread);
|
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),
|
error => this.onCallbackError(error),
|
||||||
);
|
);
|
||||||
|
|
|
@ -2,7 +2,7 @@ import { Injectable } from '@angular/core';
|
||||||
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router';
|
||||||
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||||
import { AppPermission } from '@app/core/common/enum/permission.enum';
|
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 { 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 { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||||
import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
import { Dmp, DmpDescriptionTemplate } from '@app/core/model/dmp/dmp';
|
||||||
|
@ -131,10 +131,7 @@ export class DescriptionEditorResolver extends BaseEditorResolver {
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.label)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.ordinal)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.id)].join('.'),
|
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.label)].join('.'),
|
|
||||||
// (prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.minMultiplicity)].join('.'),
|
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.maxMultiplicity)].join('.'),
|
||||||
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.prefillingSources), nameof<PrefillingSource>(x => x.id)].join('.'),
|
(prefix ? prefix + '.' : '') + [nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.prefillingSources), nameof<PrefillingSource>(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)));
|
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) {
|
} else if (dmpId != null && dmpSectionId != null && copyDmpId == null) {
|
||||||
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields())
|
return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields())
|
||||||
.pipe(tap(x => {
|
.pipe(tap(x => {
|
||||||
this.breadcrumbService.addIdResolvedValue(`${x.id}/${dmpSectionId}`, this.language.instant("DESCRIPTION-EDITOR.TITLE-NEW"));
|
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 = {};
|
const description: Description = {};
|
||||||
description.dmp = dmp;
|
description.dmp = dmp;
|
||||||
description.dmpDescriptionTemplate = {
|
description.dmpDescriptionTemplate = {
|
||||||
sectionId: Guid.parse(dmpSectionId)
|
sectionId: Guid.parse(dmpSectionId)
|
||||||
}
|
}
|
||||||
return description;
|
return description;
|
||||||
}));
|
}));
|
||||||
} else if (copyDmpId != null && id != null && dmpSectionId != null) {
|
} 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.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 => {
|
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));
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,10 @@
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { RouterModule, Routes } from '@angular/router';
|
import { RouterModule, Routes } from '@angular/router';
|
||||||
// import { DescriptionWizardComponent } from './description-wizard/description-wizard.component';
|
import { AuthGuard } from '@app/core/auth-guard.service';
|
||||||
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 { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.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 { DescriptionEditorComponent } from './description-editor.component';
|
||||||
import { DescriptionEditorResolver } from './description-editor.resolver';
|
import { DescriptionEditorResolver } from './description-editor.resolver';
|
||||||
import { AuthGuard } from '@app/core/auth-guard.service';
|
|
||||||
|
|
||||||
const routes: Routes = [
|
const routes: Routes = [
|
||||||
{
|
{
|
||||||
|
@ -22,11 +19,7 @@ const routes: Routes = [
|
||||||
breadcrumbs: true,
|
breadcrumbs: true,
|
||||||
getFromTitleService: true,
|
getFromTitleService: true,
|
||||||
usePrefix: false
|
usePrefix: false
|
||||||
//title: 'DESCRIPTION-EDITOR.TITLE-EDIT-DESCRIPTION'
|
|
||||||
// ,
|
|
||||||
// authContext: {
|
|
||||||
// permissions: [AppPermission.EditDescription]
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -43,10 +36,6 @@ const routes: Routes = [
|
||||||
hideNavigationItem: true
|
hideNavigationItem: true
|
||||||
}),
|
}),
|
||||||
title: 'DESCRIPTION-EDITOR.TITLE-EDIT-DESCRIPTION',
|
title: 'DESCRIPTION-EDITOR.TITLE-EDIT-DESCRIPTION',
|
||||||
// ,
|
|
||||||
// authContext: {
|
|
||||||
// permissions: [AppPermission.EditDescription]
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -62,10 +51,6 @@ const routes: Routes = [
|
||||||
title: 'DESCRIPTION-EDITOR.TITLE-NEW',
|
title: 'DESCRIPTION-EDITOR.TITLE-NEW',
|
||||||
getFromTitleService: true,
|
getFromTitleService: true,
|
||||||
usePrefix: false
|
usePrefix: false
|
||||||
// ,
|
|
||||||
// authContext: {
|
|
||||||
// permissions: [AppPermission.EditDescription]
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -81,66 +66,8 @@ const routes: Routes = [
|
||||||
title: 'DESCRIPTION-EDITOR.TITLE-NEW',
|
title: 'DESCRIPTION-EDITOR.TITLE-NEW',
|
||||||
getFromTitleService: true,
|
getFromTitleService: true,
|
||||||
usePrefix: false
|
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({
|
@NgModule({
|
||||||
|
|
|
@ -35,18 +35,10 @@ export class DescriptionFormFieldSetComponent extends BaseComponent {
|
||||||
return this.fieldSet.hasMultiplicity && this.fieldSet.multiplicity != null;
|
return this.fieldSet.hasMultiplicity && this.fieldSet.multiplicity != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
isVisibleByVisibilityService: boolean = true;
|
isVisibleByVisibilityService: boolean = true;
|
||||||
@Input() visibilityRulesService: VisibilityRulesService;
|
@Input() visibilityRulesService: VisibilityRulesService;
|
||||||
@Input() path: String;
|
@Input() path: String;
|
||||||
|
|
||||||
|
|
||||||
@Input() datasetProfileId: String;
|
@Input() datasetProfileId: String;
|
||||||
// @Input() form: UntypedFormGroup;
|
|
||||||
@Input() isChild: Boolean = false;
|
@Input() isChild: Boolean = false;
|
||||||
@Input() showDelete: Boolean = false;
|
@Input() showDelete: Boolean = false;
|
||||||
@Input() tocentry: ToCEntry;
|
@Input() tocentry: ToCEntry;
|
||||||
|
|
|
@ -190,11 +190,6 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O
|
||||||
) {
|
) {
|
||||||
setTimeout(() => this.refreshCallback(true));
|
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<ExternalSourceItemModel[]> {
|
filterTags(value: string): Observable<ExternalSourceItemModel[]> {
|
||||||
|
@ -225,12 +220,6 @@ export class DatasetCriteriaComponent extends BaseCriteriaComponent implements O
|
||||||
const fields: Array<string> = new Array<string>();
|
const fields: Array<string> = new Array<string>();
|
||||||
fields.push('asc');
|
fields.push('asc');
|
||||||
|
|
||||||
// if (this.isPublic) {
|
|
||||||
// const dmpDataTableRequest: DataTableRequest<ExploreDmpCriteriaModel> = new DataTableRequest(0, null, { fields: fields });
|
|
||||||
// dmpDataTableRequest.criteria = new ExploreDmpCriteriaModel();
|
|
||||||
// dmpDataTableRequest.criteria.like = value;
|
|
||||||
// return this.dmpService.getPublicPaged(dmpDataTableRequest, "autocomplete");
|
|
||||||
// } else {
|
|
||||||
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
|
const dmpDataTableRequest: DataTableRequest<DmpCriteria> = new DataTableRequest(0, null, { fields: fields });
|
||||||
dmpDataTableRequest.criteria = new DmpCriteria();
|
dmpDataTableRequest.criteria = new DmpCriteria();
|
||||||
dmpDataTableRequest.criteria.like = value;
|
dmpDataTableRequest.criteria.like = value;
|
||||||
|
|
|
@ -12,6 +12,7 @@ import { AppPermission } from '@app/core/common/enum/permission.enum';
|
||||||
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
||||||
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
import { DescriptionTemplate } from '@app/core/model/description-template/description-template';
|
||||||
import { Description } from '@app/core/model/description/description';
|
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 { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp';
|
||||||
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
|
import { DmpReference } from '@app/core/model/dmp/dmp-reference';
|
||||||
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
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 { DmpLookup } from '@app/core/query/dmp.lookup';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
import { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
import { DescriptionService } from '@app/core/services/description/description.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 { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
|
import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants';
|
||||||
import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service';
|
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 { 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 { 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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
import { StartNewDescriptionDialogComponent } from '../start-new-description-dialog/start-new-description-dialog.component';
|
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({
|
@Component({
|
||||||
selector: 'app-description-listing-component',
|
selector: 'app-description-listing-component',
|
||||||
templateUrl: 'description-listing.component.html',
|
templateUrl: 'description-listing.component.html',
|
||||||
styleUrls: ['./description-listing.component.scss']
|
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(MatPaginator, { static: true }) _paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
// @ViewChild(DescriptionCriteriaComponent, { static: true }) criteria: DescriptionCriteriaComponent;
|
|
||||||
|
|
||||||
// breadCrumbs: Observable<BreadcrumbItem[]>;
|
|
||||||
|
|
||||||
titlePrefix: String;
|
titlePrefix: String;
|
||||||
dmpId: string;
|
dmpId: string;
|
||||||
|
@ -202,12 +196,12 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
|
||||||
this.refresh(this.lookup);
|
this.refresh(this.lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
orderByChanged(){
|
orderByChanged() {
|
||||||
if (this.formGroup.get('order').value == RecentActivityOrder.Status){
|
if (this.formGroup.get('order').value == RecentActivityOrder.Status) {
|
||||||
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.status)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(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<Dmp>(x => x.label)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.label)] };
|
||||||
}else{
|
} else {
|
||||||
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.updatedAt)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.updatedAt)] };
|
||||||
}
|
}
|
||||||
this.refresh(this.lookup);
|
this.refresh(this.lookup);
|
||||||
|
@ -256,96 +250,35 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
|
||||||
[nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
[nameof<Description>(x => x.dmpDescriptionTemplate), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
if(this.isPublic){
|
if (this.isPublic) {
|
||||||
this.descriptionService.publicQuery(lookup).pipe(takeUntil(this._destroyed))
|
this.descriptionService.publicQuery(lookup).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(result => {
|
.subscribe(result => {
|
||||||
if (!result) { return []; }
|
if (!result) { return []; }
|
||||||
this.totalCount = result.count;
|
this.totalCount = result.count;
|
||||||
if (lookup?.page?.offset === 0) this.listingItems = [];
|
if (lookup?.page?.offset === 0) this.listingItems = [];
|
||||||
this.listingItems.push(...result.items);
|
this.listingItems.push(...result.items);
|
||||||
this.hasListingItems = true;
|
this.hasListingItems = true;
|
||||||
},
|
},
|
||||||
(error) => this.httpErrorHandlingService.handleBackedRequestError(error));
|
(error) => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}else{
|
} else {
|
||||||
this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed))
|
this.descriptionService.query(lookup).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(result => {
|
.subscribe(result => {
|
||||||
if (!result) { return []; }
|
if (!result) { return []; }
|
||||||
this.totalCount = result.count;
|
this.totalCount = result.count;
|
||||||
if (lookup?.page?.offset === 0) this.listingItems = [];
|
if (lookup?.page?.offset === 0) this.listingItems = [];
|
||||||
result.items.forEach(description => {
|
result.items.forEach(description => {
|
||||||
if (description.status != DescriptionStatus.Canceled) this.listingItems.push(description);
|
if (description.status != DescriptionStatus.Canceled) this.listingItems.push(description);
|
||||||
})
|
})
|
||||||
this.hasListingItems = true;
|
this.hasListingItems = true;
|
||||||
},
|
},
|
||||||
(error) => this.httpErrorHandlingService.handleBackedRequestError(error));
|
(error) => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
openFiltersDialog(): void {
|
openFiltersDialog(): void {
|
||||||
//TODO: Add filters dialog
|
//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 => (<ExternalTagEditorModel>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 {
|
hasScrollbar(): boolean {
|
||||||
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
||||||
|
@ -360,16 +293,16 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
|
||||||
|
|
||||||
public setDashboardTourDmpText(): void {
|
public setDashboardTourDmpText(): void {
|
||||||
this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
this.dmpText = this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' +
|
||||||
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||||
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
|
this.language.instant('DMP-LISTING.LINK-ZENODO') + ' ' +
|
||||||
this.language.instant('DMP-LISTING.GET-IDEA');
|
this.language.instant('DMP-LISTING.GET-IDEA');
|
||||||
this.dashboardTour.steps[0].title = this.dmpText;
|
this.dashboardTour.steps[0].title = this.dmpText;
|
||||||
}
|
}
|
||||||
|
|
||||||
public setDashboardTourDescriptionText(): void {
|
public setDashboardTourDescriptionText(): void {
|
||||||
this.descriptionText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' +
|
this.descriptionText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' +
|
||||||
this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||||
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
||||||
this.dashboardTour.steps[1].title = this.descriptionText;
|
this.dashboardTour.steps[1].title = this.descriptionText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -416,7 +349,7 @@ export class DescriptionListingComponent extends BaseComponent implements OnInit
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSortDirection(): void {
|
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();
|
this.orderByChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
|
||||||
import { Location } from '@angular/common';
|
import { Location } from '@angular/common';
|
||||||
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { UntypedFormBuilder, Validators } from '@angular/forms';
|
import { UntypedFormBuilder, Validators } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
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 { DmpReference } from '@app/core/model/dmp/dmp-reference';
|
||||||
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
||||||
import { Reference } from '@app/core/model/reference/reference';
|
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 { AuthService } from '@app/core/services/auth/auth.service';
|
||||||
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
import { DescriptionService } from '@app/core/services/description/description.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 { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service';
|
||||||
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
||||||
import { ReferenceService } from '@app/core/services/reference/reference.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 { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||||
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
||||||
import { DescriptionValidationOutput } from '@app/ui/dmp/dmp-finalize-dialog/dmp-finalize-dialog.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 { 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 { 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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
import { map, takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
import { DescriptionCopyDialogComponent } from '../description-copy-dialog/description-copy-dialog.component';
|
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({
|
@Component({
|
||||||
|
@ -59,7 +58,6 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
||||||
isFinalized = false;
|
isFinalized = false;
|
||||||
isPublicView = true;
|
isPublicView = true;
|
||||||
hasPublishButton: boolean = true;
|
hasPublishButton: boolean = true;
|
||||||
// breadCrumbs: Observable<BreadcrumbItem[]> = observableOf();
|
|
||||||
expand = false;
|
expand = false;
|
||||||
isLocked: Boolean;
|
isLocked: Boolean;
|
||||||
descriptionStatusEnum = DescriptionStatus;
|
descriptionStatusEnum = DescriptionStatus;
|
||||||
|
@ -189,14 +187,14 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.isAuthenticated()) {
|
if (this.isAuthenticated()) {
|
||||||
this.userService.getSingle(this.authentication.userId(), [
|
this.userService.getSingle(this.authentication.userId(), [
|
||||||
nameof<User>(x => x.id),
|
nameof<User>(x => x.id),
|
||||||
nameof<User>(x => x.name)])
|
nameof<User>(x => x.name)])
|
||||||
.pipe(map(u => u.name)).subscribe(name => this.userName = name);
|
.pipe(map(u => u.name)).subscribe(name => this.userName = name);
|
||||||
} else {
|
} else {
|
||||||
this.userName = '';
|
this.userName = '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get unauthorizedTootipText(): string {
|
get unauthorizedTootipText(): string {
|
||||||
|
@ -216,10 +214,10 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.router.navigate(['/descriptions']);
|
this.router.navigate(['/descriptions']);
|
||||||
this.httpErrorHandlingService.handleBackedRequestError(error);
|
this.httpErrorHandlingService.handleBackedRequestError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
onFetchingDeletedCallbackError(redirectRoot: string) {
|
onFetchingDeletedCallbackError(redirectRoot: string) {
|
||||||
|
@ -417,39 +415,39 @@ export class DescriptionOverviewComponent extends BaseComponent implements OnIni
|
||||||
finalize(description: Description) {
|
finalize(description: Description) {
|
||||||
|
|
||||||
this.descriptionService.validate([description.id]).pipe(takeUntil(this._destroyed))
|
this.descriptionService.validate([description.id]).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(result => {
|
.subscribe(result => {
|
||||||
if (result[0].result == DescriptionValidationOutput.Invalid) {
|
if (result[0].result == DescriptionValidationOutput.Invalid) {
|
||||||
this.router.navigate(['descriptions/edit/' + description.id + '/finalize']);
|
this.router.navigate(['descriptions/edit/' + description.id + '/finalize']);
|
||||||
} else {
|
} else {
|
||||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||||
restoreFocus: false,
|
restoreFocus: false,
|
||||||
data: {
|
data: {
|
||||||
message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'),
|
message: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.TITLE'),
|
||||||
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'),
|
confirmButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.CONFIRM'),
|
||||||
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'),
|
cancelButton: this.language.instant('DESCRIPTION-OVERVIEW.FINALIZE-DIALOG.NEGATIVE'),
|
||||||
isDeleteConfirmation: false
|
isDeleteConfirmation: false
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => {
|
||||||
if (result) {
|
if (result) {
|
||||||
const descriptionStatusPersist: DescriptionStatusPersist = {
|
const descriptionStatusPersist: DescriptionStatusPersist = {
|
||||||
id: description.id,
|
id: description.id,
|
||||||
status: DescriptionStatus.Finalized,
|
status: DescriptionStatus.Finalized,
|
||||||
hash: description.hash
|
hash: description.hash
|
||||||
};
|
};
|
||||||
this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed))
|
this.descriptionService.persistStatus(descriptionStatusPersist).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(data => {
|
.subscribe(data => {
|
||||||
this.reloadPage();
|
this.reloadPage();
|
||||||
this.onUpdateCallbackSuccess()
|
this.onUpdateCallbackSuccess()
|
||||||
}, (error: any) => {
|
}, (error: any) => {
|
||||||
this.onUpdateCallbackError(error)
|
this.onUpdateCallbackError(error)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
|
}
|
||||||
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
}
|
|
||||||
},
|
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
hasReversableStatus(description: Description): boolean {
|
hasReversableStatus(description: Description): boolean {
|
||||||
|
|
|
@ -317,11 +317,6 @@ export class DmpEditorComponent extends BaseEditor<DmpEditorModel, Dmp> implemen
|
||||||
|
|
||||||
formSubmit(): void {
|
formSubmit(): void {
|
||||||
this.formService.removeAllBackEndErrors(this.formGroup);
|
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();
|
this.persistEntity();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -53,9 +53,6 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
||||||
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.email)].join('.'),
|
[nameof<Dmp>(x => x.properties), nameof<DmpProperties>(x => x.contacts), nameof<DmpContact>(x => x.email)].join('.'),
|
||||||
|
|
||||||
|
|
||||||
// [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.id)].join('.'),
|
|
||||||
// [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.repositoryId)].join('.'),
|
|
||||||
// [nameof<Dmp>(x => x.entityDois), nameof<EntityDoi>(x => x.doi)].join('.'),
|
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.id)].join('.'),
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.label)].join('.'),
|
||||||
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
|
[nameof<Dmp>(x => x.descriptions), nameof<Description>(x => x.status)].join('.'),
|
||||||
|
@ -88,11 +85,6 @@ export class DmpEditorResolver extends BaseEditorResolver {
|
||||||
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
||||||
|
|
||||||
|
|
||||||
// nameof<Dmp>(x => x.id),
|
|
||||||
// nameof<Dmp>(x => x.label),
|
|
||||||
// nameof<Dmp>(x => x.status),
|
|
||||||
// nameof<Dmp>(x => x.description),
|
|
||||||
// nameof<Dmp>(x => x.status),
|
|
||||||
...DmpEditorResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
|
...DmpEditorResolver.blueprintLookupFields(nameof<Dmp>(x => x.blueprint)),
|
||||||
|
|
||||||
]
|
]
|
||||||
|
|
|
@ -1,33 +0,0 @@
|
||||||
<div class="main-info" [formGroup]="formGroup">
|
|
||||||
<div class="col-12 intro">
|
|
||||||
<p>{{'DMP-EDITOR.DATASET-INFO.SECOND-INTRO' | translate}}</p>
|
|
||||||
</div>
|
|
||||||
<div class="col-12 card">
|
|
||||||
<div class="row">
|
|
||||||
<div class="col-12">
|
|
||||||
<div class="heading">4.1 {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}}*</div>
|
|
||||||
<div class="hint">
|
|
||||||
<div class="pb-1">{{'DMP-EDITOR.DATASET-INFO.HINT' | translate}}</div>
|
|
||||||
<div><span class="material-icons-outlined align-bottom">info</span> {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}</div>
|
|
||||||
</div>
|
|
||||||
<div class="profile-form">
|
|
||||||
<mat-form-field>
|
|
||||||
<mat-label>{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}</mat-label>
|
|
||||||
<app-multiple-auto-complete placeholder="{{'DMP-EDITOR.FIELDS.SELECT-TEMPLATE' | translate}}" required='true' [formControl]="formGroup.get('profiles')" [configuration]="profilesAutoCompleteConfiguration" (optionRemoved)="onRemoveTemplate($event)" (optionActionClicked)="onPreviewTemplate($event)" (optionSelected)="onOptionSelected()">
|
|
||||||
</app-multiple-auto-complete>
|
|
||||||
<mat-error *ngIf="formGroup.get('profiles').hasError('backendError')">
|
|
||||||
{{formGroup.get('profiles').getError('backendError').message}}</mat-error>
|
|
||||||
<mat-error *ngIf="formGroup.get('profiles').hasError('required')">
|
|
||||||
{{'GENERAL.VALIDATION.REQUIRED' | translate}}</mat-error>
|
|
||||||
<button matSuffix class="input-btn" [disabled]="formGroup.get('profiles').disabled" (click)="allAvailableProfiles($event)">
|
|
||||||
<mat-icon class="icon-btn">view_list</mat-icon>
|
|
||||||
</button>
|
|
||||||
</mat-form-field>
|
|
||||||
</div>
|
|
||||||
<div class="col pl-0 pt-2 pb-3 d-flex">
|
|
||||||
<span class="not-found">{{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.SECOND-STEP.FIELDS.HELP' | translate}}</span>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
|
@ -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;
|
|
||||||
}
|
|
|
@ -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<any> = 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<DatasetProfileModel[]> {
|
|
||||||
const request = new DataTableRequest<DatasetProfileCriteria>(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<DatasetProfileCriteria> = 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<String, number> = new Map<String, number>();
|
|
||||||
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')
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,43 +6,41 @@ import { MatDialog } from '@angular/material/dialog';
|
||||||
import { MatPaginator } from '@angular/material/paginator';
|
import { MatPaginator } from '@angular/material/paginator';
|
||||||
import { MatSort } from '@angular/material/sort';
|
import { MatSort } from '@angular/material/sort';
|
||||||
import { ActivatedRoute, Router } from '@angular/router';
|
import { ActivatedRoute, Router } from '@angular/router';
|
||||||
import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order';
|
import { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||||
import { AuthService } from '@app/core/services/auth/auth.service';
|
import { DmpStatus } from '@app/core/common/enum/dmp-status';
|
||||||
import { DmpService } from '@app/core/services/dmp/dmp.service';
|
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
|
||||||
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 { IsActive } from '@app/core/common/enum/is-active.enum';
|
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 { Description } from '@app/core/model/description/description';
|
||||||
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, DmpBlueprintDefinitionSection } from '@app/core/model/dmp-blueprint/dmp-blueprint';
|
||||||
import { Dmp, DmpDescriptionTemplate, DmpUser } from '@app/core/model/dmp/dmp';
|
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 { 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 { 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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { NgDialogAnimationService } from "ng-dialog-animation";
|
import { NgDialogAnimationService } from "ng-dialog-animation";
|
||||||
import { debounceTime, takeUntil } from 'rxjs/operators';
|
import { debounceTime, takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
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({
|
@Component({
|
||||||
selector: 'app-dmp-listing-component',
|
selector: 'app-dmp-listing-component',
|
||||||
templateUrl: 'dmp-listing.component.html',
|
templateUrl: 'dmp-listing.component.html',
|
||||||
styleUrls: ['./dmp-listing.component.scss'],
|
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(MatPaginator, { static: true }) _paginator: MatPaginator;
|
||||||
@ViewChild(MatSort) sort: MatSort;
|
@ViewChild(MatSort) sort: MatSort;
|
||||||
|
@ -174,8 +172,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
this.language.instant('DMP-LISTING.GET-IDEA');
|
this.language.instant('DMP-LISTING.GET-IDEA');
|
||||||
|
|
||||||
this.dashboardTour.steps[1].title = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' +
|
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.TEXT-INFO-QUESTION') + ' ' +
|
||||||
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
||||||
|
|
||||||
this.guidedTourService.startTour(this.dashboardTour);
|
this.guidedTourService.startTour(this.dashboardTour);
|
||||||
});
|
});
|
||||||
|
@ -186,12 +184,12 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
this.refresh(this.lookup);
|
this.refresh(this.lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
orderByChanged(){
|
orderByChanged() {
|
||||||
if (this.formGroup.get('order').value == RecentActivityOrder.Status){
|
if (this.formGroup.get('order').value == RecentActivityOrder.Status) {
|
||||||
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.status)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(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<Dmp>(x => x.label)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.label)] };
|
||||||
}else{
|
} else {
|
||||||
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.updatedAt)] };
|
this.lookup.order = { items: [this.sortingDirectionPrefix + nameof<Dmp>(x => x.updatedAt)] };
|
||||||
}
|
}
|
||||||
this.refresh(this.lookup);
|
this.refresh(this.lookup);
|
||||||
|
@ -234,10 +232,6 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.hasTemplates)].join('.'),
|
||||||
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
[nameof<Dmp>(x => x.blueprint), nameof<DmpBlueprint>(x => x.definition), nameof<DmpBlueprintDefinition>(x => x.sections), nameof<DmpBlueprintDefinitionSection>(x => x.descriptionTemplates), nameof<DescriptionTemplatesInSection>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
|
|
||||||
// [nameof<Description>(x => x.descriptionTemplate), nameof<DescriptionTemplate>(x => x.label)].join('.'),
|
|
||||||
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.id)].join('.'),
|
|
||||||
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.label)].join('.'),
|
|
||||||
// [nameof<Description>(x => x.dmp), nameof<Dmp>(x => x.accessType)].join('.'),
|
|
||||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
|
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.id)].join('.'),
|
||||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
|
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.user.id)].join('.'),
|
||||||
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
|
[nameof<Dmp>(x => x.dmpUsers), nameof<DmpUser>(x => x.role)].join('.'),
|
||||||
|
@ -253,43 +247,41 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.sectionId)].join('.'),
|
||||||
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.descriptionTemplateGroupId)].join('.'),
|
||||||
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
[nameof<Dmp>(x => x.dmpDescriptionTemplates), nameof<DmpDescriptionTemplate>(x => x.isActive)].join('.'),
|
||||||
|
|
||||||
// [nameof<Dmp>(x => x.dmpReferences), nameof<DmpReference>(x => x.reference), nameof<Reference>(x => x.reference)].join('.'),
|
|
||||||
]
|
]
|
||||||
};
|
};
|
||||||
|
|
||||||
if(this.isPublic){
|
if (this.isPublic) {
|
||||||
this.dmpService.publicQuery(lookup).pipe(takeUntil(this._destroyed))
|
this.dmpService.publicQuery(lookup).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(result => {
|
.subscribe(result => {
|
||||||
if (!result) { return []; }
|
if (!result) { return []; }
|
||||||
this.totalCount = result.count;
|
this.totalCount = result.count;
|
||||||
if (lookup?.page?.offset === 0) this.listingItems = [];
|
if (lookup?.page?.offset === 0) this.listingItems = [];
|
||||||
this.listingItems.push(...result.items);
|
this.listingItems.push(...result.items);
|
||||||
this.hasListingItems = true;
|
this.hasListingItems = true;
|
||||||
},
|
},
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
|
|
||||||
}else{
|
} else {
|
||||||
this.dmpService.query(lookup).pipe(takeUntil(this._destroyed))
|
this.dmpService.query(lookup).pipe(takeUntil(this._destroyed))
|
||||||
.subscribe(result => {
|
.subscribe(result => {
|
||||||
if (!result) { return []; }
|
if (!result) { return []; }
|
||||||
this.totalCount = result.count;
|
this.totalCount = result.count;
|
||||||
if (lookup?.page?.offset === 0) this.listingItems = [];
|
if (lookup?.page?.offset === 0) this.listingItems = [];
|
||||||
result.items.forEach(x=> {
|
result.items.forEach(x => {
|
||||||
if (x.descriptions) {
|
if (x.descriptions) {
|
||||||
if (x.status == DmpStatus.Finalized) {
|
if (x.status == DmpStatus.Finalized) {
|
||||||
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status === DescriptionStatus.Finalized);
|
||||||
} else {
|
} else {
|
||||||
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
x.descriptions = x.descriptions.filter(x => x.isActive === IsActive.Active && x.status !== DescriptionStatus.Canceled);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
x.dmpUsers = x.dmpUsers.filter(x => x.isActive === IsActive.Active);
|
||||||
x.dmpUsers = x.dmpUsers.filter(x=> x.isActive === IsActive.Active);
|
this.listingItems.push(x);
|
||||||
this.listingItems.push(x);
|
})
|
||||||
})
|
this.hasListingItems = true;
|
||||||
// this.listingItems.push(...result.items);
|
},
|
||||||
this.hasListingItems = true;
|
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
||||||
},
|
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -303,92 +295,12 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
|
|
||||||
openShareDialog(rowId: any, rowName: any) {
|
openShareDialog(rowId: any, rowName: any) {
|
||||||
//TODO: add this
|
//TODO: add this
|
||||||
// const dialogRef = this.dialog.open(DmpInvitationDialogComponent, {
|
|
||||||
// autoFocus: false,
|
|
||||||
// data: {
|
|
||||||
// dmpId: rowId,
|
|
||||||
// dmpName: rowName
|
|
||||||
// }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
openFiltersDialog(): void {
|
openFiltersDialog(): void {
|
||||||
//TODO: Add filters dialog
|
//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 {
|
hasScrollbar(): boolean {
|
||||||
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
return document.getElementById("main-page").scrollHeight > document.documentElement.clientHeight
|
||||||
}
|
}
|
||||||
|
@ -403,8 +315,8 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
|
|
||||||
public setDashboardTourDatasetText(): void {
|
public setDashboardTourDatasetText(): void {
|
||||||
const datasetText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' +
|
const datasetText = this.language.instant('DESCRIPTION-LISTING.TEXT-INFO') + '\n\n' +
|
||||||
this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
this.language.instant('DESCRIPTION-LISTING.TEXT-INFO-QUESTION') + ' ' +
|
||||||
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
this.language.instant('DESCRIPTION-LISTING.GET-IDEA');
|
||||||
this.dashboardTour.steps[1].title = datasetText;
|
this.dashboardTour.steps[1].title = datasetText;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,7 +331,7 @@ export class DmpListingComponent extends BaseComponent implements OnInit { //IBr
|
||||||
}
|
}
|
||||||
|
|
||||||
toggleSortDirection(): void {
|
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();
|
this.orderByChanged();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,18 +1,10 @@
|
||||||
|
import { Location } from '@angular/common';
|
||||||
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
import { Component, ElementRef, OnInit, ViewChild } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, Params, Router } from '@angular/router';
|
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 { DescriptionStatus } from '@app/core/common/enum/description-status';
|
||||||
import { DmpAccessType } from '@app/core/common/enum/dmp-access-type';
|
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 { DmpUserRole } from '@app/core/common/enum/dmp-user-role';
|
||||||
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
|
import { DmpVersionStatus } from '@app/core/common/enum/dmp-version-status';
|
||||||
import { FileTransformerEntityType } from '@app/core/common/enum/file-transformer-entity-type';
|
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 { EntityDoi } from '@app/core/model/entity-doi/entity-doi';
|
||||||
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
import { ReferenceType } from '@app/core/model/reference-type/reference-type';
|
||||||
import { Reference } from '@app/core/model/reference/reference';
|
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 { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
import { DepositService } from '@app/core/services/deposit/deposit.service';
|
import { DepositService } from '@app/core/services/deposit/deposit.service';
|
||||||
import { DmpBlueprintService } from '@app/core/services/dmp/dmp-blueprint.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 { FileTransformerService } from '@app/core/services/file-transformer/file-transformer.service';
|
||||||
import { LockService } from '@app/core/services/lock/lock.service';
|
import { LockService } from '@app/core/services/lock/lock.service';
|
||||||
import { AnalyticsService } from '@app/core/services/matomo/analytics-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 { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service';
|
||||||
import { ReferenceService } from '@app/core/services/reference/reference.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 { EnumUtils } from '@app/core/services/utilities/enum-utils.service';
|
||||||
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
import { FileUtils } from '@app/core/services/utilities/file-utils.service';
|
||||||
import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component';
|
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 { 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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { map, takeUntil } from 'rxjs/operators';
|
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 { DmpFinalizeDialogComponent, DmpFinalizeDialogOutput } from '../dmp-finalize-dialog/dmp-finalize-dialog.component';
|
||||||
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
|
import { DmpInvitationDialogComponent } from '../invitation/dialog/dmp-invitation-dialog.component';
|
||||||
import { NewVersionDmpDialogComponent } from '../new-version-dialog/dmp-new-version-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({
|
@Component({
|
||||||
selector: 'app-dmp-overview',
|
selector: 'app-dmp-overview',
|
||||||
|
@ -70,8 +68,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
|
||||||
isFinalized = false;
|
isFinalized = false;
|
||||||
isPublicView = true;
|
isPublicView = true;
|
||||||
hasPublishButton: boolean = true;
|
hasPublishButton: boolean = true;
|
||||||
// breadCrumbs: Observable<BreadcrumbItem[]> = observableOf();
|
|
||||||
// isUserOwner: boolean;
|
|
||||||
isLocked: Boolean;
|
isLocked: Boolean;
|
||||||
textMessage: any;
|
textMessage: any;
|
||||||
selectedModel: EntityDoi;
|
selectedModel: EntityDoi;
|
||||||
|
@ -116,7 +112,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
|
||||||
) {
|
) {
|
||||||
super();
|
super();
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
ngOnInit() {
|
||||||
this.analyticsService.trackPageView(AnalyticsService.DmpOverview);
|
this.analyticsService.trackPageView(AnalyticsService.DmpOverview);
|
||||||
// Gets dmp data using parameter id
|
// Gets dmp data using parameter id
|
||||||
|
@ -210,10 +206,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
|
||||||
this.depositRepos = repos;
|
this.depositRepos = repos;
|
||||||
},
|
},
|
||||||
error => this.depositRepos = []);
|
error => this.depositRepos = []);
|
||||||
|
|
||||||
this.userService.getSingle(this.authentication.userId(), [
|
this.userService.getSingle(this.authentication.userId(), [
|
||||||
nameof<User>(x => x.id),
|
nameof<User>(x => x.id),
|
||||||
nameof<User>(x => x.name)])
|
nameof<User>(x => x.name)])
|
||||||
.pipe(map(u => u.name)).subscribe(name => this.userName = name);
|
.pipe(map(u => u.name)).subscribe(name => this.userName = name);
|
||||||
} else {
|
} else {
|
||||||
this.userName = '';
|
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() {
|
deleteClicked() {
|
||||||
let dialogRef: any;
|
let dialogRef: any;
|
||||||
if (this.dmp.descriptions && this.dmp.descriptions.length > 0) {
|
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<boolean> {
|
|
||||||
// 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 {
|
public isAuthenticated(): boolean {
|
||||||
return this.authentication.currentAccountIsAuthenticated();
|
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) {
|
removeUserFromDmp(dmpUser: DmpUser) {
|
||||||
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
const dialogRef = this.dialog.open(ConfirmationDialogComponent, {
|
||||||
data: {
|
data: {
|
||||||
|
@ -714,10 +584,10 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
this.router.navigate(['/plans']);
|
this.router.navigate(['/plans']);
|
||||||
this.httpErrorHandlingService.handleBackedRequestError(error);
|
this.httpErrorHandlingService.handleBackedRequestError(error);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private lookupFields(): string[] {
|
private lookupFields(): string[] {
|
||||||
|
|
|
@ -4,7 +4,6 @@ import { MatDialog, MatDialogRef } from '@angular/material/dialog';
|
||||||
import { MatMenuTrigger } from '@angular/material/menu';
|
import { MatMenuTrigger } from '@angular/material/menu';
|
||||||
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
import { DomSanitizer, SafeUrl } from '@angular/platform-browser';
|
||||||
import { Router } from '@angular/router';
|
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 { TenantConfigurationType } from '@app/core/common/enum/tenant-configuration-type';
|
||||||
import { StorageFile } from '@app/core/model/storage-file/storage-file';
|
import { StorageFile } from '@app/core/model/storage-file/storage-file';
|
||||||
import { LogoTenantConfiguration, TenantConfiguration } from '@app/core/model/tenant-configuaration/tenant-configuration';
|
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 { SideNavService } from '@app/core/services/sidenav/side-nav.sevice';
|
||||||
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
|
import { StorageFileService } from '@app/core/services/storage-file/storage-file.service';
|
||||||
import { TenantConfigurationService } from '@app/core/services/tenant-configuration/tenant-configuration.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 { BaseComponent } from '@common/base/base.component';
|
||||||
import { InAppNotificationService } from '@notification-service/services/http/inapp-notification.service';
|
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';
|
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 { StartNewDmpDialogComponent } from '../dmp/new/start-new-dmp-dialogue/start-new-dmp-dialog.component';
|
||||||
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
|
import { FaqDialogComponent } from '../faq/dialog/faq-dialog.component';
|
||||||
import { UserDialogComponent } from './user-dialog/user-dialog.component';
|
import { UserDialogComponent } from './user-dialog/user-dialog.component';
|
||||||
import { UserService } from '@app/core/services/user/user.service';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-navbar',
|
selector: 'app-navbar',
|
||||||
|
@ -230,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 {
|
public getCurrentLanguage(): any {
|
||||||
const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage());
|
const lang = this.languages.find(lang => lang.value === this.languageService.getCurrentLanguage());
|
||||||
return lang;
|
return lang;
|
||||||
|
@ -270,10 +254,6 @@ export class NavbarComponent extends BaseComponent implements OnInit {
|
||||||
(ev.target as HTMLImageElement).src = this.getDefaultAvatar();
|
(ev.target as HTMLImageElement).src = this.getDefaultAvatar();
|
||||||
}
|
}
|
||||||
|
|
||||||
public isAdmin(): boolean {
|
|
||||||
return this.authentication.hasRole(AppRole.Admin);
|
|
||||||
}
|
|
||||||
|
|
||||||
openProfile() {
|
openProfile() {
|
||||||
const dialogRef = this.dialog.open(UserDialogComponent, {
|
const dialogRef = this.dialog.open(UserDialogComponent, {
|
||||||
hasBackdrop: true,
|
hasBackdrop: true,
|
||||||
|
|
|
@ -113,13 +113,6 @@ export class ReferenceFieldComponent extends BaseComponent implements OnInit, On
|
||||||
} else {
|
} else {
|
||||||
this.referenceToUse = referenceToUse;
|
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) {
|
if (this.multiple) {
|
||||||
this.multipleAutoCompleteSearchConfiguration = this.referenceService.getMultipleAutoCompleteSearchConfiguration(this.referenceType.id, this.referenceToUse);
|
this.multipleAutoCompleteSearchConfiguration = this.referenceService.getMultipleAutoCompleteSearchConfiguration(this.referenceType.id, this.referenceToUse);
|
||||||
|
|
|
@ -3,14 +3,12 @@ import { HttpClient } from '@angular/common/http';
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { Router } from '@angular/router';
|
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 { TranslateService } from '@ngx-translate/core';
|
||||||
import { AppRole } from '../../core/common/enum/app-role';
|
import { AuthService } from '../../core/services/auth/auth.service';
|
||||||
import { AuthService, LoginStatus } from '../../core/services/auth/auth.service';
|
|
||||||
import { LanguageDialogComponent } from '../language/dialog/language-dialog.component';
|
import { LanguageDialogComponent } from '../language/dialog/language-dialog.component';
|
||||||
import { UserDialogComponent } from '../navbar/user-dialog/user-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 {
|
declare interface RouteInfo {
|
||||||
path: string;
|
path: string;
|
||||||
|
@ -151,14 +149,6 @@ export class SidebarComponent implements OnInit {
|
||||||
return this.authentication.currentAccountIsAuthenticated();
|
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 {
|
isLoginRouteActivated(): boolean {
|
||||||
return this.location.path().indexOf('/login') > -1;
|
return this.location.path().indexOf('/login') > -1;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,8 @@
|
||||||
import { Component, OnInit } from '@angular/core';
|
|
||||||
import { HttpClient } from '@angular/common/http';
|
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 { DomSanitizer } from '@angular/platform-browser';
|
||||||
|
import { ConfigurationService } from '@app/core/services/configuration/configuration.service';
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-splash',
|
selector: 'app-splash',
|
||||||
|
@ -23,22 +22,8 @@ export class SplashComponent extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
ngOnInit() {
|
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() {
|
resizeFrame() {
|
||||||
const frame: HTMLIFrameElement = (document.getElementById('splash') as HTMLIFrameElement);
|
const frame: HTMLIFrameElement = (document.getElementById('splash') as HTMLIFrameElement);
|
||||||
|
@ -46,7 +31,6 @@ export class SplashComponent extends BaseComponent implements OnInit {
|
||||||
}
|
}
|
||||||
|
|
||||||
getSplashUrl() {
|
getSplashUrl() {
|
||||||
// return this.sanitizer.bypassSecurityTrustHtml(this.configurationService.splashPath);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 { SupportiveMaterialService } from '@app/core/services/supportive-material/supportive-material.service';
|
||||||
import { BaseComponent } from '@common/base/base.component';
|
import { BaseComponent } from '@common/base/base.component';
|
||||||
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
import { LangChangeEvent, TranslateService } from '@ngx-translate/core';
|
||||||
import { interval, Subject } from 'rxjs';
|
import { Subject, interval } from 'rxjs';
|
||||||
import { takeUntil } from 'rxjs/operators';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
|
@ -60,16 +60,7 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit {
|
||||||
this.readBlob(blob);
|
this.readBlob(blob);
|
||||||
} else {
|
} else {
|
||||||
this.guideHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob));
|
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) {
|
onIFrameLoad(iframe: HTMLIFrameElement) {
|
||||||
|
|
||||||
try {
|
try {
|
||||||
// const contentDocument = iframe.contentDocument;
|
|
||||||
// const URI = contentDocument.URL;
|
|
||||||
// const refs = contentDocument.getElementsByTagName('a');
|
|
||||||
// const navLinks:HTMLAnchorElement[] = [];//only navigation links
|
|
||||||
// for(let i =0; i<refs.length;i++){
|
|
||||||
// const ref = refs[i];
|
|
||||||
// if(ref.classList.contains('nav-link')){
|
|
||||||
// navLinks.push(ref);
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// navLinks.forEach(a=>a.href = URI+a.hash);
|
|
||||||
|
|
||||||
const images = iframe.contentWindow.document.getElementsByTagName('img');
|
const images = iframe.contentWindow.document.getElementsByTagName('img');
|
||||||
|
|
||||||
for (let i = 0; i < images.length; i++) {
|
for (let i = 0; i < images.length; i++) {
|
||||||
|
@ -181,11 +160,6 @@ export class UserGuideContentComponent extends BaseComponent implements OnInit {
|
||||||
tempDiv.innerHTML = currentImage.outerHTML.trim();
|
tempDiv.innerHTML = currentImage.outerHTML.trim();
|
||||||
currentImage.src = (tempDiv.firstChild as HTMLImageElement).src;
|
currentImage.src = (tempDiv.firstChild as HTMLImageElement).src;
|
||||||
}
|
}
|
||||||
|
|
||||||
// const elem = tempDiv.firstChild as HTMLImageElement;
|
|
||||||
// console.log('eleme', elem);
|
|
||||||
// firstimage.src = elem.src;
|
|
||||||
|
|
||||||
} catch {
|
} catch {
|
||||||
console.warn('Could not find contentDocument');
|
console.warn('Could not find contentDocument');
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,27 +4,26 @@ import { Component, OnInit } from '@angular/core';
|
||||||
import { UntypedFormGroup } from '@angular/forms';
|
import { UntypedFormGroup } from '@angular/forms';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
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 { BaseEntity } from '@common/base/base-entity.model';
|
||||||
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
import { BasePendingChangesComponent } from '@common/base/base-pending-changes.component';
|
||||||
import { FormService } from '@common/forms/form-service';
|
import { FormService } from '@common/forms/form-service';
|
||||||
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
import { HttpError, HttpErrorHandlingService } from '@common/modules/errors/error-handling/http-error-handling.service';
|
||||||
import { FilterService } from '@common/modules/text-filter/filter-service';
|
import { FilterService } from '@common/modules/text-filter/filter-service';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
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 { takeUntil } from 'rxjs/operators';
|
||||||
import { nameof } from 'ts-simple-nameof';
|
import { nameof } from 'ts-simple-nameof';
|
||||||
import { Guid } from '../types/guid';
|
import { Guid } from '../types/guid';
|
||||||
import { BaseEditorModel } from './base-form-editor-model';
|
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({
|
@Component({
|
||||||
selector: 'app-base-editor-component',
|
selector: 'app-base-editor-component',
|
||||||
|
@ -73,13 +72,13 @@ export abstract class BaseEditor<EditorModelType extends BaseEditorModel, Entity
|
||||||
|
|
||||||
public ngOnInit(): void {
|
public ngOnInit(): void {
|
||||||
const entity = this.route.snapshot.data['entity'] as EntityType;
|
const entity = this.route.snapshot.data['entity'] as EntityType;
|
||||||
if(entity) {
|
if (entity) {
|
||||||
this.isNew = false;
|
this.isNew = false;
|
||||||
this.prepareForm(entity);
|
this.prepareForm(entity);
|
||||||
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
|
if (this.formGroup && this.editorModel.belongsToCurrentTenant == false) {
|
||||||
this.formGroup.disable();
|
this.formGroup.disable();
|
||||||
}
|
}
|
||||||
}else{
|
} else {
|
||||||
this.prepareForm(null);
|
this.prepareForm(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -131,11 +130,11 @@ export abstract class BaseEditor<EditorModelType extends BaseEditorModel, Entity
|
||||||
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
const error: HttpError = this.httpErrorHandlingService.getError(errorResponse);
|
||||||
if (error.statusCode === 400) {
|
if (error.statusCode === 400) {
|
||||||
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
this.editorModel.validationErrorModel.fromJSONObject(errorResponse.error);
|
||||||
|
|
||||||
if(errorResponse.error.code === ResponseErrorCode.DmpDescriptionTemplateCanNotRemove){
|
if (errorResponse.error.code === ResponseErrorCode.DmpDescriptionTemplateCanNotRemove) {
|
||||||
this.refreshOnNavigateToData(null);
|
this.refreshOnNavigateToData(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
this.formService.validateAllFormFields(this.formGroup);
|
this.formService.validateAllFormFields(this.formGroup);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -145,20 +144,7 @@ export abstract class BaseEditor<EditorModelType extends BaseEditorModel, Entity
|
||||||
this.formService.validateAllFormFields(this.formGroup);
|
this.formService.validateAllFormFields(this.formGroup);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// private refreshOnNavigateToData(id?: Guid): void {
|
|
||||||
// if (this.isNew) {
|
|
||||||
// this.formGroup.markAsPristine();
|
|
||||||
// this.router.navigate([this.formUtilsService.getFormRoute(this.editorModel.type) + '/' + (id ? id : this.editorModel.id)]);
|
|
||||||
// } else { this.internalRefreshData(); }
|
|
||||||
// }
|
|
||||||
|
|
||||||
internalRefreshData(): void {
|
internalRefreshData(): void {
|
||||||
// setTimeout(() => {
|
|
||||||
// this.formGroup = null;
|
|
||||||
// this.editorModel = null;
|
|
||||||
// });
|
|
||||||
this.refreshData();
|
this.refreshData();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -221,6 +207,6 @@ export abstract class BaseEditor<EditorModelType extends BaseEditorModel, Entity
|
||||||
|
|
||||||
ngOnDestroy(): void {
|
ngOnDestroy(): void {
|
||||||
super.ngOnDestroy();
|
super.ngOnDestroy();
|
||||||
if(this.isLockedByUser) this.unlockTarget(this.editorModel.id);
|
if (this.isLockedByUser) this.unlockTarget(this.editorModel.id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -80,14 +80,5 @@ export class FormValidationErrorsDialogComponent {
|
||||||
} else if (formControl.nativeElement.localName === 'app-multiple-auto-complete') {
|
} else if (formControl.nativeElement.localName === 'app-multiple-auto-complete') {
|
||||||
return (Array.from(formControl.nativeElement.firstChild.firstChild.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
return (Array.from(formControl.nativeElement.firstChild.firstChild.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder');
|
||||||
}
|
}
|
||||||
|
|
||||||
// Needs to have <mat-label> in <mat-form-field> 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;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,6 @@ import { JsonInterceptor } from './interceptors/json.interceptor';
|
||||||
import { LocaleInterceptor } from './interceptors/locale.interceptor';
|
import { LocaleInterceptor } from './interceptors/locale.interceptor';
|
||||||
import { ProgressIndicationInterceptor } from './interceptors/progress-indication.interceptor';
|
import { ProgressIndicationInterceptor } from './interceptors/progress-indication.interceptor';
|
||||||
import { RequestTimingInterceptor } from './interceptors/request-timing.interceptor';
|
import { RequestTimingInterceptor } from './interceptors/request-timing.interceptor';
|
||||||
import { ResponsePayloadInterceptor } from './interceptors/response-payload.interceptor';
|
|
||||||
import { UnauthorizedResponseInterceptor } from './interceptors/unauthorized-response.interceptor';
|
import { UnauthorizedResponseInterceptor } from './interceptors/unauthorized-response.interceptor';
|
||||||
import { StatusCodeInterceptor } from './interceptors/status-code.interceptor';
|
import { StatusCodeInterceptor } from './interceptors/status-code.interceptor';
|
||||||
import { TenantHeaderInterceptor } from './interceptors/tenant-header.interceptor';
|
import { TenantHeaderInterceptor } from './interceptors/tenant-header.interceptor';
|
||||||
|
@ -51,11 +50,6 @@ import { TenantHeaderInterceptor } from './interceptors/tenant-header.intercepto
|
||||||
useClass: ProgressIndicationInterceptor,
|
useClass: ProgressIndicationInterceptor,
|
||||||
multi: true,
|
multi: true,
|
||||||
},
|
},
|
||||||
{
|
|
||||||
provide: HTTP_INTERCEPTORS,
|
|
||||||
useClass: ResponsePayloadInterceptor,
|
|
||||||
multi: true,
|
|
||||||
},
|
|
||||||
{
|
{
|
||||||
provide: HTTP_INTERCEPTORS,
|
provide: HTTP_INTERCEPTORS,
|
||||||
useClass: StatusCodeInterceptor,
|
useClass: StatusCodeInterceptor,
|
||||||
|
|
|
@ -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<any>, next: HttpHandler): Observable<HttpSentEvent | HttpHeaderResponse | HttpProgressEvent | HttpResponse<any> | HttpUserEvent<any>> {
|
|
||||||
|
|
||||||
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;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -111,24 +111,7 @@ export class UserSettingsPickerComponent extends BaseComponent implements OnInit
|
||||||
}
|
}
|
||||||
|
|
||||||
renameCurrentUserSetting(): void {
|
renameCurrentUserSetting(): void {
|
||||||
// this.dialog.open<FilterNameDialogComponent, FilterNameDialogComponentParams, FilterNameDialogComponentReturn>(
|
|
||||||
// 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) {
|
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() {
|
saveFilter() {
|
||||||
// const saveDialogRef = this.dialog.open(FilterNameDialogComponent, {
|
//TODO: implement
|
||||||
// maxWidth: '600px',
|
|
||||||
// maxHeight: '400px',
|
|
||||||
// restoreFocus: false,
|
|
||||||
// data: { name: this.currentUserSetting ? this.currentUserSetting.name : '' },
|
|
||||||
// disableClose: false
|
|
||||||
// });
|
|
||||||
|
|
||||||
// saveDialogRef.afterClosed().subscribe(result => {
|
|
||||||
// if (result) { this.createNewFilter(result); }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
import { Component, EventEmitter, Input, OnChanges, OnInit, Output, SimpleChanges } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
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 { BaseComponent } from '@common/base/base.component';
|
||||||
import { Lookup } from '@common/model/lookup';
|
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 { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component';
|
||||||
|
import { TranslateService } from '@ngx-translate/core';
|
||||||
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
|
import { isNullOrUndefined } from '@swimlane/ngx-datatable';
|
||||||
import { UserSetting, UserSettingsService } from '@app/core/services/user-settings/user-settings.service';
|
import { takeUntil } from 'rxjs/operators';
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-user-settings-selector',
|
selector: 'app-user-settings-selector',
|
||||||
|
@ -87,7 +87,6 @@ export class UserSettingsSelectorComponent extends BaseComponent implements OnIn
|
||||||
if (setting === null) { return; }
|
if (setting === null) { return; }
|
||||||
|
|
||||||
//Persist the active user setting
|
//Persist the active user setting
|
||||||
//this.onSettingSelected.emit(setting.value);
|
|
||||||
this.userSettingsService.set(setting, true, this.key);
|
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() {
|
saveFilter() {
|
||||||
// const saveDialogRef = this.dialog.open(FilterNameDialogComponent, {
|
//TODO: implement
|
||||||
// maxWidth: '600px',
|
|
||||||
// maxHeight: '400px',
|
|
||||||
// restoreFocus: false,
|
|
||||||
// data: { name: this.currentUserSetting ? this.currentUserSetting.name : '' },
|
|
||||||
// disableClose: false
|
|
||||||
// });
|
|
||||||
|
|
||||||
// saveDialogRef.afterClosed().subscribe(result => {
|
|
||||||
// if (result) { this.createNewFilter(result); }
|
|
||||||
// });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateFilter() {
|
updateFilter() {
|
||||||
|
@ -147,7 +135,7 @@ export class UserSettingsSelectorComponent extends BaseComponent implements OnIn
|
||||||
setting.updatedAt = null;
|
setting.updatedAt = null;
|
||||||
setting.userId = null;
|
setting.userId = null;
|
||||||
this.currentUserSetting = setting;
|
this.currentUserSetting = setting;
|
||||||
|
|
||||||
this.persistLookupChangesManually(this.currentUserSetting, true);
|
this.persistLookupChangesManually(this.currentUserSetting, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,23 +1,22 @@
|
||||||
import { HttpErrorResponse } from '@angular/common/http';
|
|
||||||
import { Component, OnInit } from '@angular/core';
|
import { Component, OnInit } from '@angular/core';
|
||||||
import { MatDialog } from '@angular/material/dialog';
|
import { MatDialog } from '@angular/material/dialog';
|
||||||
import { ActivatedRoute, ParamMap, Router } from '@angular/router';
|
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 { BaseComponent } from '@common/base/base.component';
|
||||||
import { FormService } from '@common/forms/form-service';
|
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 { 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 { Guid } from '@common/types/guid';
|
||||||
import { TranslateService } from '@ngx-translate/core';
|
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 { NotificationInAppTracking } from '@notification-service/core/enum/notification-inapp-tracking.enum';
|
||||||
import { InAppNotification } from '@notification-service/core/model/inapp-notification.model';
|
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({
|
@Component({
|
||||||
selector: 'app-inapp-notification-editor',
|
selector: 'app-inapp-notification-editor',
|
||||||
|
@ -72,7 +71,7 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O
|
||||||
this.isDeleted = this.inappNotification.isActive === IsActive.Inactive;
|
this.isDeleted = this.inappNotification.isActive === IsActive.Inactive;
|
||||||
this.isRead = this.inappNotification.trackingState === NotificationInAppTracking.Delivered;
|
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)
|
error => this.httpErrorHandlingService.handleBackedRequestError(error)
|
||||||
);
|
);
|
||||||
|
@ -89,7 +88,6 @@ export class InAppNotificationEditorComponent extends BaseComponent implements O
|
||||||
complete => this.onCallbackSuccess(),
|
complete => this.onCallbackSuccess(),
|
||||||
error => this.httpErrorHandlingService.handleBackedRequestError(error)
|
error => this.httpErrorHandlingService.handleBackedRequestError(error)
|
||||||
);
|
);
|
||||||
// this.clearErrorModel();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public delete() {
|
public delete() {
|
||||||
|
|
|
@ -2,8 +2,6 @@ import { DragDropModule } from '@angular/cdk/drag-drop';
|
||||||
import { NgModule } from '@angular/core';
|
import { NgModule } from '@angular/core';
|
||||||
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
import { CommonFormsModule } from '@common/forms/common-forms.module';
|
||||||
import { CommonUiModule } from '@common/ui/common-ui.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';
|
import { UserProfileNotifierListEditorComponent } from '@notification-service/ui/user-profile/notifier-list/user-profile-notifier-list-editor.component';
|
||||||
|
|
||||||
@NgModule({
|
@NgModule({
|
||||||
|
|
|
@ -149,21 +149,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim
|
||||||
filter: alpha(opacity=20);
|
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 {
|
.cc-btn {
|
||||||
background-color: var(--primary-color-3) !important;
|
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 {
|
.lightblue-btn {
|
||||||
background-color: var(--primary-color) !important;
|
background-color: var(--primary-color) !important;
|
||||||
color: white !important;
|
color: white !important;
|
||||||
// background-color: rgba(0, 112, 192, 1) !important;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.listing-item {
|
.listing-item {
|
||||||
|
@ -211,7 +195,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim
|
||||||
padding: 0.1em 1em;
|
padding: 0.1em 1em;
|
||||||
border-radius: 10em;
|
border-radius: 10em;
|
||||||
background-color: #0d7489;
|
background-color: #0d7489;
|
||||||
// background-color: rgba(0, 112, 192, 1);
|
|
||||||
color: #fff;
|
color: #fff;
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
|
@ -227,8 +210,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim
|
||||||
border-radius: 10em;
|
border-radius: 10em;
|
||||||
background-color: rgb(236, 241, 249);
|
background-color: rgb(236, 241, 249);
|
||||||
color: var(--primary-color);
|
color: var(--primary-color);
|
||||||
// color: rgba(0, 112, 192, 1);
|
|
||||||
// color: rgb(68, 114, 196);
|
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
font-weight: 500;
|
font-weight: 500;
|
||||||
max-width: 160px;
|
max-width: 160px;
|
||||||
|
@ -274,21 +255,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim
|
||||||
margin-bottom: 0px;
|
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 {
|
h4 span {
|
||||||
color: #089dbb;
|
color: #089dbb;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
|
@ -387,43 +353,6 @@ $mat-dark-theme: mat.m2-define-dark-theme((color: (primary: $mat-dark-theme-prim
|
||||||
margin-top: 8px;
|
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 <angular-editor> (@kolkov/angular-editor)
|
|
||||||
|
|
||||||
/* Transition Group */
|
/* Transition Group */
|
||||||
.list-move {
|
.list-move {
|
||||||
transition: transform 1s;
|
transition: transform 1s;
|
||||||
|
|
|
@ -24,6 +24,9 @@ notification:
|
||||||
- #descriptionFinalised
|
- #descriptionFinalised
|
||||||
type: 33790bad-94d4-488a-8ee2-7f6295ca18ea
|
type: 33790bad-94d4-488a-8ee2-7f6295ca18ea
|
||||||
contacts: [ inapp, email ]
|
contacts: [ inapp, email ]
|
||||||
|
- #descriptionAnnotationCreated
|
||||||
|
type: db1e99d2-a240-4e75-9bb2-ef25b234c1f0
|
||||||
|
contacts: [ inapp, email ]
|
||||||
- #mergeAcountConfirmation
|
- #mergeAcountConfirmation
|
||||||
type: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
type: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
||||||
contacts: [ email ]
|
contacts: [ email ]
|
||||||
|
@ -196,6 +199,31 @@ notification:
|
||||||
bcc-mode: 0
|
bcc-mode: 0
|
||||||
allow-attachments: false
|
allow-attachments: false
|
||||||
cipher-fields: [ ]
|
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
|
- #mergeAccountConfirmation
|
||||||
key: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
key: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
||||||
subject-path: classpath:notification_templates/mergeacountconfirmation/email/subject.{language}.txt
|
subject-path: classpath:notification_templates/mergeacountconfirmation/email/subject.{language}.txt
|
||||||
|
@ -449,6 +477,29 @@ notification:
|
||||||
'[{tenant-url-path}]': null
|
'[{tenant-url-path}]': null
|
||||||
priority-key: null
|
priority-key: null
|
||||||
cipher-fields: [ ]
|
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
|
- #mergeAccountConfirmation
|
||||||
key: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
key: BFE68845-CB05-4C5A-A03D-29161A7C9660
|
||||||
subject-path: classpath:notification_templates/mergeacountconfirmation/inapp/subject.{language}.txt
|
subject-path: classpath:notification_templates/mergeacountconfirmation/inapp/subject.{language}.txt
|
||||||
|
|
|
@ -0,0 +1,304 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
<title>OpenCDMP Notification</title>
|
||||||
|
<style>
|
||||||
|
/* -------------------------------------
|
||||||
|
GLOBAL RESETS
|
||||||
|
------------------------------------- */
|
||||||
|
img {
|
||||||
|
border: none;
|
||||||
|
-ms-interpolation-mode: bicubic;
|
||||||
|
max-width: 100%; }
|
||||||
|
body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
font-family: sans-serif;
|
||||||
|
-webkit-font-smoothing: antialiased;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
|
-ms-text-size-adjust: 100%;
|
||||||
|
-webkit-text-size-adjust: 100%; }
|
||||||
|
table {
|
||||||
|
border-collapse: separate;
|
||||||
|
mso-table-lspace: 0pt;
|
||||||
|
mso-table-rspace: 0pt;
|
||||||
|
width: 100%; }
|
||||||
|
table td {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
vertical-align: top; }
|
||||||
|
/* -------------------------------------
|
||||||
|
BODY & CONTAINER
|
||||||
|
------------------------------------- */
|
||||||
|
.body {
|
||||||
|
background-color: #f6f6f6;
|
||||||
|
width: 100%; }
|
||||||
|
/* Set a max-width, and make it display as block so it will automatically stretch to that width, but will also shrink down on a phone or something */
|
||||||
|
.container {
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto !important;
|
||||||
|
/* makes it centered */
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px;
|
||||||
|
width: 580px; }
|
||||||
|
/* This should also be a block element, so that it will fill 100% of the .container */
|
||||||
|
.content {
|
||||||
|
box-sizing: border-box;
|
||||||
|
display: block;
|
||||||
|
Margin: 0 auto;
|
||||||
|
max-width: 580px;
|
||||||
|
padding: 10px; }
|
||||||
|
/* -------------------------------------
|
||||||
|
HEADER, FOOTER, MAIN
|
||||||
|
------------------------------------- */
|
||||||
|
.main {
|
||||||
|
background: #ffffff;
|
||||||
|
border-radius: 3px;
|
||||||
|
width: 100%; }
|
||||||
|
.wrapper {
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding: 20px; }
|
||||||
|
.content-block {
|
||||||
|
padding-bottom: 10px;
|
||||||
|
padding-top: 10px;
|
||||||
|
}
|
||||||
|
.footer {
|
||||||
|
clear: both;
|
||||||
|
Margin-top: 10px;
|
||||||
|
text-align: center;
|
||||||
|
width: 100%; }
|
||||||
|
.footer td,
|
||||||
|
.footer p,
|
||||||
|
.footer span,
|
||||||
|
.footer a {
|
||||||
|
color: #999999;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: center; }
|
||||||
|
/* -------------------------------------
|
||||||
|
TYPOGRAPHY
|
||||||
|
------------------------------------- */
|
||||||
|
h1,
|
||||||
|
h2,
|
||||||
|
h3,
|
||||||
|
h4 {
|
||||||
|
color: #000000;
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-weight: 400;
|
||||||
|
line-height: 1.4;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 30px; }
|
||||||
|
h1 {
|
||||||
|
font-size: 35px;
|
||||||
|
font-weight: 300;
|
||||||
|
text-align: center;
|
||||||
|
text-transform: capitalize; }
|
||||||
|
p,
|
||||||
|
ul,
|
||||||
|
ol {
|
||||||
|
font-family: sans-serif;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: normal;
|
||||||
|
margin: 0;
|
||||||
|
Margin-bottom: 15px; }
|
||||||
|
p li,
|
||||||
|
ul li,
|
||||||
|
ol li {
|
||||||
|
list-style-position: inside;
|
||||||
|
margin-left: 5px; }
|
||||||
|
a {
|
||||||
|
color: #3498db;
|
||||||
|
text-decoration: underline; }
|
||||||
|
/* -------------------------------------
|
||||||
|
BUTTONS
|
||||||
|
------------------------------------- */
|
||||||
|
.btn {
|
||||||
|
box-sizing: border-box;
|
||||||
|
width: 100%; }
|
||||||
|
.btn > tbody > tr > td {
|
||||||
|
padding-bottom: 15px; }
|
||||||
|
.btn table {
|
||||||
|
width: auto; }
|
||||||
|
.btn table td {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border-radius: 5px;
|
||||||
|
text-align: center; }
|
||||||
|
.btn a {
|
||||||
|
background-color: #ffffff;
|
||||||
|
border: solid 1px #3498db;
|
||||||
|
border-radius: 5px;
|
||||||
|
box-sizing: border-box;
|
||||||
|
color: #3498db;
|
||||||
|
cursor: pointer;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 14px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin: 0;
|
||||||
|
padding: 12px 25px;
|
||||||
|
text-decoration: none;
|
||||||
|
text-transform: capitalize; }
|
||||||
|
.btn-primary table td {
|
||||||
|
background-color: #3498db; }
|
||||||
|
.btn-primary a {
|
||||||
|
background-color: #3498db;
|
||||||
|
border-color: #3498db;
|
||||||
|
color: #ffffff; }
|
||||||
|
/* -------------------------------------
|
||||||
|
OTHER STYLES THAT MIGHT BE USEFUL
|
||||||
|
------------------------------------- */
|
||||||
|
.last {
|
||||||
|
margin-bottom: 0; }
|
||||||
|
.first {
|
||||||
|
margin-top: 0; }
|
||||||
|
.align-center {
|
||||||
|
text-align: center; }
|
||||||
|
.align-right {
|
||||||
|
text-align: right; }
|
||||||
|
.align-left {
|
||||||
|
text-align: left; }
|
||||||
|
.clear {
|
||||||
|
clear: both; }
|
||||||
|
.mt0 {
|
||||||
|
margin-top: 0; }
|
||||||
|
.mb0 {
|
||||||
|
margin-bottom: 0; }
|
||||||
|
.preheader {
|
||||||
|
color: transparent;
|
||||||
|
display: none;
|
||||||
|
height: 0;
|
||||||
|
max-height: 0;
|
||||||
|
max-width: 0;
|
||||||
|
opacity: 0;
|
||||||
|
overflow: hidden;
|
||||||
|
mso-hide: all;
|
||||||
|
visibility: hidden;
|
||||||
|
width: 0; }
|
||||||
|
.powered-by a {
|
||||||
|
text-decoration: none; }
|
||||||
|
hr {
|
||||||
|
border: 0;
|
||||||
|
border-bottom: 1px solid #f6f6f6;
|
||||||
|
Margin: 20px 0; }
|
||||||
|
/* -------------------------------------
|
||||||
|
RESPONSIVE AND MOBILE FRIENDLY STYLES
|
||||||
|
------------------------------------- */
|
||||||
|
@media only screen and (max-width: 620px) {
|
||||||
|
table[class=body] h1 {
|
||||||
|
font-size: 28px !important;
|
||||||
|
margin-bottom: 10px !important; }
|
||||||
|
table[class=body] p,
|
||||||
|
table[class=body] ul,
|
||||||
|
table[class=body] ol,
|
||||||
|
table[class=body] td,
|
||||||
|
table[class=body] span,
|
||||||
|
table[class=body] a {
|
||||||
|
font-size: 16px !important; }
|
||||||
|
table[class=body] .wrapper,
|
||||||
|
table[class=body] .article {
|
||||||
|
padding: 10px !important; }
|
||||||
|
table[class=body] .content {
|
||||||
|
padding: 0 !important; }
|
||||||
|
table[class=body] .container {
|
||||||
|
padding: 0 !important;
|
||||||
|
width: 100% !important; }
|
||||||
|
table[class=body] .main {
|
||||||
|
border-left-width: 0 !important;
|
||||||
|
border-radius: 0 !important;
|
||||||
|
border-right-width: 0 !important; }
|
||||||
|
table[class=body] .btn table {
|
||||||
|
width: 100% !important; }
|
||||||
|
table[class=body] .btn a {
|
||||||
|
width: 100% !important; }
|
||||||
|
table[class=body] .img-responsive {
|
||||||
|
height: auto !important;
|
||||||
|
max-width: 100% !important;
|
||||||
|
width: auto !important; }}
|
||||||
|
/* -------------------------------------
|
||||||
|
PRESERVE THESE STYLES IN THE HEAD
|
||||||
|
------------------------------------- */
|
||||||
|
@media all {
|
||||||
|
.ExternalClass {
|
||||||
|
width: 100%; }
|
||||||
|
.ExternalClass,
|
||||||
|
.ExternalClass p,
|
||||||
|
.ExternalClass span,
|
||||||
|
.ExternalClass font,
|
||||||
|
.ExternalClass td,
|
||||||
|
.ExternalClass div {
|
||||||
|
line-height: 100%; }
|
||||||
|
.apple-link a {
|
||||||
|
color: inherit !important;
|
||||||
|
font-family: inherit !important;
|
||||||
|
font-size: inherit !important;
|
||||||
|
font-weight: inherit !important;
|
||||||
|
line-height: inherit !important;
|
||||||
|
text-decoration: none !important; }
|
||||||
|
.btn-primary table td:hover {
|
||||||
|
background-color: #34495e !important; }
|
||||||
|
.btn-primary a:hover {
|
||||||
|
background-color: #34495e !important;
|
||||||
|
border-color: #34495e !important; } }
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body class="">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="body">
|
||||||
|
<tr>
|
||||||
|
<td> </td>
|
||||||
|
<td class="container">
|
||||||
|
<div class="content">
|
||||||
|
|
||||||
|
<!-- START CENTERED WHITE CONTAINER -->
|
||||||
|
<span class="preheader">This is preheader text. Some clients will show this text as a preview.</span>
|
||||||
|
<table class="main">
|
||||||
|
|
||||||
|
<!-- START MAIN CONTENT AREA -->
|
||||||
|
<tr>
|
||||||
|
<td class="wrapper">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tr>
|
||||||
|
<td>
|
||||||
|
<p>Dear {recipient},</p>
|
||||||
|
<p>{reasonName} made a comment on the Description {name}.</p>
|
||||||
|
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0" class="btn btn-primary">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td align="left">
|
||||||
|
<table border="0" cellpadding="0" cellspacing="0">
|
||||||
|
<tbody>
|
||||||
|
<tr>
|
||||||
|
<td> <a href="{installation-url}{tenant-url-path}/descriptions/edit/{id}" target="_blank">Click here to view it.</a> </td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
|
||||||
|
<!-- END MAIN CONTENT AREA -->
|
||||||
|
</table>
|
||||||
|
|
||||||
|
<!-- START FOOTER -->
|
||||||
|
<div class="footer">
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- END FOOTER -->
|
||||||
|
|
||||||
|
<!-- END CENTERED WHITE CONTAINER -->
|
||||||
|
</div>
|
||||||
|
</td>
|
||||||
|
<td> </td>
|
||||||
|
</tr>
|
||||||
|
</table>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
OpenCDMP - Comment for Description
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!doctype html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<meta name="viewport" content="width=device-width" />
|
||||||
|
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
|
||||||
|
</head>
|
||||||
|
<body class="">
|
||||||
|
<p>Dear {recipient},</p>
|
||||||
|
<p>{reasonName} made a comment on the Description {name}.</p>
|
||||||
|
<a href="{installation-url}{tenant-url-path}/descriptions/edit/{id}" target="_blank">Click here to view it.</a>
|
||||||
|
</body>
|
||||||
|
</html>
|
|
@ -0,0 +1 @@
|
||||||
|
OpenCDMP - Comment for Description
|
Loading…
Reference in New Issue