diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/DependencyPropertyEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/DependencyPropertyEntity.java new file mode 100644 index 000000000..da2f13a20 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/DependencyPropertyEntity.java @@ -0,0 +1,44 @@ +package eu.eudat.commons.types.referencetype; + +import jakarta.xml.bind.annotation.XmlAccessType; +import jakarta.xml.bind.annotation.XmlAccessorType; +import jakarta.xml.bind.annotation.XmlAttribute; +import jakarta.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "property") +@XmlAccessorType(XmlAccessType.FIELD) +public class DependencyPropertyEntity { + + @XmlAttribute(name = "code") + private String code; + + @XmlAttribute(name = "target") + private String target; + + @XmlAttribute(name = "required") + private Boolean required; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseConfigurationEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseConfigurationEntity.java index 81faad415..ead9bec7c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseConfigurationEntity.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseConfigurationEntity.java @@ -2,6 +2,9 @@ package eu.eudat.commons.types.referencetype; import eu.eudat.commons.enums.ReferenceTypeSourceType; import jakarta.xml.bind.annotation.XmlElement; +import jakarta.xml.bind.annotation.XmlElementWrapper; + +import java.util.List; public abstract class ReferenceTypeSourceBaseConfigurationEntity { @@ -12,7 +15,7 @@ public abstract class ReferenceTypeSourceBaseConfigurationEntity { private Integer ordinal; private ReferenceTypeSourceType type; - + private List dependencies; public ReferenceTypeSourceType getType() { return type; } @@ -48,4 +51,14 @@ public abstract class ReferenceTypeSourceBaseConfigurationEntity { public void setType(ReferenceTypeSourceType type) { this.type = type; } + + public List getDependencies() { + return dependencies; + } + + @XmlElementWrapper + @XmlElement(name = "dependency") + public void setDependencies(List dependencies) { + this.dependencies = dependencies; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseDependencyEntity.java b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseDependencyEntity.java new file mode 100644 index 000000000..394662da7 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/types/referencetype/ReferenceTypeSourceBaseDependencyEntity.java @@ -0,0 +1,55 @@ +package eu.eudat.commons.types.referencetype; + +import jakarta.xml.bind.annotation.*; + +import java.util.List; + +@XmlRootElement(name = "dependency") +@XmlAccessorType(XmlAccessType.FIELD) +public class ReferenceTypeSourceBaseDependencyEntity { + @XmlAttribute(name = "referenceTypeCode") + private String referenceTypeCode; + + @XmlAttribute(name = "key") + private String key; + + @XmlAttribute(name = "required") + private Boolean required; + + @XmlElementWrapper(name = "properties") + @XmlElement(name = "property") + private List properties; + + + public String getReferenceTypeCode() { + return referenceTypeCode; + } + + public void setReferenceTypeCode(String referenceTypeCode) { + this.referenceTypeCode = referenceTypeCode; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/DependencyPropertyBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/DependencyPropertyBuilder.java new file mode 100644 index 000000000..40323dc92 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/DependencyPropertyBuilder.java @@ -0,0 +1,59 @@ +package eu.eudat.model.builder.referencetypedefinition; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.commons.types.referencetype.DependencyPropertyEntity; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.builder.BaseBuilder; +import eu.eudat.model.referencetypedefinition.DependencyProperty; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.exception.MyApplicationException; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.*; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class DependencyPropertyBuilder extends BaseBuilder { + + private final BuilderFactory builderFactory; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public DependencyPropertyBuilder( + ConventionService conventionService, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(DependencyPropertyBuilder.class))); + this.builderFactory = builderFactory; + } + + public DependencyPropertyBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + List models = new ArrayList<>(); + for (DependencyPropertyEntity d : data) { + DependencyProperty m = new DependencyProperty(); + if (fields.hasField(this.asIndexer(DependencyProperty._code))) m.setCode(d.getCode()); + if (fields.hasField(this.asIndexer(DependencyProperty._target))) m.setTarget(d.getTarget()); + if (fields.hasField(this.asIndexer(DependencyProperty._required))) m.setRequired(d.getRequired()); + + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceBaseConfigurationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceBaseConfigurationBuilder.java index fdc496cdc..0732d118e 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceBaseConfigurationBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceBaseConfigurationBuilder.java @@ -5,6 +5,7 @@ import eu.eudat.commons.types.referencetype.ReferenceTypeSourceBaseConfiguration import eu.eudat.convention.ConventionService; import eu.eudat.model.builder.BaseBuilder; import eu.eudat.model.referencetypedefinition.ReferenceTypeSourceBaseConfiguration; +import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.fieldset.FieldSet; import gr.cite.tools.logging.DataLogEntry; @@ -21,12 +22,14 @@ import java.util.*; public abstract class ReferenceTypeSourceBaseConfigurationBuilder extends BaseBuilder { protected EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + protected final BuilderFactory builderFactory; @Autowired public ReferenceTypeSourceBaseConfigurationBuilder( ConventionService conventionService, - LoggerService logger) { + LoggerService logger, BuilderFactory builderFactory) { super(conventionService, logger); + this.builderFactory = builderFactory; } public ReferenceTypeSourceBaseConfigurationBuilder authorize(EnumSet values) { @@ -44,6 +47,7 @@ public abstract class ReferenceTypeSourceBaseConfigurationBuilder(); + FieldSet dependenciesFields = fields.extractPrefixed(this.asPrefix(Model._dependencies)); List models = new ArrayList<>(); for (Entity d : data) { Model m = this.getInstance(); @@ -51,6 +55,8 @@ public abstract class ReferenceTypeSourceBaseConfigurationBuilder { + + private final BuilderFactory builderFactory; + private EnumSet authorize = EnumSet.of(AuthorizationFlags.None); + + @Autowired + public ReferenceTypeSourceBaseDependencyBuilder( + ConventionService conventionService, BuilderFactory builderFactory) { + super(conventionService, new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceBaseDependencyBuilder.class))); + this.builderFactory = builderFactory; + } + + public ReferenceTypeSourceBaseDependencyBuilder authorize(EnumSet values) { + this.authorize = values; + return this; + } + + @Override + public List build(FieldSet fields, List data) throws MyApplicationException { + this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0)); + this.logger.trace(new DataLogEntry("requested fields", fields)); + if (fields == null || data == null || fields.isEmpty()) + return new ArrayList<>(); + + FieldSet propertiesFields = fields.extractPrefixed(this.asPrefix(ReferenceTypeSourceBaseDependency._properties)); + + List models = new ArrayList<>(); + for (ReferenceTypeSourceBaseDependencyEntity d : data) { + ReferenceTypeSourceBaseDependency m = new ReferenceTypeSourceBaseDependency(); + if (fields.hasField(this.asIndexer(ReferenceTypeSourceBaseDependency._referenceTypeCode))) m.setReferenceTypeCode(d.getReferenceTypeCode()); + if (fields.hasField(this.asIndexer(ReferenceTypeSourceBaseDependency._key))) m.setKey(d.getKey()); + if (fields.hasField(this.asIndexer(ReferenceTypeSourceBaseDependency._required))) m.setRequired(d.getRequired()); + if (!propertiesFields.isEmpty() && d.getProperties() != null) m.setProperties(this.builderFactory.builder(DependencyPropertyBuilder.class).authorize(this.authorize).build(propertiesFields, d.getProperties())); + + models.add(m); + } + this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0)); + return models; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationBuilder.java index 81827876a..fd6df6401 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceExternalApiConfigurationBuilder.java @@ -25,7 +25,7 @@ public class ReferenceTypeSourceExternalApiConfigurationBuilder extends Referenc @Autowired public ReferenceTypeSourceExternalApiConfigurationBuilder( ConventionService conventionService, BuilderFactory builderFactory) { - super(conventionService, new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceExternalApiConfigurationBuilder.class))); + super(conventionService, new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceExternalApiConfigurationBuilder.class)), builderFactory); this.builderFactory = builderFactory; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceStaticOptionConfigurationBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceStaticOptionConfigurationBuilder.java index dfd06af8b..fe78fc243 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceStaticOptionConfigurationBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/referencetypedefinition/ReferenceTypeSourceStaticOptionConfigurationBuilder.java @@ -25,7 +25,7 @@ public class ReferenceTypeSourceStaticOptionConfigurationBuilder extends Referen @Autowired public ReferenceTypeSourceStaticOptionConfigurationBuilder( ConventionService conventionService, BuilderFactory builderFactory) { - super(conventionService, new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceStaticOptionConfigurationBuilder.class))); + super(conventionService, new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceStaticOptionConfigurationBuilder.class)), builderFactory); this.builderFactory = builderFactory; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/ReferenceTypeCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/ReferenceTypeCensor.java index 15e2582d0..42987894d 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/ReferenceTypeCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/ReferenceTypeCensor.java @@ -3,7 +3,7 @@ package eu.eudat.model.censorship; import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; import eu.eudat.model.ReferenceType; -import eu.eudat.model.censorship.referencetype.ReferenceTypeDefinitionCensor; +import eu.eudat.model.censorship.referencetypedefinition.ReferenceTypeDefinitionCensor; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.tools.data.censor.CensorFactory; import gr.cite.tools.fieldset.FieldSet; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeSourceBaseConfigurationCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/DependencyPropertyCensor.java similarity index 74% rename from dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeSourceBaseConfigurationCensor.java rename to dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/DependencyPropertyCensor.java index 54d71217c..9c8ac04ca 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeSourceBaseConfigurationCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/DependencyPropertyCensor.java @@ -1,4 +1,4 @@ -package eu.eudat.model.censorship.referencetype; +package eu.eudat.model.censorship.referencetypedefinition; import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; @@ -16,14 +16,14 @@ import java.util.UUID; @Component @Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) -public class ReferenceTypeSourceBaseConfigurationCensor extends BaseCensor { +public class DependencyPropertyCensor extends BaseCensor { - private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceBaseConfigurationCensor.class)); + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DependencyPropertyCensor.class)); protected final AuthorizationService authService; - public ReferenceTypeSourceBaseConfigurationCensor(ConventionService conventionService, - AuthorizationService authService) { + public DependencyPropertyCensor(ConventionService conventionService, + AuthorizationService authService) { super(conventionService); this.authService = authService; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeDefinitionCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeDefinitionCensor.java similarity index 97% rename from dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeDefinitionCensor.java rename to dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeDefinitionCensor.java index 2eb0c7966..7be330405 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeDefinitionCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeDefinitionCensor.java @@ -1,4 +1,4 @@ -package eu.eudat.model.censorship.referencetype; +package eu.eudat.model.censorship.referencetypedefinition; import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeFieldCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeFieldCensor.java similarity index 95% rename from dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeFieldCensor.java rename to dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeFieldCensor.java index a17c67573..b9dff5d9f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetype/ReferenceTypeFieldCensor.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeFieldCensor.java @@ -1,4 +1,4 @@ -package eu.eudat.model.censorship.referencetype; +package eu.eudat.model.censorship.referencetypedefinition; import eu.eudat.authorization.Permission; import eu.eudat.convention.ConventionService; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseConfigurationCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseConfigurationCensor.java new file mode 100644 index 000000000..04a715aee --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseConfigurationCensor.java @@ -0,0 +1,45 @@ +package eu.eudat.model.censorship.referencetypedefinition; + +import eu.eudat.authorization.Permission; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.censorship.BaseCensor; +import eu.eudat.model.referencetypedefinition.ReferenceTypeSourceBaseConfiguration; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ReferenceTypeSourceBaseConfigurationCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceBaseConfigurationCensor.class)); + + protected final AuthorizationService authService; + protected final CensorFactory censorFactory; + + public ReferenceTypeSourceBaseConfigurationCensor(ConventionService conventionService, + AuthorizationService authService, CensorFactory censorFactory) { + super(conventionService); + this.authService = authService; + this.censorFactory = censorFactory; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + this.authService.authorizeForce(Permission.BrowseReferenceType); + FieldSet dependenciesFields = fields.extractPrefixed(this.asIndexerPrefix(ReferenceTypeSourceBaseConfiguration._dependencies)); + this.censorFactory.censor(ReferenceTypeSourceBaseDependencyCensor.class).censor(dependenciesFields, userId); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseDependencyCensor.java b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseDependencyCensor.java new file mode 100644 index 000000000..29386f0fa --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/censorship/referencetypedefinition/ReferenceTypeSourceBaseDependencyCensor.java @@ -0,0 +1,45 @@ +package eu.eudat.model.censorship.referencetypedefinition; + +import eu.eudat.authorization.Permission; +import eu.eudat.convention.ConventionService; +import eu.eudat.model.censorship.BaseCensor; +import eu.eudat.model.referencetypedefinition.ReferenceTypeSourceBaseDependency; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.tools.data.censor.CensorFactory; +import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.logging.DataLogEntry; +import gr.cite.tools.logging.LoggerService; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.config.ConfigurableBeanFactory; +import org.springframework.context.annotation.Scope; +import org.springframework.stereotype.Component; + +import java.util.UUID; + +@Component +@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE) +public class ReferenceTypeSourceBaseDependencyCensor extends BaseCensor { + + private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(ReferenceTypeSourceBaseDependencyCensor.class)); + + protected final AuthorizationService authService; + protected final CensorFactory censorFactory; + + public ReferenceTypeSourceBaseDependencyCensor(ConventionService conventionService, + AuthorizationService authService, CensorFactory censorFactory) { + super(conventionService); + this.authService = authService; + this.censorFactory = censorFactory; + } + + public void censor(FieldSet fields, UUID userId) { + logger.debug(new DataLogEntry("censoring fields", fields)); + if (fields == null || fields.isEmpty()) + return; + + this.authService.authorizeForce(Permission.BrowseReferenceType); + FieldSet propertiesFields = fields.extractPrefixed(this.asIndexerPrefix( ReferenceTypeSourceBaseDependency._properties)); + this.censorFactory.censor(DependencyPropertyCensor.class).censor(propertiesFields, userId); + } + +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/DependencyPropertyPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/DependencyPropertyPersist.java new file mode 100644 index 000000000..ecfcd8bc5 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/DependencyPropertyPersist.java @@ -0,0 +1,43 @@ +package eu.eudat.model.persist.referencetypedefinition; + + +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +public class DependencyPropertyPersist { + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String code; + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String target; + + @NotNull(message = "{validation.empty}") + private Boolean required; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java index 9a7b5f481..63a3c93c5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseConfigurationPersist.java @@ -4,9 +4,12 @@ import com.fasterxml.jackson.annotation.JsonSubTypes; import com.fasterxml.jackson.annotation.JsonTypeInfo; import eu.eudat.commons.enums.ReferenceTypeSourceType; import eu.eudat.commons.validation.ValidEnum; +import jakarta.validation.Valid; import jakarta.validation.constraints.NotEmpty; import jakarta.validation.constraints.NotNull; +import java.util.List; + @JsonTypeInfo( use = JsonTypeInfo.Id.NAME, include = JsonTypeInfo.As.PROPERTY, @@ -32,6 +35,8 @@ public abstract class ReferenceTypeSourceBaseConfigurationPersist { @ValidEnum(message = "{validation.empty}") private ReferenceTypeSourceType type; + @Valid + private List dependencies; public String getKey() { return key; @@ -64,4 +69,12 @@ public abstract class ReferenceTypeSourceBaseConfigurationPersist { public void setType(ReferenceTypeSourceType type) { this.type = type; } + + public List getDependencies() { + return dependencies; + } + + public void setDependencies(List dependencies) { + this.dependencies = dependencies; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseDependencyPersist.java b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseDependencyPersist.java new file mode 100644 index 000000000..f1a88bf8f --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/persist/referencetypedefinition/ReferenceTypeSourceBaseDependencyPersist.java @@ -0,0 +1,58 @@ +package eu.eudat.model.persist.referencetypedefinition; + +import jakarta.validation.Valid; +import jakarta.validation.constraints.NotEmpty; +import jakarta.validation.constraints.NotNull; + +import java.util.List; + +public class ReferenceTypeSourceBaseDependencyPersist { + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String referenceTypeCode; + + @NotNull(message = "{validation.empty}") + @NotEmpty(message = "{validation.empty}") + private String key; + + @NotNull(message = "{validation.empty}") + private Boolean required; + + @NotNull(message = "{validation.empty}") + @Valid + private List properties; + + + public String getReferenceTypeCode() { + return referenceTypeCode; + } + + public void setReferenceTypeCode(String referenceTypeCode) { + this.referenceTypeCode = referenceTypeCode; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/DependencyProperty.java b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/DependencyProperty.java new file mode 100644 index 000000000..3cfde1e92 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/DependencyProperty.java @@ -0,0 +1,38 @@ +package eu.eudat.model.referencetypedefinition; + + +public class DependencyProperty { + + public final static String _code = "code"; + private String code; + + public final static String _target = "target"; + private String target; + + public final static String _required = "required"; + private Boolean required; + + public String getCode() { + return code; + } + + public void setCode(String code) { + this.code = code; + } + + public String getTarget() { + return target; + } + + public void setTarget(String target) { + this.target = target; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseConfiguration.java b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseConfiguration.java index 38505db48..5621c4c23 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseConfiguration.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseConfiguration.java @@ -2,6 +2,8 @@ package eu.eudat.model.referencetypedefinition; import eu.eudat.commons.enums.ReferenceTypeSourceType; +import java.util.List; + public abstract class ReferenceTypeSourceBaseConfiguration { @@ -17,6 +19,9 @@ public abstract class ReferenceTypeSourceBaseConfiguration { public final static String _type = "type"; private ReferenceTypeSourceType type; + public final static String _dependencies = "dependencies"; + private List dependencies; + public ReferenceTypeSourceType getType() { return type; } @@ -48,4 +53,12 @@ public abstract class ReferenceTypeSourceBaseConfiguration { public void setOrdinal(Integer ordinal) { this.ordinal = ordinal; } + + public List getDependencies() { + return dependencies; + } + + public void setDependencies(List dependencies) { + this.dependencies = dependencies; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseDependency.java b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseDependency.java new file mode 100644 index 000000000..5f3f0cc35 --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/model/referencetypedefinition/ReferenceTypeSourceBaseDependency.java @@ -0,0 +1,52 @@ +package eu.eudat.model.referencetypedefinition; + + +import java.util.List; + +public class ReferenceTypeSourceBaseDependency { + + public final static String _referenceTypeCode = "referenceTypeCode"; + private String referenceTypeCode; + + public final static String _key = "key"; + private String key; + + public final static String _required = "required"; + private Boolean required; + + public final static String _properties = "properties"; + private List properties; + + + public String getReferenceTypeCode() { + return referenceTypeCode; + } + + public void setReferenceTypeCode(String referenceTypeCode) { + this.referenceTypeCode = referenceTypeCode; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + + public Boolean getRequired() { + return required; + } + + public void setRequired(Boolean required) { + this.required = required; + } + + public List getProperties() { + return properties; + } + + public void setProperties(List properties) { + this.properties = properties; + } +} diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceTypeQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceTypeQuery.java index 7bc0e599b..cba845bd5 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceTypeQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/ReferenceTypeQuery.java @@ -142,7 +142,7 @@ public class ReferenceTypeQuery extends QueryBase { predicates.add(inClause); } if (this.codes != null) { - CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceEntity._type)); + CriteriaBuilder.In inClause = queryContext.CriteriaBuilder.in(queryContext.Root.get(ReferenceTypeEntity._code)); for (String item : this.codes) inClause.value(item); predicates.add(inClause); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java index 7014175eb..02cf92191 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/RepositoryDepositService.java @@ -23,8 +23,8 @@ import eu.eudat.service.entitydoi.EntityDoiService; import eu.eudat.utilities.pdf.PDFUtils; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.oidc.apikey.ApiKeyCacheService; -import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyExchangeFilterFunction; -import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyWebfluxModel; +//import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyExchangeFilterFunction; +//import gr.cite.commons.web.oidc.apikey.webflux.ApiKeyWebfluxModel; import gr.cite.tools.data.query.Ordering; import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; @@ -83,11 +83,11 @@ public class RepositoryDepositService { DepositProperties.DepositSource source = depositProperties.getSources().stream().filter(depositSource -> depositSource.getCodes().contains(repoId)).findFirst().orElse(null); if (source != null) { String host = URI.create(source.getUrl()).getHost(); - ApiKeyWebfluxModel apiKeyWebfluxModel = new ApiKeyWebfluxModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); - ApiKeyExchangeFilterFunction apiKeyExchangeFilterFunction = new ApiKeyExchangeFilterFunction(this.apiKeyCacheService, apiKeyWebfluxModel); - DepositRepository repository = new DepositRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build()); - source.getCodes().forEach(code -> this.clients.put(code, repository)); - return repository; +// ApiKeyWebfluxModel apiKeyWebfluxModel = new ApiKeyWebfluxModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); +// ApiKeyExchangeFilterFunction apiKeyExchangeFilterFunction = new ApiKeyExchangeFilterFunction(this.apiKeyCacheService, apiKeyWebfluxModel); +// DepositRepository repository = new DepositRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/deposit").filters(exchangeFilterFunctions -> exchangeFilterFunctions.add(apiKeyExchangeFilterFunction)).build()); +// source.getCodes().forEach(code -> this.clients.put(code, repository)); +// return repository; } return null; } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/referencetype/ReferenceTypeServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/referencetype/ReferenceTypeServiceImpl.java index d90da72f7..3b09d5ca9 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/referencetype/ReferenceTypeServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/referencetype/ReferenceTypeServiceImpl.java @@ -183,6 +183,13 @@ public class ReferenceTypeServiceImpl implements ReferenceTypeService { data.setLabel(persist.getLabel()); data.setOrdinal(persist.getOrdinal()); + if (!this.conventionService.isListNullOrEmpty(persist.getDependencies())){ + data.setDependencies(new ArrayList<>()); + for (ReferenceTypeSourceBaseDependencyPersist dependencyPersist: persist.getDependencies()) { + data.getDependencies().add(this.buildDependencyEntity(dependencyPersist)); + } + } + return data; } @@ -247,6 +254,35 @@ public class ReferenceTypeServiceImpl implements ReferenceTypeService { return data; } + private @NotNull ReferenceTypeSourceBaseDependencyEntity buildDependencyEntity(ReferenceTypeSourceBaseDependencyPersist persist){ + ReferenceTypeSourceBaseDependencyEntity data = new ReferenceTypeSourceBaseDependencyEntity(); + if (persist == null) return data; + + data.setReferenceTypeCode(persist.getReferenceTypeCode()); + data.setKey(persist.getKey()); + data.setRequired(persist.getRequired()); + + if (!this.conventionService.isListNullOrEmpty(persist.getProperties())){ + data.setProperties(new ArrayList<>()); + for (DependencyPropertyPersist propertyPersist: persist.getProperties()) { + data.getProperties().add(this.buildPropertyEntity(propertyPersist)); + } + } + + return data; + } + + private @NotNull DependencyPropertyEntity buildPropertyEntity(DependencyPropertyPersist persist){ + DependencyPropertyEntity data = new DependencyPropertyEntity(); + if (persist == null) return data; + + data.setCode(persist.getCode()); + data.setTarget(persist.getTarget()); + data.setRequired(persist.getRequired()); + + return data; + } + public void deleteAndSave(UUID id) throws MyForbiddenException, InvalidApplicationException { logger.debug("deleting : {}", id); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/references/ReferenceService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/references/ReferenceService.java index 3daeff910..1aa4ea04a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/references/ReferenceService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/references/ReferenceService.java @@ -51,6 +51,7 @@ import gr.cite.tools.logging.LoggerService; import gr.cite.tools.logging.MapLogEntry; import jakarta.persistence.EntityManager; import jakarta.xml.bind.JAXBException; +import net.minidev.json.JSONArray; import org.jetbrains.annotations.NotNull; import org.slf4j.LoggerFactory; import org.springframework.context.MessageSource; @@ -323,7 +324,7 @@ public class ReferenceService { Map map = new HashMap<>(); source.getOptions().forEach(option -> { map.put(option.getCode(), option.getValue()); - map.put("label", source.getLabel()); + map.put("tag", source.getLabel()); map.put("key", source.getKey()); }); results.add(map); @@ -373,7 +374,7 @@ public class ReferenceService { .collect(Collectors.toList())); } if (fetchStrategy == FetchStrategy.FIRST) - return results.getResults().stream().peek(x -> x.put("label", label)).peek(x -> x.put("key", key)).collect(Collectors.toList()); + return results.getResults().stream().peek(x -> x.put("tag", label)).peek(x -> x.put("key", key)).collect(Collectors.toList()); if (results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set for (int i = 2; i <= results.getPagination().get("pages"); i++) @@ -394,7 +395,7 @@ public class ReferenceService { Results remainingResults = optionalResults.orElseGet(Results::new); remainingResults.getResults().addAll(results.getResults()); - return remainingResults.getResults().stream().peek(x -> x.put("label", label)).peek(x -> x.put("key", key)).collect(Collectors.toList()); + return remainingResults.getResults().stream().peek(x -> x.put("tag", label)).peek(x -> x.put("key", key)).collect(Collectors.toList()); } else { return new LinkedList<>(); @@ -404,17 +405,29 @@ public class ReferenceService { private String replaceLookupFields(String urlPath, ReferenceDefinitionSearchLookup lookup, String firstPage, List queries){ String completedPath = urlPath; - if (urlPath.contains("{like}")){ + if (urlPath.contains("openaire") || urlPath.contains("orcid") ){ if (lookup.getLike() != null) { + completedPath = completedPath.replace("{query}", lookup.getLike()); completedPath = completedPath.replace("{like}", lookup.getLike()); } else { + completedPath = completedPath.replace("{query}", "*"); completedPath = completedPath.replace("{like}", "*"); } } - if (urlPath.contains("{page}")){ + if (urlPath.contains("{like}")){ + if (lookup.getLike() != null) { + completedPath = completedPath.replace("{like}", lookup.getLike()); + } else { + completedPath = completedPath.replace("{like}", ""); + } + } + + if (urlPath.contains("{page}")) { if (lookup.getPage() != null && lookup.getPage().getOffset() > 0) { completedPath = completedPath.replace("{page}", String.valueOf(lookup.getPage().getOffset())); + } else if (firstPage != null) { + completedPath = completedPath.replace("{page}", firstPage); } else { completedPath = completedPath.replace("{page}", "1"); } @@ -428,13 +441,6 @@ public class ReferenceService { } } - if (urlPath.contains("openaire")){ - if (lookup.getLike() != null) { - completedPath = completedPath.replace("{query}", lookup.getLike()); - } else { - completedPath = completedPath.replace("{query}", "*"); - } - } return completedPath; } @@ -485,20 +491,76 @@ public class ReferenceService { private static List> parseData (DocumentContext jsonContext, ResultsConfigurationEntity resultsEntity) { List > rawData = jsonContext.read(resultsEntity.getResultsArrayPath()); List> parsedData = new ArrayList<>(); - rawData.forEach(stringObjectMap -> { + + for (Map stringObjectMap: rawData){ Map map = new HashMap<>(); - resultsEntity.getFieldsMapping().forEach(field ->{ + for(ResultFieldsMappingConfigurationEntity field: resultsEntity.getFieldsMapping()){ String pathValue = field.getResponsePath(); - if (stringObjectMap.containsKey(pathValue)){ - map.put(field.getCode(), stringObjectMap.get(pathValue)); + if (!pathValue.contains(".")){ + if (stringObjectMap.containsKey(pathValue)) { + //map.put(field.getCode(), stringObjectMap.get(pathValue)); + map.put(field.getCode(), normalizeValue(stringObjectMap.get(pathValue))); + } + }else { + if (stringObjectMap.containsKey(pathValue.split("\\.")[0])){ + String value = null; + Object fieldObj = stringObjectMap.get(pathValue.split("\\.")[0]); + if (fieldObj != null){ + if (fieldObj instanceof Map){ + Object o = ((Map) fieldObj).get(pathValue.split("\\.")[1]); + if(o instanceof String){ + value = (String)o; + } + else if(o instanceof Integer){ + value = String.valueOf(o); + } + } else if (fieldObj instanceof List) { + Object o = ((List>) fieldObj).get(0).get(pathValue.split("\\.")[1]); + if(o instanceof String){ + value = (String)o; + } + else if(o instanceof Integer){ + value = String.valueOf(o); + } + } + } + if (value != null){ + map.put(field.getCode(), value); + } + } } - }); + } parsedData.add(map); - - - }); + } return parsedData; } + private static String normalizeValue(Object value) { + if (value instanceof JSONArray) { + JSONArray jarr = (JSONArray) value; + if (jarr.get(0) instanceof String) { + return jarr.get(0).toString(); + } else { + for (Object o : jarr) { + if ((o instanceof Map) && ((Map) o).containsKey("content")) { + try { + return ((Map) o).get("content"); + } + catch (ClassCastException e){ + if(((Map) o).get("content") instanceof Integer) { + return String.valueOf(((Map) o).get("content")); + } + return null; + } + } + } + } + } else if (value instanceof Map) { + String key = ((Map)value).containsKey("$") ? "$" : "content"; + return ((Map)value).get(key); + } + return value != null ? value.toString() : null; + } + } diff --git a/dmp-frontend/src/app/core/model/reference-type/reference-type.ts b/dmp-frontend/src/app/core/model/reference-type/reference-type.ts index 95792312a..3feaad017 100644 --- a/dmp-frontend/src/app/core/model/reference-type/reference-type.ts +++ b/dmp-frontend/src/app/core/model/reference-type/reference-type.ts @@ -26,6 +26,7 @@ export interface ReferenceTypeSourceBaseConfiguration extends ReferenceTypeSourc key: string; label: string; ordinal: number; + dependencies: ReferenceTypeSourceBaseDependency[]; } export interface ReferenceTypeSourceExternalApiConfiguration{ @@ -77,6 +78,19 @@ export interface ReferenceTypeStaticOption{ value: string; } +export interface ReferenceTypeSourceBaseDependency{ + referenceTypeCode: string; + key: string; + required: boolean; + properties: DependencyProperty[]; +} + +export interface DependencyProperty{ + code: string; + target: string; + required: boolean; +} + // Persist @@ -103,6 +117,7 @@ export interface ReferenceTypeSourceBaseConfigurationPersist extends ReferenceTy key: string; label: string; ordinal: number; + dependencies?: ReferenceTypeSourceBaseDependencyPersist[]; } export interface ReferenceTypeSourceExternalApiConfigurationPersist{ @@ -155,3 +170,16 @@ export interface ReferenceTypeStaticOptionPersist{ code: string; value: string; } + +export interface ReferenceTypeSourceBaseDependencyPersist{ + referenceTypeCode: string; + key: string; + required: boolean; + properties: DependencyPropertyPersist[]; +} + +export interface DependencyPropertyPersist{ + code: string; + target: string; + required: boolean; +} diff --git a/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts b/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts index b83bd3539..8aebac210 100644 --- a/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts +++ b/dmp-frontend/src/app/core/services/reference-type/reference-type.service.ts @@ -8,6 +8,11 @@ import { ConfigurationService } from '../configuration/configuration.service'; import { BaseHttpV2Service } from '../http/base-http-v2.service'; import { ReferenceTypeLookup } from '@app/core/query/reference-type.lookup'; import { ReferenceType, ReferenceTypePersist } from '@app/core/model/reference-type/reference-type'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { IsActive } from '@app/core/common/enum/is-active.enum'; +import { nameof } from 'ts-simple-nameof'; +import { ReferenceTypeEditorResolver } from '@app/ui/admin/reference-type/editor/reference-type-editor.resolver'; @Injectable() export class ReferenceTypeService { @@ -51,4 +56,59 @@ export class ReferenceTypeService { catchError((error: any) => throwError(error))); } + // LOOKUP + + public static DefaultReferenceTypeLookup(): ReferenceTypeLookup{ + const lookup = new ReferenceTypeLookup(); + + lookup.project = { + fields: [ + ...ReferenceTypeEditorResolver.lookupFields() + ] + }; + lookup.order = { items: [nameof(x => x.code)] }; + lookup.page = { offset: 0, size: 100 }; + lookup.isActive = [IsActive.Active]; + return lookup; + } + + // + // Autocomplete Commons + // + // + public singleAutocompleteConfiguration: SingleAutoCompleteConfiguration = { + initialItems: (data?: any) => this.query(this.buildAutocompleteLookup()).pipe(map(x => x.items)), + filterFn: (searchQuery: string, data?: any) => this.query(this.buildAutocompleteLookup(searchQuery)).pipe(map(x => x.items)), + getSelectedItem: (selectedItem: any) => this.query(this.buildAutocompleteLookup(null, null, [selectedItem])).pipe(map(x => x.items[0])), + displayFn: (item: ReferenceType) => item.name, + titleFn: (item: ReferenceType) => item.name, + valueAssign: (item: ReferenceType) => item.id, + }; + + public multipleAutocompleteConfiguration: MultipleAutoCompleteConfiguration = { + initialItems: (excludedItems: any[], data?: any) => this.query(this.buildAutocompleteLookup(null, excludedItems ? excludedItems : null)).pipe(map(x => x.items)), + filterFn: (searchQuery: string, excludedItems: any[]) => this.query(this.buildAutocompleteLookup(searchQuery, excludedItems)).pipe(map(x => x.items)), + getSelectedItems: (selectedItems: any[]) => this.query(this.buildAutocompleteLookup(null, null, selectedItems)).pipe(map(x => x.items)), + displayFn: (item: ReferenceType) => item.name, + titleFn: (item: ReferenceType) => item.name, + valueAssign: (item: ReferenceType) => item.id, + }; + + private buildAutocompleteLookup(like?: string, excludedIds?: Guid[], ids?: Guid[]): ReferenceTypeLookup { + const lookup: ReferenceTypeLookup = new ReferenceTypeLookup(); + lookup.page = { size: 100, offset: 0 }; + if (excludedIds && excludedIds.length > 0) { lookup.excludedIds = excludedIds; } + if (ids && ids.length > 0) { lookup.ids = ids; } + lookup.isActive = [IsActive.Active]; + lookup.project = { + fields: [ + nameof(x => x.id), + nameof(x => x.name) + ] + }; + lookup.order = { items: [nameof(x => x.name)] }; + if (like) { lookup.like = this.filterService.transformLike(like); } + return lookup; + } + } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index e5485c9f9..b359d8171 100644 --- a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts +++ b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts @@ -17,6 +17,9 @@ import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description import { DmpBlueprintSystemFieldType } from '@app/core/common/enum/dmp-blueprint-system-field-type'; import { DmpBlueprintStatus } from '@app/core/common/enum/dmp-blueprint-status'; import { DescriptionTemplateStatus } from '@app/core/common/enum/description-template-status'; +import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; +import { ReferenceTypeSourceType } from '@app/core/common/enum/reference-type-source-type'; +import { ReferenceTypeExternalApiHTTPMethodType } from '@app/core/common/enum/reference-type-external-api-http-method-type'; @Injectable() export class EnumUtils { @@ -235,4 +238,26 @@ export class EnumUtils { case DmpBlueprintExtraFieldDataType.ExternalAutocomplete: return this.language.instant('TYPES.DMP-BLUEPRINT-EXTRA-FIELD-DATA-TYPE.EXTERNAL-AUTOCOMPLETE'); } } + + toReferenceTypeSourceTypeString(status: ReferenceTypeSourceType): string { + switch (status) { + case ReferenceTypeSourceType.API: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.API'); + case ReferenceTypeSourceType.STATIC: return this.language.instant('TYPES.REFERENCE-TYPE-SOURCE-TYPE.STATIC'); + } + } + + toReferenceFieldDataTypeString(status: ReferenceFieldDataType): string { + switch (status) { + case ReferenceFieldDataType.Text: return this.language.instant('TYPES.REFERENCE-FIELD-DATA-TYPE.TEXT'); + case ReferenceFieldDataType.Date: return this.language.instant('TYPES.REFERENCE-FIELD-DATA-TYPE.DATE'); + } + } + + + toReferenceTypeExternalApiHTTPMethodTypeString(status: ReferenceTypeExternalApiHTTPMethodType): string { + switch (status) { + case ReferenceTypeExternalApiHTTPMethodType.GET: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.GET'); + case ReferenceTypeExternalApiHTTPMethodType.POST: return this.language.instant('TYPES.REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE.POST'); + } + } } diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html index 1f621af05..90eec2012 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.html @@ -1,4 +1,4 @@ -
+
@@ -16,12 +16,6 @@ {{'REFERENCE-TYPE-EDITOR.ACTIONS.DELETE' | translate}}
-
+
@@ -65,16 +60,15 @@ - Reference Type Fields + -
-
-
+
+
@@ -83,7 +77,7 @@
-
@@ -101,7 +95,7 @@
- Description + {{'REFERENCE-TYPE-EDITOR.FIELDS.DESCRIPTION' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -119,8 +113,8 @@ {{'REFERENCE-TYPE-EDITOR.FIELDS.DATA-TYPE' | translate}} - - {{dataType.name}} + + {{enumUtils.toReferenceFieldDataTypeString(fieldDataType)}} @@ -141,16 +135,16 @@ - Reference Type Source + - +
-
+
@@ -158,7 +152,7 @@ {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-CONFIGURATION' | translate}} {{sourceIndex + 1}}
-
@@ -190,10 +184,10 @@
- Source Type + {{'REFERENCE-TYPE-EDITOR.FIELDS.SOURCE-TYPE' | translate}} - - {{vis.name}} + + {{enumUtils.toReferenceTypeSourceTypeString(sourceType)}} @@ -201,7 +195,7 @@
-
+
{{'REFERENCE-TYPE-EDITOR.FIELDS.URL' | translate}} @@ -220,7 +214,7 @@
- Content Type + {{'REFERENCE-TYPE-EDITOR.FIELDS.CONTENT-TYPE' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -228,7 +222,7 @@
- First Page + {{'REFERENCE-TYPE-EDITOR.FIELDS.FIRST-PAGE' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -236,10 +230,10 @@
- HTTP Method + {{'REFERENCE-TYPE-EDITOR.FIELDS.HTTP-METHOD' | translate}} - - {{vis.name}} + + {{enumUtils.toReferenceTypeExternalApiHTTPMethodTypeString(httpMethod)}} @@ -247,8 +241,8 @@
- - Request Body + + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUEST-BODY' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -256,7 +250,7 @@
- Filter Type + {{'REFERENCE-TYPE-EDITOR.FIELDS.FILTER-TYPE' | translate}}ype {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -266,7 +260,7 @@

{{'REFERENCE-TYPE-EDITOR.FIELDS.RESULTS' | translate}}

- Results Path + {{'REFERENCE-TYPE-EDITOR.FIELDS.RESULTS-PATH' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -274,7 +268,7 @@
-
+
@@ -284,7 +278,7 @@
-
+ + +
{{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} - + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -336,10 +332,10 @@
- Method + {{'REFERENCE-TYPE-EDITOR.FIELDS.HTTP-METHOD' | translate}} - - {{vis.name}} + + {{enumUtils.toReferenceTypeExternalApiHTTPMethodTypeString(httpMethod)}} @@ -348,7 +344,7 @@
- Token Path + {{'REFERENCE-TYPE-EDITOR.FIELDS.TOKEN-PATH' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -356,7 +352,7 @@
- Request Body + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUEST-BODY' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -364,7 +360,7 @@
- Type + {{'REFERENCE-TYPE-EDITOR.FIELDS.TYPE' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -374,8 +370,8 @@

{{'REFERENCE-TYPE-EDITOR.FIELDS.QUERIES' | translate}}

-
-
+
+
@@ -383,44 +379,46 @@

{{'REFERENCE-TYPE-EDITOR.FIELDS.QUERY' | translate}} {{queryIndex + 1}}

-
-
- - Condition - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Separator - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - Value - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - -
-
- - {{'REFERENCE-TYPE-EDITOR.FIELDS.ORDINAL' | translate}} - - - {{'GENERAL.VALIDATION.REQUIRED' | translate}} - +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CONDITION' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.SEPARATOR' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.VALUE' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.ORDINAL' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
@@ -428,10 +426,10 @@
-
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.OPTIONS' | translate}}

-
+
@@ -441,7 +439,7 @@
-
+ +
{{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} - + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -481,9 +481,120 @@
-
- + +

{{'REFERENCE-TYPE-EDITOR.FIELDS.DEPENDENCIES' | translate}} + +

+
+
+
+ +
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.DEPENDENCY' | translate}} {{dependencyIndex + 1}}

+
+
+ +
+
+
+ +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} + + + {{referenceType.code}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.KEY' | translate}} + + + {{key}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUIRED' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ +

{{'REFERENCE-TYPE-EDITOR.FIELDS.PROPERTIES' | translate}} + +

+
+
+
+
+
+

{{'REFERENCE-TYPE-EDITOR.FIELDS.PROPERTY' | translate}} {{propertyIndex + 1}}

+
+
+ +
+
+
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.CODE' | translate}} + + + {{code}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.TARGET' | translate}} + + + {{targetCode}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + {{'REFERENCE-TYPE-EDITOR.FIELDS.REQUIRED' | translate}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ +
+
+
+
+
+
+
diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.scss b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.scss index 4372160ca..a6f1e5ed7 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.scss @@ -1,4 +1,4 @@ -.dmp-blueprint-editor { +.reference-type-editor { margin-top: 1.3rem; margin-left: 1em; margin-right: 3em; diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts index ec0baa33b..cce9f394f 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.component.ts @@ -25,27 +25,13 @@ import { TranslateService } from '@ngx-translate/core'; import { map, takeUntil } from 'rxjs/operators'; import { ReferenceTypeEditorResolver } from './reference-type-editor.resolver'; import { ReferenceTypeEditorService } from './reference-type-editor.service'; -import { QueryConfigEditorModel, ReferenceTypeEditorModel, ReferenceTypeFieldEditorModel, ReferenceTypeSourceBaseConfigurationEditorModel, ReferenceTypeStaticOptionEditorModel, ResultFieldsMappingConfigurationEditorModel } from './reference-type-editor.model'; +import { DependencyPropertyEditorModel, QueryConfigEditorModel, ReferenceTypeEditorModel, ReferenceTypeFieldEditorModel, ReferenceTypeSourceBaseConfigurationEditorModel, ReferenceTypeSourceBaseDependencyEditorModel, ReferenceTypeStaticOptionEditorModel, ResultFieldsMappingConfigurationEditorModel } from './reference-type-editor.model'; import { ReferenceFieldDataType } from '@app/core/common/enum/reference-field-data-type'; import { ReferenceTypeSourceType } from '@app/core/common/enum/reference-type-source-type'; import { ReferenceTypeExternalApiHTTPMethodType } from '@app/core/common/enum/reference-type-external-api-http-method-type'; +import { ReferenceTypeLookup } from '@app/core/query/reference-type.lookup'; -export interface visibleDataType { - name: string; - type: ReferenceFieldDataType; -} - -export interface visibleSourceType { - name: string; - type: ReferenceTypeSourceType; -} - -export interface visibleHTTPMethodType { - name: string; - type: ReferenceTypeExternalApiHTTPMethodType; -} - @Component({ selector: 'app-reference-type-editor-component', templateUrl: 'reference-type-editor.component.html', @@ -58,7 +44,17 @@ export class ReferenceTypeEditorComponent extends BaseEditor source.dependencies.forEach(dependency => { + this.selectedReferenceTypeChanged(dependency.referenceTypeCode); + })); + this.editorModel.definition.sources.forEach(source => { + if(source.type == ReferenceTypeSourceType.STATIC){ + source.options.forEach(option => { + if(!this.propertyCodes.includes(option.code)){ + this.propertyCodes.push(option.code); + } + }); + }else{ + source.results.fieldsMapping.forEach(fieldMapping => { + if(!this.propertyCodes.includes(fieldMapping.code)){ + this.propertyCodes.push(fieldMapping.code); + } + }); + } + }); + } + this.isDeleted = data ? data.isActive === IsActive.Inactive : false; this.buildForm(); } catch (error) { @@ -167,7 +170,7 @@ export class ReferenceTypeEditorComponent extends BaseEditor void): void { - const formData = this.formService.getValue(this.formGroup.value) as ReferenceTypePersist; + const formData = this.formService.getValue(this.formGroup.getRawValue()) as ReferenceTypePersist; console.log(formData); this.referenceTypeService.persist(formData) .pipe(takeUntil(this._destroyed)).subscribe( @@ -221,36 +224,54 @@ export class ReferenceTypeEditorComponent extends BaseEditor 0){ + if(this.propertyCodes.includes(fieldCode)){ + this.propertyCodes.splice(this.propertyCodes.indexOf(fieldCode),1); + } + } + (this.formGroup.get('definition').get('fields') as FormArray).removeAt(fieldIndex); - } - dropFields(event: CdkDragDrop) { - const fieldssFormArray = (this.formGroup.get('definition').get('fields') as FormArray); + const sourceFormArray = ((this.formGroup.get('definition').get('sources') as FormArray)); + for(let i=0; i 0){ - for(let i =0; i < sourceSize; i++){ - this.addFieldMapping(i, fieldssFormArray.at(i).get('code').value); - this.addOption(i, fieldssFormArray.at(i).get('code').value); + if(fieldsFormArray.length > 0){ + for(let j=0; j< sourcesFormArray.length; j++){ + for(let i =0; i < fieldsFormArray.length; i++){ + this.addFieldMapping(j, fieldsFormArray.at(i).get('code').value); + this.addOption(j, fieldsFormArray.at(i).get('code').value); + + if(!this.propertyCodes.includes(fieldsFormArray.at(i).get('code').value)){ + this.propertyCodes.push(fieldsFormArray.at(i).get('code').value); + } + } } } } @@ -261,16 +282,20 @@ export class ReferenceTypeEditorComponent extends BaseEditor { - this.addFieldMapping(sourceIndex, null); - this.addOption(sourceIndex, null); - }); - const fieldsSize = (this.formGroup.get('definition').get('fields') as FormArray).length; - if(fieldsSize && fieldsSize > 0){ - for(let i =0; i < fieldsSize; i++){ - this.addFieldMapping(sourceIndex, null); - this.addOption(sourceIndex, null); + this.addFieldMapping(sourceIndex, "reference_id"); + this.addFieldMapping(sourceIndex, "label"); + this.addFieldMapping(sourceIndex, "description"); + + this.addOption(sourceIndex, "reference_id"); + this.addOption(sourceIndex, "label"); + this.addOption(sourceIndex, "description"); + + const fieldsFormArray = (this.formGroup.get('definition').get('fields') as FormArray); + if(fieldsFormArray && fieldsFormArray.length > 0){ + for(let i =0; i < fieldsFormArray.length; i++){ + this.addFieldMapping(sourceIndex, fieldsFormArray.at(i).get('code').value); + this.addOption(sourceIndex, fieldsFormArray.at(i).get('code').value); } } } @@ -285,22 +310,19 @@ export class ReferenceTypeEditorComponent extends BaseEditor0){ for(let i=0; i) { - const fieldssFormArray = (this.formGroup.get('definition').get('sources').get('fieldsMapping') as FormArray); - - moveItemInArray(fieldssFormArray.controls, event.previousIndex, event.currentIndex); - fieldssFormArray.updateValueAndValidity(); - } - // // @@ -326,16 +341,9 @@ export class ReferenceTypeEditorComponent extends BaseEditor) { - const fieldssFormArray = (this.formGroup.get('definition').get('sources').get('queries') as FormArray); - - moveItemInArray(fieldssFormArray.controls, event.previousIndex, event.currentIndex); - fieldssFormArray.updateValueAndValidity(); + formArray.removeAt(queryIndex); } // Options @@ -346,15 +354,101 @@ export class ReferenceTypeEditorComponent extends BaseEditor0){ for(let i=0; i { + this.referenceTypes = response.items as ReferenceType[]; + }); + } + + selectedReferenceTypeChanged(code: string): void{ + this.selectedReferenceTypeCode = code; + this.sourceKeys = []; + this.targetPropertyCodes = []; + + const lookup = ReferenceTypeService.DefaultReferenceTypeLookup(); + lookup.codes = [this.selectedReferenceTypeCode]; + + this.referenceTypeService.query(lookup) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + if(response.count ==1){ + const referenceType = response.items[0] as ReferenceType; + referenceType.definition.sources.forEach(source => { + if(!this.sourceKeys.includes(source.key)) this.sourceKeys.push(source.key) + if(source.type == ReferenceTypeSourceType.API){ + source.results.fieldsMapping.forEach(target => { + if(!this.targetPropertyCodes.includes(target.code)) this.targetPropertyCodes.push(target.code) + }); + }else{ + source.options.forEach(target => { + if(!this.targetPropertyCodes.includes(target.code)) this.targetPropertyCodes.push(target.code) + }); + } + }); + } + }); + + } + + // Properties + addProperty(sourceIndex: number, dependencyIndex: number): void{ + + const optionFormArray = ((this.formGroup.get('definition').get('sources') as FormArray).at(sourceIndex).get('options') as FormArray); + + for(let i =0; i < optionFormArray.length; i++){ + if(!this.propertyCodes.includes(optionFormArray.at(i).get('code').getRawValue())){ + this.propertyCodes.push(optionFormArray.at(i).get('code').getRawValue()); + } + } + + if (((this.formGroup.get('definition').get('sources') as FormArray).at(sourceIndex).get('dependencies') as FormArray).at(dependencyIndex).get('referenceTypeCode').value == null){ + return ; + } + + const property: DependencyPropertyEditorModel = new DependencyPropertyEditorModel(); + (((this.formGroup.get('definition').get('sources') as FormArray).at(sourceIndex).get('dependencies') as FormArray).at(dependencyIndex).get("properties") as FormArray).push(property.buildForm()); + } + + removeProperty(sourceIndex: number, dependencyIndex: number, propertyIndex: number): void { + const formArray = (((this.formGroup.get('definition').get('sources') as FormArray).at(sourceIndex).get('dependencies') as FormArray).at(dependencyIndex).get("properties") as FormArray); + formArray.removeAt(propertyIndex); } } diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts index e6bbf7176..fb155e84b 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.model.ts @@ -2,7 +2,7 @@ import { UntypedFormBuilder, UntypedFormGroup, Validators } from "@angular/forms import { ReferenceFieldDataType } from "@app/core/common/enum/reference-field-data-type"; import { ReferenceTypeExternalApiHTTPMethodType } from "@app/core/common/enum/reference-type-external-api-http-method-type"; import { ReferenceTypeSourceType } from "@app/core/common/enum/reference-type-source-type"; -import { ReferenceType, ReferenceTypeDefinition, ReferenceTypeDefinitionPersist, ReferenceTypePersist, ReferenceTypeFieldPersist,ReferenceTypeField, AuthenticationConfiguration, AuthenticationConfigurationPersist, QueryConfigPersist, QueryConfig, ResultsConfigurationPersist, ResultFieldsMappingConfigurationPersist, ResultsConfiguration, ResultFieldsMappingConfiguration, ReferenceTypeSourceBaseConfigurationPersist, ReferenceTypeSourceBaseConfiguration, ReferenceTypeStaticOptionPersist, ReferenceTypeStaticOption } from "@app/core/model/reference-type/reference-type"; +import { ReferenceType, ReferenceTypeDefinition, ReferenceTypeDefinitionPersist, ReferenceTypePersist, ReferenceTypeFieldPersist,ReferenceTypeField, AuthenticationConfiguration, AuthenticationConfigurationPersist, QueryConfigPersist, QueryConfig, ResultsConfigurationPersist, ResultFieldsMappingConfigurationPersist, ResultsConfiguration, ResultFieldsMappingConfiguration, ReferenceTypeSourceBaseConfigurationPersist, ReferenceTypeSourceBaseConfiguration, ReferenceTypeStaticOptionPersist, ReferenceTypeStaticOption, DependencyPropertyPersist, DependencyProperty, ReferenceTypeSourceBaseDependency, ReferenceTypeSourceBaseDependencyPersist } from "@app/core/model/reference-type/reference-type"; import { BaseEditorModel } from "@common/base/base-form-editor-model"; import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; @@ -211,6 +211,8 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc options : ReferenceTypeStaticOptionEditorModel[] = []; + dependencies : ReferenceTypeSourceBaseDependencyEditorModel[] = []; + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); constructor( @@ -235,7 +237,15 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc if (item.auth) this.auth = new AuthenticationConfigurationEditorModel().fromModel(item.auth); if(item.queries) { item.queries.map(x => this.queries.push(new QueryConfigEditorModel().fromModel(x))); } - if(item.options) { item.options.map(x => this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel(x))); } + if(item.options) { + item.options.map(x => this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel(x))); + } else { + this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({code: 'reference_id', value: undefined})); + this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({code: 'label', value: undefined})); + this.options.push(new ReferenceTypeStaticOptionEditorModel().fromModel({code: 'description', value: undefined})); + } + + if(item.dependencies) { item.dependencies.map(x => this.dependencies.push(new ReferenceTypeSourceBaseDependencyEditorModel().fromModel(x))); } } return this; } @@ -282,7 +292,6 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc }), context.getValidation('queries') ) ), - options: this.formBuilder.array( (this.options ?? []).map( (item, index) => new ReferenceTypeStaticOptionEditorModel( @@ -291,6 +300,15 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc rootPath: `options[${index}].` }), context.getValidation('options') ) + ), + dependencies: this.formBuilder.array( + (this.dependencies ?? []).map( + (item, index) => new ReferenceTypeSourceBaseDependencyEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `dependencies[${index}].` + }), context.getValidation('dependencies') + ) ) }); @@ -312,7 +330,7 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc baseValidationArray.push({ key: 'url', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}url`)] }); baseValidationArray.push({ key: 'paginationPath', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}paginationPath`)] }); baseValidationArray.push({ key: 'contentType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}contentType`)] }); - baseValidationArray.push({ key: 'firstPage', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}firstPage`)] }); + baseValidationArray.push({ key: 'firstPage', validators: [Validators.pattern("^[0-9]*$"), BackendErrorValidator(validationErrorModel, `${rootPath}firstPage`)] }); baseValidationArray.push({ key: 'httpMethod', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}httpMethod`)] }); baseValidationArray.push({ key: 'requestBody', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}requestBody`)] }); baseValidationArray.push({ key: 'filterType', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}filterType`)] }); @@ -321,6 +339,8 @@ export class ReferenceTypeSourceBaseConfigurationEditorModel implements Referenc baseValidationArray.push({ key: 'options', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}options`)] }); + baseValidationArray.push({ key: 'dependencies', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}dependencies`)] }); + baseContext.validation = baseValidationArray; return baseContext; } @@ -339,6 +359,11 @@ export class ResultsConfigurationEditorModel implements ResultsConfigurationPers fromModel(item: ResultsConfiguration): ResultsConfigurationEditorModel { this.resultsArrayPath = item.resultsArrayPath; if(item.fieldsMapping) { item.fieldsMapping.map(x => this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel().fromModel(x))); } + else { + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel().fromModel({code: 'reference_id', responsePath: undefined})); + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel().fromModel({code: 'label', responsePath: undefined})); + this.fieldsMapping.push(new ResultFieldsMappingConfigurationEditorModel().fromModel({code: 'description', responsePath: undefined})); + } return this; } @@ -417,7 +442,7 @@ export class ResultFieldsMappingConfigurationEditorModel implements ResultFields } return this.formBuilder.group({ - code: [{ value: "code", disabled: disabled }, context.getValidation('code').validators], + code: [{ value: "code", disabled: true }, context.getValidation('code').validators], responsePath: [{ value: this.responsePath, disabled: disabled }, context.getValidation('responsePath').validators], }); } @@ -594,7 +619,7 @@ export class ReferenceTypeStaticOptionEditorModel implements ReferenceTypeStatic } return this.formBuilder.group({ - code: [{ value: this.code, disabled: disabled }, context.getValidation('code').validators], + code: [{ value: this.code, disabled: true }, context.getValidation('code').validators], value: [{ value: this.value, disabled: disabled }, context.getValidation('value').validators], }); } @@ -610,6 +635,132 @@ export class ReferenceTypeStaticOptionEditorModel implements ReferenceTypeStatic baseValidationArray.push({ key: 'code', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); baseValidationArray.push({ key: 'value', validators: [BackendErrorValidator(validationErrorModel, `${rootPath}value`)] }); + baseContext.validation = baseValidationArray; + return baseContext; + } +} + +export class ReferenceTypeSourceBaseDependencyEditorModel implements ReferenceTypeSourceBaseDependencyPersist { + public referenceTypeCode: string; + public key: string; + public required = true; + public properties: DependencyPropertyEditorModel[] = []; + + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: ReferenceTypeSourceBaseDependency): ReferenceTypeSourceBaseDependencyEditorModel { + this.referenceTypeCode = item.referenceTypeCode; + this.key = item.key; + this.required = item.required; + if(item.properties) { item.properties.map(x => this.properties.push(new DependencyPropertyEditorModel().fromModel(x))); } + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = ReferenceTypeSourceBaseDependencyEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + referenceTypeCode: [{ value: this.referenceTypeCode, disabled: disabled }, context.getValidation('referenceTypeCode').validators], + key: [{ value: this.key, disabled: disabled }, context.getValidation('key').validators], + required: [{ value: this.required, disabled: true }, context.getValidation('required').validators], + properties: this.formBuilder.array( + (this.properties ?? []).map( + (item, index) => new DependencyPropertyEditorModel( + this.validationErrorModel + ).fromModel(item).buildForm({ + rootPath: `properties[${index}].` + }), context.getValidation('properties') + ) + ), + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'referenceTypeCode', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}referenceTypeCode`)] }); + baseValidationArray.push({ key: 'key', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}key`)] }); + baseValidationArray.push({ key: 'required', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}required`)] }); + baseValidationArray.push({ key: 'properties', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}properties`)] }); + + baseContext.validation = baseValidationArray; + return baseContext; + } +} + +export class DependencyPropertyEditorModel implements DependencyPropertyPersist { + public code: string; + public target: string; + public required = true; + + + protected formBuilder: UntypedFormBuilder = new UntypedFormBuilder(); + + constructor( + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel() + ) { } + + fromModel(item: DependencyProperty): DependencyPropertyEditorModel { + this.code = item.code; + this.target = item.target; + this.required = item.required; + + return this; + } + + buildForm(params?: { + context?: ValidationContext, + disabled?: boolean, + rootPath?: string + }): UntypedFormGroup { + let { context = null, disabled = false, rootPath } = params ?? {} + if (context == null) { + context = DependencyPropertyEditorModel.createValidationContext({ + validationErrorModel: this.validationErrorModel, + rootPath + }); + } + + return this.formBuilder.group({ + code: [{ value: this.code, disabled: disabled }, context.getValidation('code').validators], + target: [{ value: this.target, disabled: disabled }, context.getValidation('target').validators], + required: [{ value: this.required, disabled: true }, context.getValidation('required').validators], + }); + } + + static createValidationContext(params: { + rootPath?: string, + validationErrorModel: ValidationErrorModel + }): ValidationContext { + const { rootPath = '', validationErrorModel } = params; + + const baseContext: ValidationContext = new ValidationContext(); + const baseValidationArray: Validation[] = new Array(); + baseValidationArray.push({ key: 'code', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}code`)] }); + baseValidationArray.push({ key: 'target', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}target`)] }); + baseValidationArray.push({ key: 'required', validators: [Validators.required, BackendErrorValidator(validationErrorModel, `${rootPath}required`)] }); + baseContext.validation = baseValidationArray; return baseContext; } diff --git a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts index c8d4a94bb..119c0d0d5 100644 --- a/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/admin/reference-type/editor/reference-type-editor.resolver.ts @@ -1,6 +1,6 @@ import { Injectable } from '@angular/core'; import { ActivatedRouteSnapshot, RouterStateSnapshot } from '@angular/router'; -import { AuthenticationConfiguration, QueryConfig, ReferenceType, ReferenceTypeDefinition, ReferenceTypeField, ReferenceTypeSourceBaseConfiguration, ResultsConfiguration, ResultFieldsMappingConfiguration, ReferenceTypeStaticOption } from '@app/core/model/reference-type/reference-type'; +import { AuthenticationConfiguration, QueryConfig, ReferenceType, ReferenceTypeDefinition, ReferenceTypeField, ReferenceTypeSourceBaseConfiguration, ResultsConfiguration, ResultFieldsMappingConfiguration, ReferenceTypeStaticOption, ReferenceTypeSourceBaseDependency, DependencyProperty } from '@app/core/model/reference-type/reference-type'; import { ReferenceTypeService } from '@app/core/services/reference-type/reference-type.service'; import { BreadcrumbService } from '@app/ui/misc/breadcrumb/breadcrumb.service'; import { BaseEditorResolver } from '@common/base/base-editor.resolver'; @@ -59,6 +59,14 @@ export class ReferenceTypeEditorResolver extends BaseEditorResolver { [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.code)].join('.'), [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.options),nameof(x => x.value)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.referenceTypeCode)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.key)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.required)].join('.'), + + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.properties), nameof(x => x.code)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.properties), nameof(x => x.target)].join('.'), + [nameof(x => x.definition), nameof(x => x.sources), nameof(x => x.dependencies),nameof(x => x.properties), nameof(x => x.required)].join('.'), + nameof(x => x.createdAt), nameof(x => x.updatedAt), nameof(x => x.isActive) diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index d028ec3ab..cafd8167c 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -1125,17 +1125,43 @@ "DATA-TYPE": "Data Type", "KEY": "Key", "LABEL": "Label", + "DESCRIPTION": "Description", "ORDINAL": "Ordinal", "URL": "Url", - "PAGINATION-PATH": "Pagination Path" + "SOURCE-TYPE": "Source Type", + "PAGINATION-PATH": "Pagination Path", + "CONTENT-TYPE": "Content Type", + "HTTP-METHOD": "HTTP Method", + "FIRST-PAGE": "First Page", + "REQUEST-BODY": "Request Body", + "FILTER-TYPE": "Filter Type", + "RESULTS-PATH": "Results Path", + "TOKEN-PATH": "Token Path", + "TYPE": "Type", + "CONDITION": "Condition", + "SEPARATOR": "Separator", + "DEPENDENCIES": "Dependencies", + "DEPENDENCY": "Dependency", + "REQUIRED": "Required", + "PROPERTIES": "Properties", + "PROPERTY": "Property", + "TARGET": "Target" + }, "ACTIONS": { "SAVE": "Save", "CANCEL": "Cancel", "DELETE": "Delete", "ADD-FIELD": "Add Field", - "ADD-CONFIG": "Add Config", - "ADD-QUERY": "Add Query" + "REMOVE-FIELD": "Remove Field", + "ADD-SOURCE": "Add Source", + "REMOVE-SOURCE": "Remove Source", + "ADD-QUERY": "Add Query", + "REMOVE-QUERY": "Remove Query", + "ADD-DEPENDENCY": "Add Dependency", + "REMOVE-DEPENDENCY": "Remove Dependency", + "ADD-PROPERTY": "Add property", + "REMOVE-PROPERTY": "Remove property" } }, "CONFIRM-DELETE-DIALOG": { @@ -1734,6 +1760,18 @@ "NUMBER": "Number", "TEXT": "Text", "EXTERNAL-AUTOCOMPLETE": "External AutoComplete" + }, + "REFERENCE-FIELD-DATA-TYPE":{ + "TEXT": "Text", + "DATE": "Date" + }, + "REFERENCE-TYPE-SOURCE-TYPE":{ + "API": "API", + "STATIC": "Static" + }, + "REFERENCE-TYPE-EXTERNAL-API-HTTP-METHOD-TYPE":{ + "GET": "GET", + "POST": "POST" } }, "ADDRESEARCHERS-EDITOR": {