diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java new file mode 100644 index 000000000..c7f21914c --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java @@ -0,0 +1,6 @@ +package eu.eudat.data.dao.criteria; + +import eu.eudat.data.entities.DMPProfile; + +public class DataManagementPlanBlueprintCriteria extends Criteria { +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java index de7119428..c859cb2c8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileCriteria.java @@ -1,13 +1,13 @@ package eu.eudat.data.dao.criteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import java.util.Date; import java.util.List; import java.util.UUID; -public class DatasetProfileCriteria extends Criteria { +public class DatasetProfileCriteria extends Criteria { public enum DatasetProfileFilter { DMPs((short) 0), Datasets((short) 1); @@ -25,7 +25,7 @@ public class DatasetProfileCriteria extends Criteria { case 1: return Datasets; default: - throw new RuntimeException("Unsupported DatasetProfile filter"); + throw new RuntimeException("Unsupported DescriptionTemplate filter"); } } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java index df4978858..9e1d5d9e2 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DatasetProfileWizardCriteria.java @@ -1,11 +1,11 @@ package eu.eudat.data.dao.criteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import java.util.UUID; -public class DatasetProfileWizardCriteria extends Criteria { +public class DatasetProfileWizardCriteria extends Criteria { private UUID id; public UUID getId() { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java index 52eae6a2a..36fc58752 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDao.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.DMPProfile; @@ -15,4 +16,6 @@ public interface DMPProfileDao extends DatabaseAccessLayer { QueryableList getWithCriteria(DataManagementPlanProfileCriteria criteria); + QueryableList getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria); + } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java index b5198d86d..671fc8b67 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPProfileDaoImpl.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; import eu.eudat.data.dao.criteria.DataManagementPlanProfileCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DMPProfile; @@ -65,4 +66,13 @@ public class DMPProfileDaoImpl extends DatabaseAccess implements DMP query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue()))); return query; } + + @Override + public QueryableList getWithCriteriaBlueprint(DataManagementPlanBlueprintCriteria criteria){ + QueryableList query = getDatabaseService().getQueryable(DMPProfile.class); + if (criteria.getLike() != null && !criteria.getLike().isEmpty()) + query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%")); + query.where(((builder, root) -> builder.notEqual(root.get("status"), DMPProfile.Status.DELETED.getValue()))); + return query; + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java index ed76b6376..a0f7f6afa 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetExternalDatasetDaoImpl.java @@ -3,7 +3,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; import eu.eudat.data.entities.DatasetExternalDataset; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.annotation.Async; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java index d2b712ea2..35f508436 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java @@ -2,20 +2,23 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.DescriptionTemplateType; import eu.eudat.queryable.QueryableList; import java.util.List; import java.util.UUID; -public interface DatasetProfileDao extends DatabaseAccessLayer { +public interface DatasetProfileDao extends DatabaseAccessLayer { - QueryableList getWithCriteria(DatasetProfileCriteria criteria); + QueryableList getWithCriteria(DatasetProfileCriteria criteria); - QueryableList getAll(); + QueryableList getAll(); - QueryableList getAuthenticated(QueryableList query, UUID principal, List roles); + QueryableList getAuthenticated(QueryableList query, UUID principal, List roles); - List getAllIds(); + List getAllIds(); + + Long countWithType(DescriptionTemplateType type); } \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java index b6cbb445b..3ba9fe758 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java @@ -3,8 +3,8 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.DescriptionTemplateType; import eu.eudat.queryable.QueryableList; import eu.eudat.queryable.types.FieldSelectionType; import eu.eudat.queryable.types.SelectionField; @@ -21,16 +21,16 @@ import java.util.UUID; import java.util.concurrent.CompletableFuture; @Component("datasetProfileDao") -public class DatasetProfileDaoImpl extends DatabaseAccess implements DatasetProfileDao { +public class DatasetProfileDaoImpl extends DatabaseAccess implements DatasetProfileDao { @Autowired - public DatasetProfileDaoImpl(DatabaseService databaseService) { + public DatasetProfileDaoImpl(DatabaseService databaseService) { super(databaseService); } @Override - public QueryableList getWithCriteria(DatasetProfileCriteria criteria) { - QueryableList query = getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList getWithCriteria(DatasetProfileCriteria criteria) { + QueryableList query = getDatabaseService().getQueryable(DescriptionTemplate.class); if (criteria.getLike() != null && !criteria.getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + criteria.getLike().toUpperCase() + "%")); if (!criteria.getAllVersions()) @@ -63,9 +63,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem query.where(((builder, root) -> root.get("id").in(criteria.getIds()))); } if (criteria.getFinalized()) { - query.where(((builder, root) -> builder.equal(root.get("status"), DatasetProfile.Status.FINALIZED.getValue()))); + query.where(((builder, root) -> builder.equal(root.get("status"), DescriptionTemplate.Status.FINALIZED.getValue()))); } else { - query.where(((builder, root) -> builder.notEqual(root.get("status"), DatasetProfile.Status.DELETED.getValue()))); + query.where(((builder, root) -> builder.notEqual(root.get("status"), DescriptionTemplate.Status.DELETED.getValue()))); } if (criteria.getPeriodStart() != null) query.where((builder, root) -> builder.greaterThanOrEqualTo(root.get("created"), criteria.getPeriodStart())); @@ -73,48 +73,48 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem } @Override - public DatasetProfile createOrUpdate(DatasetProfile item) { - return this.getDatabaseService().createOrUpdate(item, DatasetProfile.class); + public DescriptionTemplate createOrUpdate(DescriptionTemplate item) { + return this.getDatabaseService().createOrUpdate(item, DescriptionTemplate.class); } @Override - public DatasetProfile find(UUID id) { - return getDatabaseService().getQueryable(DatasetProfile.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + public DescriptionTemplate find(UUID id) { + return getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); } @Override - public QueryableList getAll() { - return getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList getAll() { + return getDatabaseService().getQueryable(DescriptionTemplate.class); } @Override - public List getAllIds(){ - return getDatabaseService().getQueryable(DatasetProfile.class).withFields(Collections.singletonList("id")).toList(); + public List getAllIds(){ + return getDatabaseService().getQueryable(DescriptionTemplate.class).withFields(Collections.singletonList("id")).toList(); } @Override - public void delete(DatasetProfile item) { + public void delete(DescriptionTemplate item) { this.getDatabaseService().delete(item); } @Override - public QueryableList asQueryable() { - return this.getDatabaseService().getQueryable(DatasetProfile.class); + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DescriptionTemplate.class); } @Async @Override - public CompletableFuture createOrUpdateAsync(DatasetProfile item) { + public CompletableFuture createOrUpdateAsync(DescriptionTemplate item) { return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); } @Override - public DatasetProfile find(UUID id, String hint) { + public DescriptionTemplate find(UUID id, String hint) { throw new UnsupportedOperationException(); } @Override - public QueryableList getAuthenticated(QueryableList query, UUID principal, List roles) { + public QueryableList getAuthenticated(QueryableList query, UUID principal, List roles) { if (roles != null && !roles.isEmpty()) { query.where((builder, root) -> { Join userJoin = root.join("users", JoinType.LEFT); @@ -126,4 +126,9 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem return query; } + + @Override + public Long countWithType(DescriptionTemplateType type) { + return this.getDatabaseService().getQueryable(DescriptionTemplate.class).where((builder, root) -> builder.equal(root.get("type"), type)).count(); + } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java index 9af289d34..3666d4014 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDao.java @@ -1,7 +1,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.data.entities.DatasetService; import java.util.UUID; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java index fd40d37ae..2f000f4f8 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetServiceDaoImpl.java @@ -2,8 +2,6 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccess; import eu.eudat.data.dao.databaselayer.service.DatabaseService; -import eu.eudat.data.entities.DatasetExternalDataset; -import eu.eudat.data.entities.DatasetProfile; import eu.eudat.data.entities.DatasetService; import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java new file mode 100644 index 000000000..764bf32e0 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDao.java @@ -0,0 +1,10 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.DescriptionTemplateType; + +import java.util.UUID; + +public interface DescriptionTemplateTypeDao extends DatabaseAccessLayer { + DescriptionTemplateType findFromName(String name); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java new file mode 100644 index 000000000..f93afb383 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DescriptionTemplateTypeDaoImpl.java @@ -0,0 +1,65 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Component; + +import javax.transaction.Transactional; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("descriptionTemplateTypeDao") +public class DescriptionTemplateTypeDaoImpl extends DatabaseAccess implements DescriptionTemplateTypeDao { + + @Autowired + public DescriptionTemplateTypeDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public DescriptionTemplateType findFromName(String name){ + try { + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.equal(root.get("name"), name)).getSingle(); + } + catch(Exception e){ + return null; + } + } + + @Override + @Transactional + public DescriptionTemplateType createOrUpdate(DescriptionTemplateType item) { + return this.getDatabaseService().createOrUpdate(item, DescriptionTemplateType.class); + } + + @Override + public DescriptionTemplateType find(UUID id) { + return getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.equal((root.get("id")), id)).getSingle(); + } + + @Override + public void delete(DescriptionTemplateType item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DescriptionTemplateType.class).where((builder, root) -> builder.notEqual((root.get("status")), DescriptionTemplateType.Status.DELETED.getValue())); + } + + @Async + @Override + public CompletableFuture createOrUpdateAsync(DescriptionTemplateType item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DescriptionTemplateType find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java new file mode 100644 index 000000000..9febf7abf --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDao.java @@ -0,0 +1,9 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.DMPDatasetProfile; + +import java.util.UUID; + +public interface DmpDatasetProfileDao extends DatabaseAccessLayer { +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java new file mode 100644 index 000000000..6c65b804f --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DmpDatasetProfileDaoImpl.java @@ -0,0 +1,52 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccess; +import eu.eudat.data.dao.databaselayer.service.DatabaseService; +import eu.eudat.data.entities.Content; +import eu.eudat.data.entities.DMPDatasetProfile; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.scheduling.annotation.Async; +import org.springframework.stereotype.Service; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Service("dmpDatasetProfileDao") +public class DmpDatasetProfileDaoImpl extends DatabaseAccess implements DmpDatasetProfileDao { + @Autowired + public DmpDatasetProfileDaoImpl(DatabaseService databaseService) { + super(databaseService); + } + + @Override + public DMPDatasetProfile createOrUpdate(DMPDatasetProfile item) { + return this.getDatabaseService().createOrUpdate(item, DMPDatasetProfile.class); + } + + @Override + @Async + public CompletableFuture createOrUpdateAsync(DMPDatasetProfile item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public DMPDatasetProfile find(UUID id) { + return this.getDatabaseService().getQueryable(DMPDatasetProfile.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + } + + @Override + public DMPDatasetProfile find(UUID id, String hint) { + throw new UnsupportedOperationException(); + } + + @Override + public void delete(DMPDatasetProfile item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(DMPDatasetProfile.class); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java index 036069e86..60277ead5 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMP.java @@ -112,12 +112,8 @@ public class DMP implements DataEntity { /*@Type(type = "eu.eudat.configurations.typedefinition.XMLType") @Column(name = "\"AssociatedDmps\"", columnDefinition = "xml", nullable = true) private String associatedDmps;*/ - @OneToMany(fetch = FetchType.LAZY) - @JoinTable(name = "\"DMPDatasetProfile\"", - joinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")}, - inverseJoinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")} - ) - private Set associatedDmps; + @OneToMany(fetch = FetchType.LAZY, mappedBy = "dmp") + private Set associatedDmps; @ManyToOne(fetch = FetchType.LAZY) @@ -274,10 +270,10 @@ public class DMP implements DataEntity { this.grant = grant; } - public Set getAssociatedDmps() { + public Set getAssociatedDmps() { return associatedDmps; } - public void setAssociatedDmps(Set associatedDmps) { + public void setAssociatedDmps(Set associatedDmps) { this.associatedDmps = associatedDmps; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java new file mode 100644 index 000000000..816ec0410 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DMPDatasetProfile.java @@ -0,0 +1,76 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"DMPDatasetProfile\"") +public class DMPDatasetProfile implements DataEntity { + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @ManyToOne + @JoinColumn(name = "\"dmp\"") + private DMP dmp; + + @ManyToOne + @JoinColumn(name = "\"datasetprofile\"") + private DescriptionTemplate datasetprofile; + + @Column(name = "\"data\"") + private String data; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public DMP getDmp() { + return dmp; + } + public void setDmp(DMP dmp) { + this.dmp = dmp; + } + + public DescriptionTemplate getDatasetprofile() { + return datasetprofile; + } + public void setDatasetprofile(DescriptionTemplate datasetprofile) { + this.datasetprofile = datasetprofile; + } + + public String getData() { + return data; + } + public void setData(String data) { + this.data = data; + } + + @Override + public void update(DMPDatasetProfile entity) { + this.dmp = entity.getDmp(); + this.datasetprofile = entity.getDatasetprofile(); + this.data = entity.getData(); + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public DMPDatasetProfile buildFromTuple(List tuple, List fields, String base) { + this.id = UUID.fromString((String) tuple.get(0).get(base.isEmpty() ? base + "." + "id" : "id")); + return this; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java index 4692571b0..357f49ec9 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/Dataset.java @@ -100,6 +100,9 @@ public class Dataset implements DataEntity { @JoinColumn(name = "\"DMP\"", nullable = false) private DMP dmp; + @Column(name = "\"DmpSectionIndex\"") + private Integer dmpSectionIndex; + @Column(name = "\"Uri\"") private String uri; @@ -110,7 +113,7 @@ public class Dataset implements DataEntity { @ManyToOne(fetch = FetchType.LAZY) //@Cascade(value=org.hibernate.annotations.CascadeType.ALL) @JoinColumn(name = "\"Profile\"") - private DatasetProfile profile; + private DescriptionTemplate profile; @Type(type = "eu.eudat.configurations.typedefinition.XMLType") @Column(name = "\"Reference\"", columnDefinition = "xml") @@ -232,6 +235,12 @@ public class Dataset implements DataEntity { this.dmp = dmp; } + public Integer getDmpSectionIndex() { + return dmpSectionIndex; + } + public void setDmpSectionIndex(Integer dmpSectionIndex) { + this.dmpSectionIndex = dmpSectionIndex; + } public String getUri() { return uri; @@ -249,10 +258,10 @@ public class Dataset implements DataEntity { } - public DatasetProfile getProfile() { + public DescriptionTemplate getProfile() { return profile; } - public void setProfile(DatasetProfile profile) { + public void setProfile(DescriptionTemplate profile) { this.profile = profile; } @@ -328,6 +337,7 @@ public class Dataset implements DataEntity { this.setRegistries(entity.getRegistries()); this.setDmp(entity.getDmp()); + this.setDmpSectionIndex(entity.getDmpSectionIndex()); this.setStatus(entity.getStatus()); this.setProfile(entity.getProfile()); this.setModified(new Date()); diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java similarity index 83% rename from dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java rename to dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java index a11316abd..958934c72 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DatasetProfile.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplate.java @@ -14,8 +14,8 @@ import java.util.UUID; @Entity -@Table(name = "\"DatasetProfile\"") -public class DatasetProfile implements DataEntity{ +@Table(name = "\"DescriptionTemplate\"") +public class DescriptionTemplate implements DataEntity{ public enum Status { SAVED((short) 0), FINALIZED((short) 1), DELETED((short) 99); @@ -79,19 +79,21 @@ public class DatasetProfile implements DataEntity{ @Column(name = "\"Version\"", nullable = false) private Short version; - @ManyToMany(fetch = FetchType.LAZY) - @JoinTable(name = "\"DMPDatasetProfile\"", - joinColumns = {@JoinColumn(name = "\"datasetprofile\"", referencedColumnName = "\"ID\"")}, - inverseJoinColumns = {@JoinColumn(name = "\"dmp\"", referencedColumnName = "\"ID\"")} - ) - private List dmps; + @OneToMany(fetch = FetchType.LAZY) + private Set dmps; @Column(name = "\"Language\"", nullable = false) private String language; - @OneToMany(mappedBy = "datasetProfile", fetch = FetchType.LAZY) + @OneToOne(fetch = FetchType.EAGER) + @JoinColumn(name = "\"Type\"", nullable = false) + private DescriptionTemplateType type; + + @OneToMany(mappedBy = "descriptionTemplate", fetch = FetchType.LAZY) private Set users; + @OneToMany(fetch = FetchType.LAZY, mappedBy = "datasetprofile") + private Set associatedDmps; public String getDescription() { return description; @@ -156,26 +158,31 @@ public class DatasetProfile implements DataEntity{ public String getLanguage() { return language; } - public void setLanguage(String language) { this.language = language; } + public DescriptionTemplateType getType() { + return type; + } + public void setType(DescriptionTemplateType type) { + this.type = type; + } + public Set getUsers() { return users; } - public void setUsers(Set users) { this.users = users; } @Override public String toString() { - return "DatasetProfileListingModel [id=" + id + ", label=" + label + ", dataset=" + dataset + ", definition=" + definition + ", version=" + version + ", language=" + language + "]"; + return "DatasetProfileListingModel [id=" + id + ", label=" + label + ", dataset=" + dataset + ", definition=" + definition + ", version=" + version + ", language=" + language + ", type=" + type +"]"; } @Override - public void update(DatasetProfile entity) { + public void update(DescriptionTemplate entity) { } @Override @@ -184,7 +191,7 @@ public class DatasetProfile implements DataEntity{ } @Override - public DatasetProfile buildFromTuple(List tuple, List fields, String base) { + public DescriptionTemplate buildFromTuple(List tuple, List fields, String base) { this.id = UUID.fromString((String) tuple.get(0).get(base.isEmpty() ? base + "." + "id" : "id")); return this; } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java new file mode 100644 index 000000000..40a755c2f --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/DescriptionTemplateType.java @@ -0,0 +1,89 @@ +package eu.eudat.data.entities; + +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.GenericGenerator; + +import javax.persistence.*; +import java.util.List; +import java.util.UUID; + +@Entity +@Table(name = "\"DescriptionTemplateType\"") +public class DescriptionTemplateType implements DataEntity { + + public enum Status { + SAVED((short) 0), FINALIZED((short) 1), DELETED((short) 99); + + private short value; + + private Status(short value) { + this.value = value; + } + public short getValue() { + return value; + } + + public static Status fromInteger(int value) { + switch (value) { + case 0: + return SAVED; + case 1: + return FINALIZED; + case 99: + return DELETED; + default: + throw new RuntimeException("Unsupported Description Template Type Status"); + } + } + } + + @Id + @GeneratedValue + @GenericGenerator(name = "uuid2", strategy = "uuid2") + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @Column(name = "\"Name\"", nullable = false) + private String name; + + @Column(name = "\"Status\"", nullable = false) + private Short status; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public Short getStatus() { + return status; + } + public void setStatus(Short status) { + this.status = status; + } + + @Override + public void update(DescriptionTemplateType entity) { + this.name = entity.name; + this.status = entity.status; + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public DescriptionTemplateType buildFromTuple(List tuple, List fields, String base) { + this.id = UUID.fromString((String) tuple.get(0).get(!base.isEmpty() ? base + "." + "id" : "id")); + return this; + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java index 8388cdbc3..4af7c2799 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/UserDatasetProfile.java @@ -22,8 +22,8 @@ public class UserDatasetProfile implements DataEntity private UserInfo user; @OneToOne(fetch = FetchType.LAZY) - @JoinColumn(name = "\"datasetProfile\"") - private DatasetProfile datasetProfile; + @JoinColumn(name = "\"descriptionTemplate\"") + private DescriptionTemplate descriptionTemplate; @Column(name = "role") private Integer role; @@ -44,12 +44,12 @@ public class UserDatasetProfile implements DataEntity this.user = user; } - public DatasetProfile getDatasetProfile() { - return datasetProfile; + public DescriptionTemplate getDatasetProfile() { + return descriptionTemplate; } - public void setDatasetProfile(DatasetProfile datasetProfile) { - this.datasetProfile = datasetProfile; + public void setDatasetProfile(DescriptionTemplate descriptionTemplate) { + this.descriptionTemplate = descriptionTemplate; } public Integer getRole() { diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java new file mode 100644 index 000000000..b1b83e5d6 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java @@ -0,0 +1,25 @@ +package eu.eudat.data.query.items.dmpblueprint; + +import eu.eudat.data.dao.criteria.DataManagementPlanBlueprintCriteria; +import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.query.PaginationService; +import eu.eudat.data.query.definition.TableQuery; +import eu.eudat.queryable.QueryableList; + +import java.util.UUID; + +public class DataManagementPlanBlueprintTableRequest extends TableQuery { + + @Override + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); + if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) + query.where((builder, root) -> builder.like(root.get("label"), "%" + this.getCriteria().getLike() + "%")); + return query; + } + + @Override + public QueryableList applyPaging(QueryableList items) { + return PaginationService.applyPaging(items, this); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java index 2cda2c5cd..984d44073 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileAutocompleteRequest.java @@ -1,25 +1,24 @@ package eu.eudat.data.query.items.item.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.PaginationService; -import eu.eudat.data.query.definition.Query; import eu.eudat.data.query.definition.TableQuery; import eu.eudat.queryable.QueryableList; import java.util.UUID; -public class DatasetProfileAutocompleteRequest extends TableQuery { +public class DatasetProfileAutocompleteRequest extends TableQuery { @Override - public QueryableList applyCriteria() { - QueryableList query = this.getQuery(); + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + this.getCriteria().getLike().toUpperCase() + "%")); return query; } @Override - public QueryableList applyPaging(QueryableList items) { + public QueryableList applyPaging(QueryableList items) { return PaginationService.applyPaging(items, this); } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java index 2d7c0b393..c911fe3af 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/item/datasetprofile/DatasetProfileWizardAutocompleteRequest.java @@ -1,15 +1,13 @@ package eu.eudat.data.query.items.item.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileWizardCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.Query; import eu.eudat.queryable.QueryableList; -import java.util.UUID; - -public class DatasetProfileWizardAutocompleteRequest extends Query { +public class DatasetProfileWizardAutocompleteRequest extends Query { @Override - public QueryableList applyCriteria() { + public QueryableList applyCriteria() { return null; } } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java index 1ff6faa88..17ad2a687 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/table/datasetprofile/DatasetProfileTableRequestItem.java @@ -1,23 +1,23 @@ package eu.eudat.data.query.items.table.datasetprofile; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.TableQuery; import eu.eudat.queryable.QueryableList; import java.util.UUID; -public class DatasetProfileTableRequestItem extends TableQuery { +public class DatasetProfileTableRequestItem extends TableQuery { @Override - public QueryableList applyCriteria() { - QueryableList query = this.getQuery(); + public QueryableList applyCriteria() { + QueryableList query = this.getQuery(); if (this.getCriteria().getLike() != null && !this.getCriteria().getLike().isEmpty()) query.where((builder, root) -> builder.like(builder.upper(root.get("label")), "%" + this.getCriteria().getLike().toUpperCase() + "%")); return query; } @Override - public QueryableList applyPaging(QueryableList items) { + public QueryableList applyPaging(QueryableList items) { return null; } } diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java index c62c32986..a6a6a6782 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/DatasetTempalate.java @@ -1,14 +1,18 @@ package eu.eudat.elastic.entities; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import org.elasticsearch.common.xcontent.XContentBuilder; import java.io.IOException; +import java.util.HashMap; import java.util.Map; import java.util.UUID; public class DatasetTempalate implements ElasticEntity { private UUID id; private String name; + private Map data; public UUID getId() { return id; @@ -26,11 +30,25 @@ public class DatasetTempalate implements ElasticEntity { this.name = name; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException { builder.startObject(); builder.field("id", this.id.toString()); builder.field("name", this.name); + if(this.data != null) { + builder.field("data", new ObjectMapper().writeValueAsString(this.data)); + } + else{ + builder.field("data", ""); + } builder.endObject(); return builder; } @@ -39,6 +57,12 @@ public class DatasetTempalate implements ElasticEntity { public DatasetTempalate fromElasticEntity(Map fields) { this.id = UUID.fromString((String) fields.get("id")); this.name = (String) fields.get("name"); + try { + this.data = new ObjectMapper().readValue((String) fields.get("data"), new TypeReference>() {}); + } + catch (Exception e){ + this.data = new HashMap<>(); + } return this; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index 7829f2fa9..b8604c456 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -1,5 +1,6 @@ package eu.eudat.controllers; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserDatasetProfile; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; @@ -16,7 +17,6 @@ import eu.eudat.models.data.admin.composite.DatasetProfile; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; -import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.types.ApiMessageCode; @@ -32,7 +32,6 @@ import javax.validation.Valid; import java.io.IOException; import java.util.List; import java.util.UUID; -import java.util.stream.Collectors; import static eu.eudat.types.Authorities.ADMIN; import static eu.eudat.types.Authorities.DATASET_PROFILE_MANAGER; @@ -61,20 +60,21 @@ public class Admin extends BaseController { public ResponseEntity addDmp(@Valid @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN ,DATASET_PROFILE_MANAGER}) Principal principal) { //this.getLoggerService().info(principal, "Admin Added Dataset Profile"); DatasetProfile shortenProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + modelDefinition.setType(getApiContext().getOperationsContext().getDatabaseRepository().getDescriptionTemplateTypeDao().findFromName(profile.getType())); modelDefinition.setGroupId(UUID.randomUUID()); modelDefinition.setVersion((short) 0); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); UserDatasetProfile userDatasetProfile = new UserDatasetProfile(); - userDatasetProfile.setDatasetProfile(datasetProfile); + userDatasetProfile.setDatasetProfile(descriptionTemplate); UserInfo userInfo = getApiContext().getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); userDatasetProfile.setUser(userInfo); userDatasetProfile.setRole(0); getApiContext().getOperationsContext().getDatabaseRepository().getUserDatasetProfileDao().createOrUpdate(userDatasetProfile); - datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); + datasetProfileManager.storeDatasetProfileUsers(descriptionTemplate, profile); - metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricsManager.datasetTemplateStatus.get(datasetProfile.getStatus()) ); + metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricsManager.datasetTemplateStatus.get(descriptionTemplate.getStatus()) ); return ResponseEntity.status(HttpStatus.OK).body(modelDefinition.getId()); } @@ -82,17 +82,17 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/addDmp/{id}"}, consumes = "application/json", produces = "application/json") public ResponseEntity> updateDmp(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { DatasetProfile shortenProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); - eu.eudat.data.entities.DatasetProfile datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(shortenProfile, getApiContext()); + DescriptionTemplate datasetprofile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); datasetprofile.setDefinition(modelDefinition.getDefinition()); Short oldStatus = datasetprofile.getStatus(); datasetprofile.setStatus(modelDefinition.getStatus()); datasetprofile.setLabel(modelDefinition.getLabel()); datasetprofile.setDescription(modelDefinition.getDescription()); datasetprofile.setLanguage(modelDefinition.getLanguage()); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile); - datasetProfileManager.storeDatasetProfileUsers(datasetProfile, profile); - if (datasetProfile.getStatus() == 1 && oldStatus == 0) { + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(datasetprofile); + datasetProfileManager.storeDatasetProfileUsers(descriptionTemplate, profile); + if (descriptionTemplate.getStatus() == 1 && oldStatus == 0) { metricsManager.increaseValue(MetricNames.DATASET_TEMPLATE, 1, MetricNames.ACTIVE); } return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); @@ -102,7 +102,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/newVersion/{id}"}, produces = "application/json") public ResponseEntity newVersionDatasetProfile(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { try { - eu.eudat.data.entities.DatasetProfile modelDefinition = this.datasetProfileManager.createNewVersionDatasetProfile(id, profile); + DescriptionTemplate modelDefinition = this.datasetProfileManager.createNewVersionDatasetProfile(id, profile); return ResponseEntity.status(HttpStatus.OK).body(modelDefinition.getId()); } catch (DatasetProfileNewVersionException exception) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(exception.getMessage())); @@ -125,7 +125,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/preview"}, consumes = "application/json", produces = "application/json") public ResponseEntity> getPreview(@RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(profile, getApiContext()); eu.eudat.models.data.user.composite.DatasetProfile datasetProfile = userManager.generateDatasetProfileModel(modelDefinition); PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetProfile); @@ -145,7 +145,7 @@ public class Admin extends BaseController { public @ResponseBody ResponseEntity> inactivate(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { try { - eu.eudat.data.entities.DatasetProfile ret = AdminManager.inactivate(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); + DescriptionTemplate ret = AdminManager.inactivate(this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao(), this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetDao(), id); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); } catch (DatasetProfileWithDatasetsExeption exception) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(exception.getMessage())); @@ -156,7 +156,7 @@ public class Admin extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json") public ResponseEntity getDatasetProfileXml(@PathVariable String id, @RequestHeader("Content-Type") String contentType, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws IllegalAccessException, IOException, InstantiationException { if (contentType.equals("application/xml")) { - eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.user.composite.DatasetProfile datasetProfile = userManager.generateDatasetProfileModel(profile); datasetProfile.setStatus(profile.getStatus()); datasetProfile.setDescription(profile.getDescription()); @@ -173,12 +173,12 @@ public class Admin extends BaseController { @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.DatasetProfile datasetProfileModel = this.datasetProfileManager.createDatasetProfileFromXml(file); eu.eudat.models.data.admin.composite.DatasetProfile datasetProfileEntity = datasetProfileModel.toAdminCompositeModel(file.getOriginalFilename()); - eu.eudat.data.entities.DatasetProfile modelDefinition; + DescriptionTemplate modelDefinition; if (id == null) { modelDefinition = AdminManager.generateViewStyleDefinition(datasetProfileEntity, getApiContext()); - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); UserDatasetProfile userDatasetProfile = new UserDatasetProfile(); - userDatasetProfile.setDatasetProfile(datasetProfile); + userDatasetProfile.setDatasetProfile(descriptionTemplate); UserInfo userInfo = getApiContext().getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); userDatasetProfile.setUser(userInfo); userDatasetProfile.setRole(0); @@ -186,7 +186,7 @@ public class Admin extends BaseController { } else { modelDefinition = datasetProfileManager.createNewVersionDatasetProfile(id, datasetProfileEntity); } - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java index 1a54587fa..b307538d7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPProfileController.java @@ -2,6 +2,8 @@ package eu.eudat.controllers; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.logic.managers.DataManagementProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -10,6 +12,7 @@ import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; import eu.eudat.models.data.helpers.common.DataTableData; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.types.ApiMessageCode; @@ -51,6 +54,14 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); } + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/blueprint"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> createOrUpdateBlueprint(@RequestBody DataManagementPlanBlueprintListingModel dataManagementPlan, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + this.dataManagementProfileManager.createOrUpdateBlueprint(dataManagementPlan, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + } + @RequestMapping(method = RequestMethod.GET, value = {"/getSingle/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity> getSingle(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException { @@ -58,6 +69,13 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanProfileListingModel)); } + @RequestMapping(method = RequestMethod.GET, value = {"/getSingleBlueprint/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> getSingleBlueprint(@PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException { + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = this.dataManagementProfileManager.getSingleBlueprint(id, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlanBlueprintListingModel)); + } + @RequestMapping(method = RequestMethod.POST, value = {"/getPaged"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity>> getPaged(@Valid @RequestBody DataManagementPlanProfileTableRequest dataManagementPlanProfileTableRequest, Principal principal) throws Exception { @@ -65,6 +83,13 @@ public class DMPProfileController extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); } + @RequestMapping(method = RequestMethod.POST, value = {"/getPagedBlueprint"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity>> getPagedBlueprint(@Valid @RequestBody DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception { + DataTableData dataTable = this.dataManagementProfileManager.getPagedBlueprint(dataManagementPlanBlueprintTableRequest, principal); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + @RequestMapping(method = RequestMethod.GET, value = {"/getXml/{id}"}, produces = "application/json") public @ResponseBody ResponseEntity getXml( @RequestHeader("Content-Type") String contentType, @PathVariable String id, Principal principal) throws IllegalAccessException, InstantiationException, IOException { @@ -82,7 +107,7 @@ public class DMPProfileController extends BaseController { eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel.DmpProfile dmpProfileModel = this.dataManagementProfileManager.createDmpProfileFromXml(file); DataManagementPlanProfileListingModel dataManagementPlan = dmpProfileModel.toDmpProfileCompositeModel(file.getOriginalFilename()); this.dataManagementProfileManager.createOrUpdate(dataManagementPlan, principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>() .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java index 1c0d56ce1..cffa509ef 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfileController.java @@ -1,6 +1,7 @@ package eu.eudat.controllers; import eu.eudat.data.dao.criteria.RequestItem; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.managers.AdminManager; import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; @@ -56,7 +57,7 @@ public class DatasetProfileController extends BaseController { @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofile/clone/{id}"}, consumes = "application/json", produces = "application/json") public ResponseEntity> clone(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN})Principal principal) { - eu.eudat.data.entities.DatasetProfile profile = this.datasetProfileManager.clone(id); + DescriptionTemplate profile = this.datasetProfileManager.clone(id); eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile); datasetprofile.setLabel(profile.getLabel() + " new "); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetprofile)); @@ -64,8 +65,8 @@ public class DatasetProfileController extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/search/autocomplete"}, consumes = "application/json", produces = "application/json") public ResponseEntity getDataForAutocomplete(@RequestBody RequestItem lookupItem) throws XPathExpressionException { - eu.eudat.data.entities.DatasetProfile datasetProfile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID())); - eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field modelfield = this.datasetProfileManager.queryForField(datasetProfile.getDefinition(), lookupItem.getCriteria().getFieldID()); + DescriptionTemplate descriptionTemplate = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(lookupItem.getCriteria().getProfileID())); + eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field modelfield = this.datasetProfileManager.queryForField(descriptionTemplate.getDefinition(), lookupItem.getCriteria().getFieldID()); AutoCompleteData data = (AutoCompleteData) modelfield.getData(); List items = this.datasetProfileManager.getAutocomplete(data, lookupItem.getCriteria().getLike()); return ResponseEntity.status(HttpStatus.OK).body(items); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 4b4a79d1e..5364cf9f0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -1,6 +1,7 @@ package eu.eudat.controllers; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; import eu.eudat.data.query.items.table.dataset.DatasetPublicTableRequest; @@ -202,7 +203,7 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/get/{id}"}, produces = "application/json") public ResponseEntity> getSingle(@PathVariable String id) { - eu.eudat.data.entities.DatasetProfile profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = this.getApiContext().getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); PagedDatasetProfile pagedDatasetProfile = new PagedDatasetProfile(); pagedDatasetProfile.buildPagedDatasetProfile(datasetprofile); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java new file mode 100644 index 000000000..47c41eb77 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DescriptionTemplateTypeController.java @@ -0,0 +1,94 @@ +package eu.eudat.controllers; + +import eu.eudat.exceptions.descriptiontemplate.DescriptionTemplatesWithTypeException; +import eu.eudat.logic.managers.DescriptionTemplateTypeManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.descriptiontemplatetype.DescriptionTemplateTypeModel; +import eu.eudat.models.data.helpers.common.DataTableData; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.types.ApiMessageCode; +import eu.eudat.types.Authorities; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.transaction.Transactional; +import java.util.UUID; + +import static eu.eudat.types.Authorities.ADMIN; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/descriptionTemplateType/"}) +public class DescriptionTemplateTypeController extends BaseController { + + private DescriptionTemplateTypeManager descriptionTemplateTypeManager; + + @Autowired + public DescriptionTemplateTypeController(ApiContext apiContext, DescriptionTemplateTypeManager descriptionTemplateTypeManager){ + super(apiContext); + this.descriptionTemplateTypeManager = descriptionTemplateTypeManager; + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"create"}, produces = "application/json") + public @ResponseBody + ResponseEntity> create(@RequestBody DescriptionTemplateTypeModel type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.descriptionTemplateTypeManager.create(type); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"update"}, produces = "application/json") + public @ResponseBody + ResponseEntity> update(@RequestBody DescriptionTemplateTypeModel type, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.descriptionTemplateTypeManager.update(type); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Updated")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } + } + + @RequestMapping(method = RequestMethod.GET, value = {"get"}, produces = "application/json") + public @ResponseBody + ResponseEntity>> get(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + DataTableData dataTable = this.descriptionTemplateTypeManager.get(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(dataTable)); + } + + @RequestMapping(method = RequestMethod.GET, value = {"get/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> getSingle(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + try { + DescriptionTemplateTypeModel typeModel = this.descriptionTemplateTypeManager.getSingle(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(typeModel)); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); + } + } + + @Transactional + @RequestMapping(method = RequestMethod.DELETE, value = {"/delete/{id}"}, produces = "application/json") + public @ResponseBody + ResponseEntity> delete(@PathVariable(value = "id") UUID id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try{ + this.descriptionTemplateTypeManager.delete(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Deleted")); + } + catch(DescriptionTemplatesWithTypeException e){ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(e.getMessage())); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java index e80a2c70d..082e9ade7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/QuickWizardController.java @@ -1,8 +1,7 @@ package eu.eudat.controllers; -import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Funder; import eu.eudat.data.entities.Project; import eu.eudat.logic.managers.DatasetManager; @@ -23,7 +22,6 @@ import org.springframework.web.bind.annotation.*; import javax.transaction.Transactional; import javax.validation.Valid; -import java.util.UUID; @RestController @CrossOrigin @@ -88,7 +86,7 @@ public class QuickWizardController extends BaseController { quickWizard.getDmp().setId(dmpEntity.getId()); for (DatasetDescriptionQuickWizardModel dataset : quickWizard.getDatasets().getDatasetsList()) { DataManagementPlan dmp = quickWizard.getDmp().toDataDmp(grantEntity, projectEntity, principal); - DatasetProfile profile = quickWizard.getDmp().getDatasetProfile(); + DescriptionTemplate profile = quickWizard.getDmp().getDatasetProfile(); DatasetWizardModel datasetWizardModel = dataset.toDataModel(dmp, profile); this.datasetManager.createOrUpdate(datasetWizardModel, principal); } @@ -100,7 +98,7 @@ public class QuickWizardController extends BaseController { public @ResponseBody ResponseEntity> addDatasetWizard(@RequestBody DatasetCreateWizardModel datasetCreateWizardModel, Principal principal) throws Exception{ for(DatasetDescriptionQuickWizardModel dataset : datasetCreateWizardModel.getDatasets().getDatasetsList()){ - DatasetProfile profile = new DatasetProfile(); + DescriptionTemplate profile = new DescriptionTemplate(); profile.setId(datasetCreateWizardModel.getDmpMeta().getDatasetProfile().getId()); profile.setLabel(datasetCreateWizardModel.getDmpMeta().getDatasetProfile().getLabel()); this.datasetManager.createOrUpdate(dataset.toDataModel(datasetCreateWizardModel.getDmpMeta().getDmp(), profile), principal); diff --git a/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java b/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java new file mode 100644 index 000000000..2c6484b05 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/exceptions/descriptiontemplate/DescriptionTemplatesWithTypeException.java @@ -0,0 +1,9 @@ +package eu.eudat.exceptions.descriptiontemplate; + +public class DescriptionTemplatesWithTypeException extends RuntimeException { + + public DescriptionTemplatesWithTypeException(String message) { + super(message); + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java index add38bb38..59194d62f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/builders/entity/DatasetProfileBuilder.java @@ -1,8 +1,8 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.builders.Builder; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; import java.util.Date; import java.util.Set; @@ -11,7 +11,7 @@ import java.util.UUID; /** * Created by ikalyvas on 2/15/2018. */ -public class DatasetProfileBuilder extends Builder { +public class DatasetProfileBuilder extends Builder { private UUID id; @@ -77,17 +77,17 @@ public class DatasetProfileBuilder extends Builder { } @Override - public DatasetProfile build() { - DatasetProfile datasetProfile = new DatasetProfile(); - datasetProfile.setCreated(created); - datasetProfile.setStatus(status); - datasetProfile.setId(id); - datasetProfile.setDataset(dataset); - datasetProfile.setDefinition(definition); - datasetProfile.setDescription(description); - datasetProfile.setModified(modified); - datasetProfile.setLabel(label); - datasetProfile.setLanguage(language); - return datasetProfile; + public DescriptionTemplate build() { + DescriptionTemplate descriptionTemplate = new DescriptionTemplate(); + descriptionTemplate.setCreated(created); + descriptionTemplate.setStatus(status); + descriptionTemplate.setId(id); + descriptionTemplate.setDataset(dataset); + descriptionTemplate.setDefinition(definition); + descriptionTemplate.setDescription(description); + descriptionTemplate.setModified(modified); + descriptionTemplate.setLabel(label); + descriptionTemplate.setLanguage(language); + return descriptionTemplate; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java index 8d4b4382c..a7569ed82 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/AdminManager.java @@ -2,6 +2,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.dao.entities.DatasetDao; import eu.eudat.data.dao.entities.DatasetProfileDao; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.logic.builders.entity.DatasetProfileBuilder; import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel; @@ -17,7 +18,7 @@ import java.util.UUID; public class AdminManager { - public static eu.eudat.data.entities.DatasetProfile generateViewStyleDefinition(DatasetProfile profile, ApiContext apiContext) { + public static DescriptionTemplate generateViewStyleDefinition(DatasetProfile profile, ApiContext apiContext) { ViewStyleModel viewStyleModel = new ViewStyleModel(); viewStyleModel.setSections(new ModelBuilder().toViewStyleDefinition(profile.getSections(), eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Section.class)); viewStyleModel.setPages(new ModelBuilder().toViewStyleDefinition(profile.getPages(), eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Page.class)); @@ -34,22 +35,22 @@ public class AdminManager { profile.setLanguage("en"); } - eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) .status(profile.getStatus()).created(new Date()).description(profile.getDescription()).language(profile.getLanguage()) .build(); - if (datasetProfile.getGroupId() == null) { - datasetProfile.setGroupId(UUID.randomUUID()); + if (descriptionTemplate.getGroupId() == null) { + descriptionTemplate.setGroupId(UUID.randomUUID()); } - if (datasetProfile.getVersion() == null) { - datasetProfile.setVersion((short)1); + if (descriptionTemplate.getVersion() == null) { + descriptionTemplate.setVersion((short)1); } - return datasetProfile; + return descriptionTemplate; } - public static eu.eudat.models.data.admin.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + public static eu.eudat.models.data.admin.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); @@ -60,12 +61,12 @@ public class AdminManager { } - public static eu.eudat.data.entities.DatasetProfile inactivate(DatasetProfileDao datasetProfileRepository, DatasetDao datasetDao, String id) { + public static DescriptionTemplate inactivate(DatasetProfileDao datasetProfileRepository, DatasetDao datasetDao, String id) { eu.eudat.data.dao.criteria.DatasetCriteria datasetsForThatDatasetProfile = new eu.eudat.data.dao.criteria.DatasetCriteria(); datasetsForThatDatasetProfile.setProfileDatasetId(UUID.fromString(id)); if (datasetDao.getWithCriteria(datasetsForThatDatasetProfile).count() == 0) { - eu.eudat.data.entities.DatasetProfile detasetProfile = datasetProfileRepository.find(UUID.fromString(id)); - detasetProfile.setStatus(eu.eudat.data.entities.DatasetProfile.Status.DELETED.getValue()); + DescriptionTemplate detasetProfile = datasetProfileRepository.find(UUID.fromString(id)); + detasetProfile.setStatus(DescriptionTemplate.Status.DELETED.getValue()); detasetProfile = datasetProfileRepository.createOrUpdate(detasetProfile); return detasetProfile; } else { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java index df74d3258..6fddb00a3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementPlanManager.java @@ -5,6 +5,7 @@ import eu.eudat.configurations.dynamicgrant.DynamicGrantConfiguration; import eu.eudat.configurations.dynamicgrant.entities.Property; import eu.eudat.data.dao.criteria.*; import eu.eudat.data.dao.entities.*; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Organisation; import eu.eudat.data.entities.Researcher; import eu.eudat.data.entities.*; @@ -25,7 +26,6 @@ import eu.eudat.elastic.entities.Tag; import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.exceptions.security.ForbiddenException; -import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.mapper.elastic.DmpMapper; @@ -51,8 +51,8 @@ import eu.eudat.models.data.dmp.*; import eu.eudat.models.data.doi.DepositRequest; import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.*; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; import eu.eudat.models.data.helpermodels.Tuple; @@ -65,7 +65,6 @@ import eu.eudat.models.data.userinfo.UserListingModel; import eu.eudat.queryable.QueryableList; import eu.eudat.types.Authorities; import eu.eudat.types.MetricNames; -import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; @@ -87,7 +86,6 @@ import javax.xml.bind.JAXBException; import javax.xml.bind.Unmarshaller; import java.io.*; import java.math.BigInteger; -import java.nio.charset.StandardCharsets; import java.nio.file.Files; import java.time.Instant; import java.time.temporal.ChronoUnit; @@ -408,7 +406,7 @@ public class DataManagementPlanManager { datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.DMPs.getValue()); datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); DataTableData data = new DataTableData<>(); @@ -449,6 +447,7 @@ public class DataManagementPlanManager { * Data Management * */ + @Transactional public DMP createOrUpdate(DataManagementPlanEditorModel dataManagementPlan, Principal principal) throws Exception { boolean setNotification = false; if (dataManagementPlan.getId() != null) { @@ -465,7 +464,7 @@ public class DataManagementPlanManager { } List datasetList = dmp1.getDataset().stream().filter(dataset -> dataset.getStatus() != 99).collect(Collectors.toList()); for (Dataset dataset : datasetList) { - if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) + if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getDescriptionTemplateId())).findAny().orElse(null) == null) throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) @@ -521,9 +520,19 @@ public class DataManagementPlanManager { assignFunderUserIfInternal(newDmp, user); assignProjectUserIfInternal(newDmp, user); + if(newDmp.getId() != null){ + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + } + apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().createOrUpdate(newDmp.getGrant()); newDmp = apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(newDmp); + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + if (dataManagementPlan.getUsers() != null && !dataManagementPlan.getUsers().isEmpty()) { clearUsers(newDmp); for (UserInfoListingModel userListing : dataManagementPlan.getUsers()) { @@ -599,7 +608,7 @@ public class DataManagementPlanManager { throw new Exception("Another user have already edit that DMP."); } for (DatasetWizardModel dataset : dataManagementPlan.getDatasets()) { - if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getId())).findAny().orElse(null) == null) + if (dataManagementPlan.getProfiles().stream().filter(associatedProfile -> dataset.getProfile().getId().equals(associatedProfile.getDescriptionTemplateId())).findAny().orElse(null) == null) throw new Exception("Dataset Template for Dataset Description is missing from the DMP."); } if (dataManagementPlan.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue() && dmp1.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) @@ -1254,116 +1263,271 @@ public class DataManagementPlanManager { // wordBuilder.addParagraphContent("Datasets", document, ParagraphStyle.HEADER1, BigInteger.ZERO); // // Space below Datasets. // XWPFParagraph parBreakDatasets = document.createParagraph(); - final Boolean isFinalized = dmpEntity.getStatus() == DMP.DMPStatus.FINALISED.getValue(); - final Boolean isPublic = dmpEntity.isPublic(); - dmpEntity.getDataset().stream() - .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) - .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) - .filter(item -> !isPublic && !isFinalized || item.getStatus() == Dataset.Status.FINALISED.getValue()) - .sorted(Comparator.comparing(Dataset::getCreated)) - .forEach(datasetEntity -> { - Map properties = new HashMap<>(); - if (datasetEntity.getProperties() != null) { - //ObjectMapper objectMapper = new ObjectMapper(); - try { - properties = objectMapper.readValue(datasetEntity.getProperties(), LinkedHashMap.class); - } catch (IOException e) { - logger.error(e.getLocalizedMessage(), e); - } - /*JSONObject jObject = new JSONObject(datasetEntity.getProperties()); - properties = jObject.toMap();*/ - } - // Custom style for the Dataset title. - //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); - XWPFParagraph datasetLabelParagraph = document.createParagraph(); -// datasetLabelParagraph.setStyle("Heading2"); - datasetLabelParagraph.setSpacingBetween(1.0); - XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); - runDatasetTitle1.setText("Title: "); - runDatasetTitle1.setColor("000000"); - //runDatasetTitle1.setBold(true); - //runDatasetTitle1.setFontSize(12); - XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); - runDatasetTitle.setText(datasetEntity.getLabel()); - runDatasetTitle.setColor("116a78"); - //runDatasetTitle.setBold(true); - //runDatasetTitle.setFontSize(12); + DMPProfile dmpProfile = dmpEntity.getProfile(); + DataManagementPlanBlueprintListingModel dmpBlueprintModel = new DataManagementPlanBlueprintListingModel(); + dmpBlueprintModel.fromDataModel(dmpProfile); + DataManagementPlanBlueprint dmpBlueprint = dmpBlueprintModel.getDefinition(); + for(Section section: dmpBlueprint.getSections()){ + wordBuilder.addParagraphContent("Section " + section.getOrdinal(), document, ParagraphStyle.HEADER1, BigInteger.ZERO, 0); + XWPFParagraph sectionInfoParagraph = document.createParagraph(); + sectionInfoParagraph.setSpacingBetween(1.0); + XWPFRun runSectionTitle = sectionInfoParagraph.createRun(); + runSectionTitle.setText("Title: "); + runSectionTitle.setColor("000000"); + XWPFRun runSectionTitleText = sectionInfoParagraph.createRun(); + runSectionTitleText.setText(section.getLabel()); + runSectionTitleText.setColor("116a78"); + XWPFParagraph sectionDescriptionParagraph = document.createParagraph(); + XWPFRun runSectionDescription = sectionDescriptionParagraph.createRun(); + runSectionDescription.setText("Description: "); + runSectionDescription.setColor("000000"); + XWPFRun runSectionDescriptionText = sectionDescriptionParagraph.createRun(); + runSectionDescriptionText.setText(section.getDescription()); + runSectionDescriptionText.setColor("116a78"); - XWPFParagraph datasetTemplateParagraph = document.createParagraph(); -// datasetTemplateParagraph.setStyle("Heading3"); - XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); - runDatasetTemplate1.setText("Template: "); - runDatasetTemplate1.setColor("000000"); - //runDatasetTemplate1.setBold(true); - //runDatasetTemplate1.setFontSize(12); - XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); - runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); - runDatasetTemplate.setColor("116a78"); - //runDatasetTemplate.setBold(true); - //runDatasetTemplate.setFontSize(12); + wordBuilder.addParagraphContent("Section Fields", document, ParagraphStyle.HEADER2, BigInteger.ZERO, 0); + section.getFields().sort(Comparator.comparingInt(FieldModel::getOrdinal)); + for(FieldModel field: section.getFields()){ + if(field.getCategory() == FieldCategory.SYSTEM){ + SystemField systemField = field.toSystemField(); + XWPFParagraph systemFieldParagraph = document.createParagraph(); + systemFieldParagraph.setSpacingBetween(1.0); + XWPFRun runSyStemFieldTitle = systemFieldParagraph.createRun(); + runSyStemFieldTitle.setText("Title: "); + runSyStemFieldTitle.setColor("000000"); + XWPFRun runSystemFieldTitleText = systemFieldParagraph.createRun(); + runSystemFieldTitleText.setText(systemField.getLabel()); + runSystemFieldTitleText.setColor("116a78"); + if(systemField.getDescription() != null && !systemField.getDescription().isEmpty()){ + XWPFParagraph systemFieldDescription = document.createParagraph(); + systemFieldDescription.setSpacingBetween(1.0); + XWPFRun runSyStemFieldDescription = systemFieldDescription.createRun(); + runSyStemFieldDescription.setText("Description: "); + runSyStemFieldDescription.setColor("000000"); + XWPFRun runSystemFieldDescriptionText = systemFieldDescription.createRun(); + runSystemFieldDescriptionText.setText(systemField.getDescription()); + runSystemFieldDescriptionText.setColor("116a78"); + } + XWPFParagraph systemFieldInput = document.createParagraph(); + systemFieldInput.setSpacingBetween(1.0); + XWPFRun runInput = systemFieldInput.createRun(); + runInput.setText("Input: "); + runInput.setColor("000000"); + switch (systemField.getType()) { + case TEXT: + XWPFRun runTitle = systemFieldInput.createRun(); + runTitle.setText(dmpEntity.getLabel()); + runTitle.setColor("116a78"); + break; + case HTML_TEXT: + XWPFRun runDescription = systemFieldInput.createRun(); + runDescription.setText(dmpEntity.getDescription()); + runDescription.setColor("116a78"); + break; + case RESEARCHERS: + for(Researcher researcher: dmpEntity.getResearchers()){ + XWPFRun runResearcher = systemFieldInput.createRun(); + runResearcher.setText("• " + researcher.getLabel()); + runResearcher.setColor("116a78"); + } + break; + case ORGANIZATIONS: + for(Organisation organisation: dmpEntity.getOrganisations()){ + XWPFRun runOrganisation = systemFieldInput.createRun(); + runOrganisation.setText("• " + organisation.getLabel()); + runOrganisation.setColor("116a78"); + } + break; + case LANGUAGE: + XWPFRun runLanguage = systemFieldInput.createRun(); + runLanguage.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("language").toString()); + runLanguage.setColor("116a78"); + break; + case CONTACT: + XWPFRun runContact = systemFieldInput.createRun(); + runContact.setText(dmpEntity.getCreator().getName()); + runContact.setColor("116a78"); + break; + case FUNDER: + XWPFRun runFunder = systemFieldInput.createRun(); + runFunder.setText(dmpEntity.getGrant().getFunder().getLabel()); + runFunder.setColor("116a78"); + break; + case GRANT: + XWPFRun runGrant = systemFieldInput.createRun(); + runGrant.setText(dmpEntity.getGrant().getLabel()); + runGrant.setColor("116a78"); + break; + case PROJECT: + XWPFRun runProject = systemFieldInput.createRun(); + runProject.setText(dmpEntity.getProject().getLabel()); + runProject.setColor("116a78"); + break; + case LICENSE: + XWPFRun runLicense = systemFieldInput.createRun(); + runLicense.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("license").toString()); + runLicense.setColor("116a78"); + break; + case ACCESS_RIGHTS: + XWPFRun runAccessRights = systemFieldInput.createRun(); + runAccessRights.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("visible").toString()); + runAccessRights.setColor("116a78"); + break; + } + document.createParagraph(); + } + else if(field.getCategory() == FieldCategory.EXTRA){ + ExtraField extraField = field.toExtraField(); + XWPFParagraph extraFieldParagraph = document.createParagraph(); + extraFieldParagraph.setSpacingBetween(1.0); + XWPFRun runExtraFieldLabel = extraFieldParagraph.createRun(); + runExtraFieldLabel.setText(extraField.getLabel()); + runExtraFieldLabel.setColor("116a78"); + if(extraField.getDescription() != null && !extraField.getDescription().isEmpty()){ + XWPFRun runExtraFieldDescription = extraFieldParagraph.createRun(); + runExtraFieldDescription.setText(extraField.getDescription()); + runExtraFieldDescription.setColor("116a78"); + } + XWPFRun runExtraFieldInput = extraFieldParagraph.createRun(); + runExtraFieldInput.setText(extraField.getLabel()); + runExtraFieldInput.setColor("116a78"); + } + } - document.createParagraph(); + if(!section.getDescriptionTemplates().isEmpty()){ + wordBuilder.addParagraphContent("Section descriptions", document, ParagraphStyle.HEADER2, BigInteger.ZERO, 0); + wordBuilder.addParagraphContent("Description Templates", document, ParagraphStyle.HEADER4, BigInteger.ZERO, 0); + for(eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DescriptionTemplate descriptionTemplate: section.getDescriptionTemplates()){ + XWPFParagraph templateParagraph = document.createParagraph(); + XWPFRun runTemplateLabel = templateParagraph.createRun(); + runTemplateLabel.setText("• " + descriptionTemplate.getLabel()); + runTemplateLabel.setColor("116a78"); + } -// /*XWPFParagraph externalReferencesParagraph = document.createParagraph(); -// externalReferencesParagraph.setStyle("Heading3"); -// XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); -// externalReferencesRun.setText("External References"); -// externalReferencesRun.setColor("2E75B6"); -// externalReferencesRun.setBold(true); -// externalReferencesRun.setFontSize(12); + final Boolean isFinalized = dmpEntity.getStatus() == DMP.DMPStatus.FINALISED.getValue(); + final Boolean isPublic = dmpEntity.isPublic(); + dmpEntity.getDataset().stream() + .filter(item -> item.getStatus() != Dataset.Status.CANCELED.getValue()) + .filter(item -> item.getStatus() != Dataset.Status.DELETED.getValue()) + .filter(item -> !isPublic && !isFinalized || item.getStatus() == Dataset.Status.FINALISED.getValue()) + .filter(item -> item.getDmpSectionIndex().equals(section.getOrdinal() - 1)) + .sorted(Comparator.comparing(Dataset::getCreated)) + .forEach(datasetEntity -> { + Map properties = new HashMap<>(); + if (datasetEntity.getProperties() != null) { + //ObjectMapper objectMapper = new ObjectMapper(); + try { + properties = objectMapper.readValue(datasetEntity.getProperties(), LinkedHashMap.class); + } catch (IOException e) { + logger.error(e.getLocalizedMessage(), e); + } + /*JSONObject jObject = new JSONObject(datasetEntity.getProperties()); + properties = jObject.toMap();*/ + } + + + // Dataset Description custom style. + XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); + datasetDescriptionParagraph.setStyle("Heading4"); + datasetDescriptionParagraph.setSpacingBetween(1.5); + XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); + datasetDescriptionRun.setText("Dataset Description"); + //datasetDescriptionRun.setColor("2E75B6"); + //datasetDescriptionRun.setBold(true); + datasetDescriptionRun.setFontSize(15); + + + // Custom style for the Dataset title. + //wordBuilder.addParagraphContent("Title: " + datasetEntity.getLabel(), document, ParagraphStyle.HEADER1, BigInteger.ZERO); + XWPFParagraph datasetLabelParagraph = document.createParagraph(); +// datasetLabelParagraph.setStyle("Heading2"); + datasetLabelParagraph.setSpacingBetween(1.0); + XWPFRun runDatasetTitle1 = datasetLabelParagraph.createRun(); + runDatasetTitle1.setText("Title: "); + runDatasetTitle1.setColor("000000"); + //runDatasetTitle1.setBold(true); + //runDatasetTitle1.setFontSize(12); + XWPFRun runDatasetTitle = datasetLabelParagraph.createRun(); + runDatasetTitle.setText(datasetEntity.getLabel()); + runDatasetTitle.setColor("116a78"); + //runDatasetTitle.setBold(true); + //runDatasetTitle.setFontSize(12); + + XWPFParagraph datasetTemplateParagraph = document.createParagraph(); +// datasetTemplateParagraph.setStyle("Heading3"); + XWPFRun runDatasetTemplate1 = datasetTemplateParagraph.createRun(); + runDatasetTemplate1.setText("Template: "); + runDatasetTemplate1.setColor("000000"); + //runDatasetTemplate1.setBold(true); + //runDatasetTemplate1.setFontSize(12); + XWPFRun runDatasetTemplate = datasetTemplateParagraph.createRun(); + runDatasetTemplate.setText(datasetEntity.getProfile().getLabel()); + runDatasetTemplate.setColor("116a78"); + //runDatasetTemplate.setBold(true); + //runDatasetTemplate.setFontSize(12); + +// /*XWPFParagraph externalReferencesParagraph = document.createParagraph(); +// externalReferencesParagraph.setStyle("Heading3"); +// XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); +// externalReferencesRun.setText("External References"); +// externalReferencesRun.setColor("2E75B6"); +// externalReferencesRun.setBold(true); +// externalReferencesRun.setFontSize(12); // -// wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getDatasetDataRepositories().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getDatasetExternalDatasets().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getRegistries().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// if (datasetEntity.getServices().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.TEXT, BigInteger.ZERO); -// } -// *//*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); -// if (datasetEntity.().size() > 0) { -// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) -// , document, ParagraphStyle.HEADER4, BigInteger.ZERO); -// }*/ +// wordBuilder.addParagraphContent("Data Repositories", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getDatasetDataRepositories().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getDatasetDataRepositories().stream().map(DatasetDataRepository::getDataRepository).map(DataRepository::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("External Datasets", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getDatasetExternalDatasets().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getDatasetExternalDatasets().stream().map(DatasetExternalDataset::getExternalDataset).map(ExternalDataset::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("Registries", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getRegistries().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getRegistries().stream().map(Registry::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// wordBuilder.addParagraphContent("Services", document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// if (datasetEntity.getServices().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.TEXT, BigInteger.ZERO); +// } +// *//*wordBuilder.addParagraphContent("Tags", document, ParagraphStyle.HEADER3, BigInteger.ZERO); +// if (datasetEntity.().size() > 0) { +// wordBuilder.addParagraphContent(datasetEntity.getServices().stream().map(DatasetService::getService).map(Service::getLabel).collect(Collectors.joining(", ")) +// , document, ParagraphStyle.HEADER4, BigInteger.ZERO); +// }*/ // // - wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); - // Dataset Description custom style. - XWPFParagraph datasetDescriptionParagraph = document.createParagraph(); - datasetDescriptionParagraph.setStyle("Heading4"); - datasetDescriptionParagraph.setSpacingBetween(1.5); - XWPFRun datasetDescriptionRun = datasetDescriptionParagraph.createRun(); - datasetDescriptionRun.setText("Dataset Description"); - //datasetDescriptionRun.setColor("2E75B6"); - //datasetDescriptionRun.setBold(true); - datasetDescriptionRun.setFontSize(15); + XWPFParagraph datasetDescParagraph = document.createParagraph(); + XWPFRun runDatasetDescription1 = datasetDescParagraph.createRun(); + runDatasetDescription1.setText("Description: "); + runDatasetDescription1.setColor("000000"); + XWPFRun runDatasetDescription = datasetDescParagraph.createRun(); + runDatasetDescription.setText(datasetEntity.getProfile().getLabel()); + runDatasetDescription.setColor("116a78"); + //wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); - PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); - visibilityRuleService.setProperties(properties); - visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); - try { - wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); - } catch (IOException e) { - logger.error(e.getMessage(), e); - } - // Page break at the end of the Dataset. - XWPFParagraph parBreakDataset = document.createParagraph(); - parBreakDataset.setPageBreak(true); - }); + document.createParagraph(); + + PagedDatasetProfile pagedDatasetProfile = datasetManager.getPagedProfile(dataset, datasetEntity); + visibilityRuleService.setProperties(properties); + visibilityRuleService.buildVisibilityContext(pagedDatasetProfile.getRules()); + try { + wordBuilder.build(document, pagedDatasetProfile, visibilityRuleService); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + // Page break at the end of the Dataset. + XWPFParagraph parBreakDataset = document.createParagraph(); + parBreakDataset.setPageBreak(true); + }); + } + } // // Removes the top empty headings. // for (int i = 0; i < 6; i++) { @@ -1603,19 +1767,20 @@ public class DataManagementPlanManager { Element profiles = xmlDoc.createElement("profiles"); // Get DatasetProfiles from DMP to add to XML. - for (DatasetProfile datasetProfile : dmp.getAssociatedDmps()) { + for (DMPDatasetProfile dmpDescriptionProfile : dmp.getAssociatedDmps()) { + DescriptionTemplate descriptionTemplate = dmpDescriptionProfile.getDatasetprofile(); Element profile = xmlDoc.createElement("profile"); Element profileId = xmlDoc.createElement("profileId"); - profileId.setTextContent(datasetProfile.getId().toString()); + profileId.setTextContent(descriptionTemplate.getId().toString()); profile.appendChild(profileId); Element profileGroupId = xmlDoc.createElement("profileGroupId"); - profileGroupId.setTextContent(datasetProfile.getGroupId().toString()); + profileGroupId.setTextContent(descriptionTemplate.getGroupId().toString()); profile.appendChild(profileGroupId); Element profileLabel = xmlDoc.createElement("profileLabel"); - profileLabel.setTextContent(datasetProfile.getLabel()); + profileLabel.setTextContent(descriptionTemplate.getLabel()); profile.appendChild(profileLabel); Element profileVersion = xmlDoc.createElement("profileVersion"); - profileVersion.setTextContent(String.valueOf(datasetProfile.getVersion())); + profileVersion.setTextContent(String.valueOf(descriptionTemplate.getVersion())); profile.appendChild(profileVersion); profiles.appendChild(profile); } @@ -1755,7 +1920,7 @@ public class DataManagementPlanManager { List associatedProfiles = new LinkedList<>(); if (profiles != null && profiles.length > 0) { for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); + DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); associatedProfiles.add(associatedProfile); } @@ -1763,7 +1928,7 @@ public class DataManagementPlanManager { for (AssociatedProfileImportModels a : dataManagementPlans.get(0).getProfilesImportModels()) { try { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(a.getId()); + DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(a.getId()); AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); associatedProfiles.add(associatedProfile); } catch (Exception ignored) { @@ -1843,7 +2008,7 @@ public class DataManagementPlanManager { try { dataset.setProfile(databaseRepository.getDatasetProfileDao().find(das.getProfile())); } catch (Exception ignored) { - dataset.setProfile(databaseRepository.getDatasetProfileDao().find(associatedProfiles.get(0).getId())); + dataset.setProfile(databaseRepository.getDatasetProfileDao().find(associatedProfiles.get(0).getDescriptionTemplateId())); } dataset.setProperties(objectMapper.writeValueAsString(das.getFieldImportModels())); dataset.setStatus((short) 0); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java index 031bab7e7..667dbbd2e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DataManagementProfileManager.java @@ -5,6 +5,7 @@ import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.RequestItem; import eu.eudat.data.dao.entities.DMPProfileDao; import eu.eudat.data.entities.DMPProfile; +import eu.eudat.data.query.items.dmpblueprint.DataManagementPlanBlueprintTableRequest; import eu.eudat.data.query.items.item.dmpprofile.DataManagementPlanProfileCriteriaRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; import eu.eudat.logic.services.operations.DatabaseRepository; @@ -17,6 +18,7 @@ import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field; import eu.eudat.models.data.helpermodels.Tuple; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; import eu.eudat.models.data.helpers.common.DataTableData; +import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; import eu.eudat.models.data.security.Principal; import eu.eudat.queryable.QueryableList; @@ -78,6 +80,20 @@ public class DataManagementProfileManager { return dataTable; } + public DataTableData getPagedBlueprint(DataManagementPlanBlueprintTableRequest dataManagementPlanBlueprintTableRequest, Principal principal) throws Exception { + + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().getWithCriteriaBlueprint(dataManagementPlanBlueprintTableRequest.getCriteria()); + QueryableList pagedItems = PaginationManager.applyPaging(items, dataManagementPlanBlueprintTableRequest); + + DataTableData dataTable = new DataTableData<>(); + + CompletableFuture itemsFuture = pagedItems + .selectAsync(item -> new DataManagementPlanBlueprintListingModel().fromDataModel(item)).whenComplete((resultList, throwable) -> dataTable.setData(resultList)); + CompletableFuture countFuture = items.countAsync().whenComplete((count, throwable) -> dataTable.setTotalCount(count)); + CompletableFuture.allOf(itemsFuture, countFuture).join(); + return dataTable; + } + public DataManagementPlanProfileListingModel getSingle(String id, Principal principal) throws InstantiationException, IllegalAccessException { DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = new DataManagementPlanProfileListingModel(); @@ -85,6 +101,13 @@ public class DataManagementProfileManager { return dataManagementPlanProfileListingModel; } + public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) throws InstantiationException, IllegalAccessException { + DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel(); + dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile); + return dataManagementPlanBlueprintListingModel; + } + public List getWithCriteria(DataManagementPlanProfileCriteriaRequest dataManagementPlanProfileCriteriaRequest) throws IllegalAccessException, InstantiationException { QueryableList items = databaseRepository.getDmpProfileDao().getWithCriteria(dataManagementPlanProfileCriteriaRequest.getCriteria()); List datamanagementPlans = items.select(item -> new DataManagementPlanProfileListingModel().fromDataModel(item)); @@ -96,6 +119,11 @@ public class DataManagementProfileManager { apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); } + public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception { + DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel(); + apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); + } + public ResponseEntity getDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws IllegalAccessException, IOException, InstantiationException { FileEnvelope envelope = getXmlDocument(dmpProfile, label); InputStream resource = new FileInputStream(envelope.getFile()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 74fa3d3ce..9b4c64840 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -292,7 +292,7 @@ public class DatasetManager { dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); - // Creates the Criteria to get all version of DatasetProfile in question. + // Creates the Criteria to get all version of DescriptionTemplate in question. DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); UUID profileId = datasetEntity.getProfile().getGroupId(); List uuidList = new LinkedList<>(); @@ -300,13 +300,13 @@ public class DatasetManager { profileCriteria.setGroupIds(uuidList); profileCriteria.setAllVersions(true); - List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) + List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) .orderBy(((builder, root) -> builder.desc(root.get("version")))) .toList(); - List profileVersionsIncluded = new LinkedList<>(); + List profileVersionsIncluded = new LinkedList<>(); // Iterate through the versions and remove those that are not included in the DMP of the dataset in question. - for (DatasetProfile version : profileVersions) { + for (DescriptionTemplate version : profileVersions) { for (AssociatedProfile p : dataset.getDmp().getProfiles()) { if (version.getId().toString().equals(p.getId().toString())) { profileVersionsIncluded.add(version); @@ -315,14 +315,14 @@ public class DatasetManager { } // Sort the list with the included Versions. - Stream sorted = profileVersionsIncluded.stream().sorted(Comparator.comparing(DatasetProfile::getVersion).reversed()); + Stream sorted = profileVersionsIncluded.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion).reversed()); // Make the Stream into List and get the first item. - List profiles = sorted.collect(Collectors.toList()); + List profiles = sorted.collect(Collectors.toList()); if (profiles.isEmpty()) throw new NoSuchElementException("No profiles found for the specific Dataset"); - DatasetProfile profile = profiles.get(0); + DescriptionTemplate profile = profiles.get(0); // Check if the dataset is on the latest Version. boolean latestVersion = profile.getVersion().toString().equals(datasetEntity.getProfile().getVersion().toString()); @@ -717,7 +717,7 @@ public class DatasetManager { public String checkDatasetValidation(Dataset dataset) throws Exception { List datasetProfileValidators = new LinkedList<>(); - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(dataset.getProfile().getId()); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(dataset.getProfile().getId()); DocumentBuilderFactory builderFactory = DocumentBuilderFactory.newInstance(); DocumentBuilder builder = builderFactory.newDocumentBuilder(); Document xmlDocument = builder.parse(new ByteArrayInputStream(profile.getDefinition().getBytes())); @@ -975,9 +975,9 @@ public class DatasetManager { // Checks if XML datasetProfileId GroupId matches the one selected. try { - eu.eudat.data.entities.DatasetProfile importDatasetProfile = databaseRepository.getDatasetProfileDao().find(UUID.fromString(importModel.getDatasetProfileId())); - eu.eudat.data.entities.DatasetProfile latestVersionDatasetProfile = databaseRepository.getDatasetProfileDao().find(UUID.fromString(datasetProfileId)); - if (latestVersionDatasetProfile.getGroupId() != importDatasetProfile.getGroupId()) { + DescriptionTemplate importDescriptionTemplate = databaseRepository.getDatasetProfileDao().find(UUID.fromString(importModel.getDatasetProfileId())); + DescriptionTemplate latestVersionDescriptionTemplate = databaseRepository.getDatasetProfileDao().find(UUID.fromString(datasetProfileId)); + if (latestVersionDescriptionTemplate.getGroupId() != importDescriptionTemplate.getGroupId()) { throw new Exception(); } } catch (Exception e) { @@ -1010,7 +1010,7 @@ public class DatasetManager { entity.setStatus((short) 0); entity.setCreated(new Date()); entity.setModified(new Date()); - DatasetProfile profile = new DatasetProfile(); + DescriptionTemplate profile = new DescriptionTemplate(); profile.setId(UUID.fromString(datasetProfileId)); entity.setProfile(profile); @@ -1037,7 +1037,7 @@ public class DatasetManager { dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); dataset.fromDataModel(datasetEntity); - // Creates the Criteria to get all version of DatasetProfile in question. + // Creates the Criteria to get all version of DescriptionTemplate in question. DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); UUID profileId = datasetEntity.getProfile().getGroupId(); List uuidList = new LinkedList<>(); @@ -1045,7 +1045,7 @@ public class DatasetManager { profileCriteria.setGroupIds(uuidList); // Gets the latest version of the datasetProfile. - eu.eudat.data.entities.DatasetProfile item = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria).getSingle(); + DescriptionTemplate item = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria).getSingle(); // Sets the latest version of dataet Profile to the Dataset in question. dataset.setDatasetProfileDefinition(getLatestDatasetProfile(datasetEntity, item)); @@ -1071,7 +1071,7 @@ public class DatasetManager { return dataset; } - public PagedDatasetProfile getLatestDatasetProfile(Dataset datasetEntity, DatasetProfile profile) { + public PagedDatasetProfile getLatestDatasetProfile(Dataset datasetEntity, DescriptionTemplate profile) { eu.eudat.models.data.user.composite.DatasetProfile datasetprofile = userManager.generateDatasetProfileModel(profile); datasetprofile.setStatus(datasetEntity.getStatus()); if (datasetEntity.getProperties() != null) { @@ -1088,7 +1088,7 @@ public class DatasetManager { datasetProfileTableRequestItem.getCriteria().setFilter(DatasetProfileCriteria.DatasetProfileFilter.Datasets.getValue()); datasetProfileTableRequestItem.getCriteria().setUserId(principal.getId()); - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); List listingModels = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); DataTableData data = new DataTableData<>(); @@ -1183,10 +1183,10 @@ public class DatasetManager { DatasetListingModel listingModel = new DatasetListingModel().fromDataModel(item); /*DatasetProfileCriteria criteria = new DatasetProfileCriteria(); criteria.setGroupIds(Collections.singletonList(item.getProfile().getGroupId())); - List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); + List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); boolean islast = false; if (!profiles.isEmpty()) { - profiles = profiles.stream().sorted(Comparator.comparing(DatasetProfile::getVersion)).collect(Collectors.toList()); + profiles = profiles.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion)).collect(Collectors.toList()); islast = profiles.get(0).getId().equals(item.getProfile().getId()); } listingModel.setProfileLatestVersion(islast);*/ diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index 3786dddb2..faf184cf8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -3,7 +3,7 @@ package eu.eudat.logic.managers; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; import eu.eudat.data.dao.criteria.DatasetProfileCriteria; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserDatasetProfile; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteRequest; @@ -82,11 +82,12 @@ public class DatasetProfileManager { @Transactional public eu.eudat.models.data.admin.composite.DatasetProfile getDatasetProfile(String id) { - eu.eudat.data.entities.DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); eu.eudat.models.data.admin.composite.DatasetProfile datasetprofile = AdminManager.generateDatasetProfileModel(profile); datasetprofile.setLabel(profile.getLabel()); datasetprofile.setStatus(profile.getStatus()); datasetprofile.setDescription(profile.getDescription()); + datasetprofile.setType(profile.getType().getName()); datasetprofile.setLanguage(profile.getLanguage()); datasetprofile.setUsers(new ArrayList<>()); retrieveUsers(profile, datasetprofile); @@ -94,35 +95,35 @@ public class DatasetProfileManager { } public List getWithCriteria(DatasetProfileAutocompleteRequest datasetProfileAutocompleteRequest) throws IllegalAccessException, InstantiationException { - QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(datasetProfileAutocompleteRequest.getCriteria()); - QueryableList pagedItems = datasetProfileAutocompleteRequest.applyPaging(items); + QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(datasetProfileAutocompleteRequest.getCriteria()); + QueryableList pagedItems = datasetProfileAutocompleteRequest.applyPaging(items); List datasetProfiles = pagedItems.select(item -> new DatasetProfileAutocompleteItem().fromDataModel(item)); return datasetProfiles; } - public DatasetProfile clone(String id) { - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + public DescriptionTemplate clone(String id) { + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); apiContext.getOperationsContext().getDatabaseRepository().detachEntity(profile); profile.setId(null); return profile; } public DataTableData getPaged(DatasetProfileTableRequestItem datasetProfileTableRequestItem, Principal principal) throws Exception { - QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); - QueryableList authItems = null; + QueryableList items = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(datasetProfileTableRequestItem.getCriteria()); + QueryableList authItems = null; if (principal.getAuthz().contains(Authorities.ADMIN)) { authItems = items; } else if (principal.getAuthz().contains(Authorities.DATASET_PROFILE_MANAGER)) { List roles = Arrays.asList(0, 1); authItems = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getAuthenticated(items, principal.getId(), roles); } - QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetProfileTableRequestItem); + QueryableList pagedItems = PaginationManager.applyPaging(authItems, datasetProfileTableRequestItem); List datasetProfiles = pagedItems.select(item -> new DatasetProfileListingModel().fromDataModel(item)); return apiContext.getOperationsContext().getBuilderFactory().getBuilder(DataTableDataBuilder.class).data(datasetProfiles).totalCount(items.count()).build(); } public List getAll(DatasetProfileTableRequestItem tableRequestItem) throws IllegalAccessException, InstantiationException { - QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); + QueryableList items = databaseRepository.getDatasetProfileDao().getWithCriteria(tableRequestItem.getCriteria()); List datasetProfiles = items.select(item -> new DatasetProfileListingModel().fromDataModel(item)); return datasetProfiles; @@ -276,36 +277,36 @@ public class DatasetProfileManager { return convFile; } - public eu.eudat.data.entities.DatasetProfile createNewVersionDatasetProfile(String id, eu.eudat.models.data.admin.composite.DatasetProfile profile) throws Exception { - // Getting the DatasetProfile which we will create its new version. - eu.eudat.data.entities.DatasetProfile oldDatasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); + public DescriptionTemplate createNewVersionDatasetProfile(String id, eu.eudat.models.data.admin.composite.DatasetProfile profile) throws Exception { + // Getting the DescriptionTemplate which we will create its new version. + DescriptionTemplate oldDescriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(id)); - // Getting the DatasetProfile with the latest Version. + // Getting the DescriptionTemplate with the latest Version. DatasetProfileCriteria criteria = new DatasetProfileCriteria(); LinkedList list = new LinkedList<>(); - list.push(oldDatasetProfile.getGroupId()); + list.push(oldDescriptionTemplate.getGroupId()); criteria.setGroupIds(list); criteria.setAllVersions(false); - QueryableList datasetProfileQueryableList = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria); - eu.eudat.data.entities.DatasetProfile latestVersionDatasetProfile = datasetProfileQueryableList.getSingle(); + QueryableList datasetProfileQueryableList = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria); + DescriptionTemplate latestVersionDescriptionTemplate = datasetProfileQueryableList.getSingle(); - if (latestVersionDatasetProfile.getVersion().equals(oldDatasetProfile.getVersion())){ + if (latestVersionDescriptionTemplate.getVersion().equals(oldDescriptionTemplate.getVersion())){ eu.eudat.models.data.admin.composite.DatasetProfile sortedProfile = profile.toShort(); - eu.eudat.data.entities.DatasetProfile modelDefinition = AdminManager.generateViewStyleDefinition(sortedProfile, apiContext); -// modelDefinition.setLabel(oldDatasetProfile.getLabel()); - modelDefinition.setVersion((short) (oldDatasetProfile.getVersion() + 1)); - modelDefinition.setGroupId(oldDatasetProfile.getGroupId()); -// modelDefinition.setLanguage(oldDatasetProfile.getLanguage()); + DescriptionTemplate modelDefinition = AdminManager.generateViewStyleDefinition(sortedProfile, apiContext); +// modelDefinition.setLabel(oldDescriptionTemplate.getLabel()); + modelDefinition.setVersion((short) (oldDescriptionTemplate.getVersion() + 1)); + modelDefinition.setGroupId(oldDescriptionTemplate.getGroupId()); +// modelDefinition.setLanguage(oldDescriptionTemplate.getLanguage()); apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); - eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); - this.storeDatasetProfileUsers(datasetProfile, profile); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().createOrUpdate(modelDefinition); + this.storeDatasetProfileUsers(descriptionTemplate, profile); return modelDefinition; } else { throw new DatasetProfileNewVersionException("Version to update not the latest."); } } - public void storeDatasetProfileUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { + public void storeDatasetProfileUsers(DescriptionTemplate entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { if (model.getUsers() != null && !model.getUsers().isEmpty()) { if (entity.getUsers() == null) { entity.setUsers(new HashSet<>()); @@ -340,7 +341,7 @@ public class DatasetProfileManager { } @Transactional - public void retrieveUsers(DatasetProfile entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { + public void retrieveUsers(DescriptionTemplate entity, eu.eudat.models.data.admin.composite.DatasetProfile model) { if (entity.getUsers() != null && !entity.getUsers().isEmpty()) { model.setUsers(entity.getUsers().stream().filter(userDatasetProfile -> userDatasetProfile.getRole() < 2).map(userDatasetProfile -> { UserInfoListingModel userInfoListingModel = new UserInfoListingModel(); @@ -381,10 +382,10 @@ public class DatasetProfileManager { } public void addSemanticsInDatasetProfiles() throws XPathExpressionException { - List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); - for(DatasetProfile dp: ids){ - DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); - Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DescriptionTemplate dp: ids){ + DescriptionTemplate descriptionTemplate = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(descriptionTemplate.getDefinition()); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//rdaCommonStandard"); @@ -402,15 +403,15 @@ public class DatasetProfileManager { fieldParent.insertBefore(schematics, rdaPropertyNode); fieldParent.removeChild(rdaPropertyNode); } - this.updateDatasetProfileXml(document, datasetProfile); + this.updateDatasetProfileXml(document, descriptionTemplate); } } public void addRdaInSemanticsInDatasetProfiles() throws XPathExpressionException { - List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); - for(DatasetProfile dp: ids){ - DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); - Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DescriptionTemplate dp: ids){ + DescriptionTemplate descriptionTemplate = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(descriptionTemplate.getDefinition()); XPathFactory xpathFactory = XPathFactory.newInstance(); XPath xpath = xpathFactory.newXPath(); XPathExpression expr = xpath.compile("//schematic"); @@ -422,11 +423,11 @@ public class DatasetProfileManager { schematicNode.setTextContent("rda." + schematicRda); } } - this.updateDatasetProfileXml(document, datasetProfile); + this.updateDatasetProfileXml(document, descriptionTemplate); } } - private void updateDatasetProfileXml(Document document, DatasetProfile datasetProfile) { + private void updateDatasetProfileXml(Document document, DescriptionTemplate descriptionTemplate) { try { DOMSource domSource = new DOMSource(document); StringWriter writer = new StringWriter(); @@ -437,8 +438,8 @@ public class DatasetProfileManager { transformer.transform(domSource, result); String newDefinition = writer.toString(); if(newDefinition != null){ - datasetProfile.setDefinition(newDefinition); - this.databaseRepository.getDatasetProfileDao().createOrUpdate(datasetProfile); + descriptionTemplate.setDefinition(newDefinition); + this.databaseRepository.getDatasetProfileDao().createOrUpdate(descriptionTemplate); } } catch(TransformerException ex) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java index c3c347bcb..123f70881 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetWizardManager.java @@ -5,7 +5,7 @@ import eu.eudat.data.dao.entities.DMPDao; import eu.eudat.data.dao.entities.DatasetProfileDao; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.query.items.item.dataset.DatasetWizardAutocompleteRequest; import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileWizardAutocompleteRequest; @@ -40,12 +40,12 @@ public class DatasetWizardManager { return new LinkedList<>(); } DatasetProfileCriteria criteria = new DatasetProfileCriteria(); - criteria.setIds(dataManagementPlan.getProfiles().stream().map(AssociatedProfile::getId).collect(Collectors.toList())); - List datasetProfiles = profileDao.getWithCriteria(criteria).toList(); + criteria.setIds(dataManagementPlan.getProfiles().stream().map(AssociatedProfile::getDescriptionTemplateId).collect(Collectors.toList())); + List descriptionTemplates = profileDao.getWithCriteria(criteria).toList(); criteria.setIds(null); - criteria.setGroupIds(datasetProfiles.stream().map(DatasetProfile::getGroupId).collect(Collectors.toList())); - datasetProfiles = profileDao.getWithCriteria(criteria).toList(); - List profiles = datasetProfiles.stream().map(profile -> new AssociatedProfile().fromData(profile)).collect(Collectors.toList()); + criteria.setGroupIds(descriptionTemplates.stream().map(DescriptionTemplate::getGroupId).collect(Collectors.toList())); + descriptionTemplates = profileDao.getWithCriteria(criteria).toList(); + List profiles = descriptionTemplates.stream().map(profile -> new AssociatedProfile().fromData(profile)).collect(Collectors.toList()); return profiles; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java new file mode 100644 index 000000000..1dda78fdb --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DescriptionTemplateTypeManager.java @@ -0,0 +1,84 @@ +package eu.eudat.logic.managers; + +import eu.eudat.data.entities.DescriptionTemplateType; +import eu.eudat.exceptions.descriptiontemplate.DescriptionTemplatesWithTypeException; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.operations.DatabaseRepository; +import eu.eudat.models.data.descriptiontemplatetype.DescriptionTemplateTypeModel; +import eu.eudat.models.data.helpers.common.DataTableData; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Component +public class DescriptionTemplateTypeManager { + private static final Logger logger = LoggerFactory.getLogger(DescriptionTemplateTypeManager.class); + + private ApiContext apiContext; + private DatabaseRepository databaseRepository; + + + @Autowired + public DescriptionTemplateTypeManager(ApiContext apiContext, DatabaseRepository databaseRepository) { + this.apiContext = apiContext; + this.databaseRepository = databaseRepository; + } + + public DataTableData get() { + List types = this.databaseRepository.getDescriptionTemplateTypeDao().asQueryable().toList(); + List typesModelList = types.stream().map(type -> new DescriptionTemplateTypeModel().fromDataModel(type)).collect(Collectors.toList()); + DataTableData dataTableData = new DataTableData<>(); + dataTableData.setData(typesModelList); + dataTableData.setTotalCount((long) typesModelList.size()); + return dataTableData; + } + + public DescriptionTemplateTypeModel getSingle(UUID id) throws Exception { + DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().find(id); + if (type != null) { + return new DescriptionTemplateTypeModel().fromDataModel(type); + } + else { + throw new DescriptionTemplatesWithTypeException("No description template type found with this id"); + } + } + + public void create(DescriptionTemplateTypeModel type) throws Exception { + DescriptionTemplateType existed = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(type.getName()); + if (existed == null) { + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type.toDataModel()); + } + else { + throw new DescriptionTemplatesWithTypeException("There is already a description template type with that name."); + } + } + + public void update(DescriptionTemplateTypeModel type) throws Exception { + DescriptionTemplateType existed = this.databaseRepository.getDescriptionTemplateTypeDao().findFromName(type.getName()); + if (existed != null) { + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type.toDataModel()); + } + else { + throw new DescriptionTemplatesWithTypeException("No description template type found."); + } + } + + public void delete(UUID id) throws DescriptionTemplatesWithTypeException { + DescriptionTemplateType type = this.databaseRepository.getDescriptionTemplateTypeDao().find(id); + if (type != null) { + Long descriptionsWithType = this.databaseRepository.getDatasetProfileDao().countWithType(type); + if(descriptionsWithType == 0) { + type.setStatus(DescriptionTemplateType.Status.DELETED.getValue()); + this.databaseRepository.getDescriptionTemplateTypeDao().createOrUpdate(type); + } + else{ + throw new DescriptionTemplatesWithTypeException("This type can not deleted, because Descriptions are associated with it"); + } + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java index 256956605..2aacc8cc3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MetricsManager.java @@ -1,7 +1,7 @@ package eu.eudat.logic.managers; import eu.eudat.data.dao.criteria.*; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.services.ApiContext; import eu.eudat.types.MetricNames; import io.micrometer.prometheus.PrometheusMeterRegistry; @@ -33,8 +33,8 @@ public class MetricsManager { private final Map gauges; public static final Map datasetTemplateStatus = Stream.of(new Object[][] { - { DatasetProfile.Status.SAVED.getValue(), MetricNames.DRAFT }, - { DatasetProfile.Status.FINALIZED.getValue(), MetricNames.ACTIVE }, + { DescriptionTemplate.Status.SAVED.getValue(), MetricNames.DRAFT }, + { DescriptionTemplate.Status.FINALIZED.getValue(), MetricNames.ACTIVE }, }).collect(Collectors.toMap(data -> (Short) data[0], data -> (String) data[1])); public void increaseValue(String name, int amount, String label) { @@ -406,9 +406,9 @@ public class MetricsManager { criteria.setStatus(1); criteria.setAllVersions(false); if (countNexus) criteria.setPeriodStart(getNexusDate()); - List datasetProfiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).withFields(Collections.singletonList("id")).toList(); + List descriptionTemplates = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).withFields(Collections.singletonList("id")).toList(); DatasetCriteria datasetCriteria = new DatasetCriteria(); - datasetCriteria.setDatasetTemplates(datasetProfiles.stream().map(DatasetProfile::getId).collect(Collectors.toList())); + datasetCriteria.setDatasetTemplates(descriptionTemplates.stream().map(DescriptionTemplate::getId).collect(Collectors.toList())); return apiContext.getOperationsContext().getDatabaseRepository().getDatasetDao().getWithCriteria(datasetCriteria).select(root -> root.getProfile().getId()).stream().distinct().count(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java index e234ff300..0643ecbe4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/PrefillingManager.java @@ -2,7 +2,7 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.mapper.prefilling.PrefillingMapper; import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; @@ -61,8 +61,8 @@ public class PrefillingManager { PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); Map prefillingEntity = getSingle(prefillingGet.getUrl(), prefillId); - DatasetProfile datasetProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); - return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), datasetProfile, datasetManager, licenseManager); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); + return PrefillingMapper.mapPrefilledEntityToDatasetWizard(prefillingEntity, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } public DatasetWizardModel getPrefilledDatasetUsingData(Map data, String configId, UUID profileId) throws Exception { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index 3820bdfa7..138730ef4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -3,13 +3,8 @@ package eu.eudat.logic.managers; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.entities.UserInfoDao; -import eu.eudat.data.entities.Credential; -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.UserInfo; -import eu.eudat.data.entities.UserRole; +import eu.eudat.data.entities.*; import eu.eudat.data.query.items.table.userinfo.UserInfoTableRequestItem; -import eu.eudat.exceptions.security.ExpiredTokenException; -import eu.eudat.exceptions.security.NonValidTokenException; import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.builders.entity.UserRoleBuilder; @@ -72,7 +67,7 @@ public class UserManager { this.environment = environment; } - public eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + public eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = (Element) viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java index 6545bb32b..75e979175 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetTemplateMapper.java @@ -1,14 +1,26 @@ package eu.eudat.logic.mapper.elastic; -import eu.eudat.data.entities.DatasetProfile; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.entities.DMPDatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.entities.DatasetTempalate; +import java.util.HashMap; +import java.util.Map; + public class DatasetTemplateMapper { - public static DatasetTempalate toElastic(DatasetProfile profile) { + public static DatasetTempalate toElastic(DMPDatasetProfile profile) { DatasetTempalate elastic = new DatasetTempalate(); - elastic.setId(profile.getId()); - elastic.setName(profile.getLabel()); + elastic.setId(profile.getDatasetprofile().getId()); + elastic.setName(profile.getDatasetprofile().getLabel()); + try { + elastic.setData(new ObjectMapper().readValue(profile.getData(), new TypeReference>() {})); + } + catch (Exception e){ + elastic.setData(new HashMap<>()); + } return elastic; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index e8758d628..50e664e2b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -5,7 +5,7 @@ import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.managers.DatasetProfileManager; @@ -40,7 +40,7 @@ public class PrefillingMapper { private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, - DatasetProfile profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { + DescriptionTemplate profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile)); Dataset dataset = new Dataset(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java index 99e088a1c..1d5e10df8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepository.java @@ -14,6 +14,8 @@ public interface DatabaseRepository { DMPDao getDmpDao(); + DmpDatasetProfileDao getDmpDatasetProfileDao(); + OrganisationDao getOrganisationDao(); GrantDao getGrantDao(); @@ -62,5 +64,7 @@ public interface DatabaseRepository { EntityDoiDao getEntityDoiDao(); + DescriptionTemplateTypeDao getDescriptionTemplateTypeDao(); + void detachEntity(T entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java index 2e2dd4c63..ccbb80304 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/DatabaseRepositoryImpl.java @@ -16,6 +16,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private DatasetDao datasetDao; private DatasetProfileDao datasetProfileDao; private DMPDao dmpDao; + private DmpDatasetProfileDao dmpDatasetProfileDao; private OrganisationDao organisationDao; private GrantDao GrantDao; private RegistryDao registryDao; @@ -40,6 +41,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private NotificationDao notificationDao; private FileUploadDao fileUploadDao; private EntityDoiDao entityDoiDao; + private DescriptionTemplateTypeDao descriptionTemplateTypeDao; private EntityManager entityManager; @@ -63,6 +65,11 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.dmpDao = dmpDao; } + @Autowired + private void setDmpDatasetProfileDao(DmpDatasetProfileDao dmpDatasetProfileDao) { + this.dmpDatasetProfileDao = dmpDatasetProfileDao; + } + @Autowired private void setOrganisationDao(OrganisationDao organisationDao) { this.organisationDao = organisationDao; @@ -113,6 +120,11 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { return dmpDao; } + @Override + public DmpDatasetProfileDao getDmpDatasetProfileDao() { + return dmpDatasetProfileDao; + } + @Override public OrganisationDao getOrganisationDao() { return organisationDao; @@ -328,6 +340,16 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.entityDoiDao = entityDoiDao; } + @Override + public DescriptionTemplateTypeDao getDescriptionTemplateTypeDao() { + return descriptionTemplateTypeDao; + } + + @Autowired + public void setDescriptionTemplateTypeDao(DescriptionTemplateTypeDao descriptionTemplateTypeDao) { + this.descriptionTemplateTypeDao = descriptionTemplateTypeDao; + } + public void detachEntity(T entity) { this.entityManager.detach(entity); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java index 2ae1a2d34..a7d29e30e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/DatasetProfile.java @@ -1,6 +1,8 @@ package eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel; +import eu.eudat.data.entities.DescriptionTemplate; + import javax.xml.bind.annotation.XmlAttribute; import javax.xml.bind.annotation.XmlElement; import javax.xml.bind.annotation.XmlRootElement; @@ -45,7 +47,7 @@ public class DatasetProfile { public eu.eudat.models.data.admin.composite.DatasetProfile toAdminCompositeModel(String label){ eu.eudat.models.data.admin.composite.DatasetProfile newDatasetEntityProfile = new eu.eudat.models.data.admin.composite.DatasetProfile(); newDatasetEntityProfile.setLabel(label); - newDatasetEntityProfile.setStatus(eu.eudat.data.entities.DatasetProfile.Status.SAVED.getValue()); + newDatasetEntityProfile.setStatus(DescriptionTemplate.Status.SAVED.getValue()); newDatasetEntityProfile.setDescription(description); newDatasetEntityProfile.setLanguage(language); List pagesDatasetEntity = new LinkedList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java index cbc23c2f4..146a4acc5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/composite/DatasetProfile.java @@ -13,6 +13,7 @@ import java.util.List; public class DatasetProfile { private String label; private String description; + private String type; private List pages; private List
sections; private Short status; @@ -35,6 +36,13 @@ public class DatasetProfile { this.description = description; } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + public List getPages() { return pages; } @@ -80,6 +88,7 @@ public class DatasetProfile { DatasetProfile shortProfile = new DatasetProfile(); shortProfile.setLabel(this.label); shortProfile.setDescription(this.description); + shortProfile.setType(this.type); List
shortSection = new LinkedList<>(); for (Section toshortSection : this.getSections()) { shortSection.add(toshortSection.toShort()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java index 34eac149e..e359c41b6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/datasetprofile/DatasetProfileAutocompleteItem.java @@ -1,12 +1,12 @@ package eu.eudat.models.data.datasetprofile; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.DataModel; import java.util.UUID; -public class DatasetProfileAutocompleteItem implements DataModel { +public class DatasetProfileAutocompleteItem implements DataModel { private UUID id; private String label; @@ -34,7 +34,7 @@ public class DatasetProfileAutocompleteItem implements DataModel { +public class DatasetProfileListingModel implements DataModel { private UUID id; private String label; @@ -66,7 +66,7 @@ public class DatasetProfileListingModel implements DataModel { +public class DatasetProfileOverviewModel implements DataModel { private UUID id; private String label; @@ -24,15 +24,15 @@ public class DatasetProfileOverviewModel implements DataModel registries; private List services; @@ -92,6 +93,13 @@ public class DatasetWizardModel implements DataModel new Service().fromDataModel(item.getService())).collect(Collectors.toList()) : new ArrayList<>(); this.created = entity.getCreated(); this.dmp = new DataManagementPlan().fromDataModelNoDatasets(entity.getDmp()); + this.dmpSectionIndex = entity.getDmpSectionIndex(); this.externalDatasets = entity.getDatasetExternalDatasets() != null ? entity.getDatasetExternalDatasets().stream().map(item -> { ExternalDatasetListingModel externalDatasetListingModel = new ExternalDatasetListingModel().fromDataModel(item.getExternalDataset()); if (item.getData() != null) { @@ -202,6 +211,7 @@ public class DatasetWizardModel implements DataModel new Registry().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>(); this.dataRepositories = entity.getDatasetDataRepositories() != null ? entity.getDatasetDataRepositories().stream().map(item -> { DataRepository dataRepository = new DataRepository().fromDataModel(item.getDataRepository()); @@ -241,10 +251,11 @@ public class DatasetWizardModel implements DataModel { + + private UUID id; + private String name; + private short status; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } + + public short getStatus() { + return status; + } + public void setStatus(short status) { + this.status = status; + } + + @Override + public DescriptionTemplateTypeModel fromDataModel(DescriptionTemplateType entity) { + this.id = entity.getId(); + this.name = entity.getName(); + this.status = entity.getStatus(); + return this; + } + + @Override + public DescriptionTemplateType toDataModel() throws Exception { + DescriptionTemplateType descriptionTemplateType = new DescriptionTemplateType(); + descriptionTemplateType.setId(this.id); + descriptionTemplateType.setName(this.name); + descriptionTemplateType.setStatus(this.status); + return descriptionTemplateType; + } + + @Override + public String getHint() { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java index e3fb43d61..13343fa5b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfile.java @@ -1,16 +1,19 @@ package eu.eudat.models.data.dmp; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.utilities.interfaces.XmlSerializable; import org.w3c.dom.Document; import org.w3c.dom.Element; +import java.util.Map; import java.util.UUID; public class AssociatedProfile implements XmlSerializable { private UUID id; + private UUID descriptionTemplateId; private String label; + private Map data; public UUID getId() { return id; @@ -20,6 +23,14 @@ public class AssociatedProfile implements XmlSerializable { this.id = id; } + public UUID getDescriptionTemplateId() { + return descriptionTemplateId; + } + + public void setDescriptionTemplateId(UUID descriptionTemplateId) { + this.descriptionTemplateId = descriptionTemplateId; + } + public String getLabel() { return label; } @@ -28,30 +39,38 @@ public class AssociatedProfile implements XmlSerializable { this.label = label; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public Element toXml(Document doc) { Element profile = doc.createElement("profile"); - profile.setAttribute("profileId", this.id.toString()); + profile.setAttribute("profileId", this.descriptionTemplateId.toString()); profile.setAttribute("label", this.label); return profile; } @Override public AssociatedProfile fromXml(Element item) { - this.id = UUID.fromString(item.getAttribute("profileId")); + this.descriptionTemplateId = UUID.fromString(item.getAttribute("profileId")); this.label = item.getAttribute("label"); return this; } - public DatasetProfile toData() { - DatasetProfile profile = new DatasetProfile(); - profile.setId(this.id); + public DescriptionTemplate toData() { + DescriptionTemplate profile = new DescriptionTemplate(); + profile.setId(this.descriptionTemplateId); profile.setLabel(this.label); return profile; } - public AssociatedProfile fromData(DatasetProfile entity) { - this.id = entity.getId(); + public AssociatedProfile fromData(DescriptionTemplate entity) { + this.descriptionTemplateId = entity.getId(); this.label = entity.getLabel(); return this; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java index 6c4018f81..002cd9bf8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlan.java @@ -1,5 +1,7 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; @@ -9,7 +11,6 @@ import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; import eu.eudat.models.data.funder.Funder; import eu.eudat.models.data.helpermodels.Tuple; -import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.Grant; import eu.eudat.models.data.project.Project; @@ -259,8 +260,15 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } @@ -321,11 +329,16 @@ public class DataManagementPlan implements DataModel { dataManagementPlanEntity.setProject(this.project.toDataModel()); } if (this.profiles != null) { - Set datasetProfiles = new HashSet<>(); + Set dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - datasetProfiles.add(profile.toData()); + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(profile.getId()); + dmpDatasetProfile.setDmp(dataManagementPlanEntity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); } - dataManagementPlanEntity.setAssociatedDmps(datasetProfiles); + dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); @@ -366,8 +379,15 @@ public class DataManagementPlan implements DataModel { if (entity.getAssociatedDmps() != null && !entity.getAssociatedDmps().isEmpty()) { this.profiles = new LinkedList<>(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java index 1eca8b81c..4f3f0b644 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanEditorModel.java @@ -1,5 +1,7 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; @@ -8,7 +10,6 @@ import eu.eudat.models.data.dynamicfields.DynamicFieldWithValue; import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.helpermodels.Tuple; -import eu.eudat.models.data.listingmodels.DatasetListingModel; import eu.eudat.models.data.listingmodels.UserInfoListingModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; import eu.eudat.models.data.project.ProjectDMPEditorModel; @@ -250,8 +251,14 @@ public class DataManagementPlanEditorModel implements DataModel(); - for (DatasetProfile datasetProfile: entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.profiles.add(associatedProfile); } } @@ -359,11 +366,16 @@ public class DataManagementPlanEditorModel implements DataModel datasetProfiles = new HashSet<>(); + Set dmpDatasetProfiles = new HashSet<>(); for (AssociatedProfile profile : this.profiles) { - datasetProfiles.add(profile.toData()); + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(profile.getId()); + dmpDatasetProfile.setDmp(dataManagementPlanEntity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); } - dataManagementPlanEntity.setAssociatedDmps(datasetProfiles); + dataManagementPlanEntity.setAssociatedDmps(dmpDatasetProfiles); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java index eae784aeb..ed62cda3e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DataManagementPlanNewVersionModel.java @@ -1,5 +1,6 @@ package eu.eudat.models.data.dmp; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.Dataset; @@ -260,8 +261,18 @@ public class DataManagementPlanNewVersionModel implements DataModel x.toData()).collect(Collectors.toSet())); + if (this.profiles != null) { + Set dmpDatasetProfiles = new HashSet<>(); + for (AssociatedProfile profile : this.profiles) { + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setId(profile.getId()); + dmpDatasetProfile.setDmp(entity); + dmpDatasetProfile.setDatasetprofile(profile.toData()); + dmpDatasetProfile.setData(new ObjectMapper().writeValueAsString(profile.getData())); + dmpDatasetProfiles.add(dmpDatasetProfile); + } + entity.setAssociatedDmps(dmpDatasetProfiles); + } return entity; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java new file mode 100644 index 000000000..9b1d57fbd --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DataManagementPlanBlueprint.java @@ -0,0 +1,50 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.LinkedList; +import java.util.List; + +public class DataManagementPlanBlueprint implements XmlSerializable { + + private List
sections; + + public List
getSections() { + return sections; + } + public void setSections(List
sections) { + this.sections = sections; + } + + @Override + public Element toXml(Document doc) { + Element root = doc.createElement("root"); + Element sections = doc.createElement("sections"); + for (Section section : this.sections) { + sections.appendChild(section.toXml(doc)); + } + root.appendChild(sections); + return root; + } + + @Override + public DataManagementPlanBlueprint fromXml(Element item) { + this.sections = new LinkedList<>(); + Element sections = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "sections"); + if (sections != null) { + NodeList sectionElements = sections.getChildNodes(); + for (int temp = 0; temp < sectionElements.getLength(); temp++) { + Node sectionElement = sectionElements.item(temp); + if (sectionElement.getNodeType() == Node.ELEMENT_NODE) { + this.sections.add(new Section().fromXml((Element) sectionElement)); + } + } + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java new file mode 100644 index 000000000..bec34133b --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/DescriptionTemplate.java @@ -0,0 +1,72 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class DescriptionTemplate implements XmlSerializable { + + private UUID id; + private UUID descriptionTemplateId; + private String label; + private Integer minMultiplicity; + private Integer maxMultiplicity; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public UUID getDescriptionTemplateId() { + return descriptionTemplateId; + } + public void setDescriptionTemplateId(UUID descriptionTemplateId) { + this.descriptionTemplateId = descriptionTemplateId; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public Integer getMinMultiplicity() { + return minMultiplicity; + } + public void setMinMultiplicity(Integer minMultiplicity) { + this.minMultiplicity = minMultiplicity; + } + + public Integer getMaxMultiplicity() { + return maxMultiplicity; + } + public void setMaxMultiplicity(Integer maxMultiplicity) { + this.maxMultiplicity = maxMultiplicity; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("descriptionTemplate"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("descriptionTemplateId", this.getDescriptionTemplateId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("minMultiplicity", String.valueOf(this.minMultiplicity)); + rootElement.setAttribute("maxMultiplicity", String.valueOf(this.maxMultiplicity)); + return rootElement; + } + + @Override + public DescriptionTemplate fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.descriptionTemplateId = UUID.fromString(item.getAttribute("descriptionTemplateId")); + this.label = item.getAttribute("label"); + this.minMultiplicity = Integer.valueOf(item.getAttribute("minMultiplicity")); + this.maxMultiplicity = Integer.valueOf(item.getAttribute("maxMultiplicity")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java new file mode 100644 index 000000000..f3ab20c59 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/ExtraField.java @@ -0,0 +1,93 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.ExtraFieldType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class ExtraField implements XmlSerializable { + + private UUID id; + private String label; + private String description; + private String placeholder; + private ExtraFieldType type; + private Boolean required; + private Integer ordinal; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public ExtraFieldType getType() { + return type; + } + public void setType(ExtraFieldType type) { + this.type = type; + } + + public Boolean getRequired() { + return required; + } + public void setRequired(Boolean required) { + this.required = required; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("extraField"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("placeholder", this.placeholder); + rootElement.setAttribute("type", String.valueOf(this.type.getValue())); + rootElement.setAttribute("required", String.valueOf(this.required)); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + return rootElement; + } + + @Override + public ExtraField fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.label = item.getAttribute("label"); + this.description = item.getAttribute("description"); + this.placeholder = item.getAttribute("placeholder"); + this.type = ExtraFieldType.fromInteger(Integer.parseInt(item.getAttribute("type"))); + this.required = Boolean.parseBoolean(item.getAttribute("required")); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java new file mode 100644 index 000000000..b311d005f --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/FieldModel.java @@ -0,0 +1,127 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.ExtraFieldType; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; + +import java.util.UUID; + +public class FieldModel { + + private UUID id; + private FieldCategory category; + private Integer type; + private String label; + private String placeholder; + private String description; + private Integer ordinal; + private boolean required; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public FieldCategory getCategory() { + return category; + } + public void setCategory(FieldCategory category) { + this.category = category; + } + + public Integer getType() { + return type; + } + public void setType(Integer type) { + this.type = type; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + public boolean isRequired() { + return required; + } + public void setRequired(boolean required) { + this.required = required; + } + + public SystemField toSystemField(){ + SystemField systemField = new SystemField(); + if (this.category == FieldCategory.SYSTEM) { + systemField.setId(this.id); + systemField.setType(SystemFieldType.fromInteger(this.type)); + systemField.setLabel(this.label); + systemField.setPlaceholder(this.placeholder); + systemField.setDescription(this.description); + systemField.setOrdinal(this.ordinal); + systemField.setRequired(this.required); + } + return systemField; + } + + public FieldModel fromSystemField(SystemField systemField){ + this.setId(systemField.getId()); + this.setCategory(FieldCategory.SYSTEM); + this.setType(systemField.getType().getType()); + this.setLabel(systemField.getLabel()); + this.setPlaceholder(systemField.getPlaceholder()); + this.setDescription(systemField.getDescription()); + this.setOrdinal(systemField.getOrdinal()); + this.setRequired(systemField.isRequired()); + return this; + } + + public ExtraField toExtraField(){ + ExtraField extraField = new ExtraField(); + if (this.category == FieldCategory.EXTRA) { + extraField.setId(this.id); + extraField.setType(ExtraFieldType.fromInteger(this.type)); + extraField.setLabel(this.label); + extraField.setPlaceholder(this.placeholder); + extraField.setDescription(this.description); + extraField.setOrdinal(this.ordinal); + extraField.setRequired(this.required); + } + return extraField; + } + + public FieldModel fromExtraField(ExtraField extraField){ + this.setId(extraField.getId()); + this.setCategory(FieldCategory.EXTRA); + this.setType(extraField.getType().getValue()); + this.setLabel(extraField.getLabel()); + this.setPlaceholder(extraField.getPlaceholder()); + this.setDescription(extraField.getDescription()); + this.setOrdinal(extraField.getOrdinal()); + this.setRequired(extraField.getRequired()); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java new file mode 100644 index 000000000..5a5da9a85 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/Section.java @@ -0,0 +1,149 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; + +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +public class Section implements XmlSerializable
{ + + private UUID id; + private String label; + private String description; + private Integer ordinal; + private List fields; + private Boolean hasTemplates; + private List descriptionTemplates; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + public List getFields() { + return fields; + } + public void setFields(List fields) { + this.fields = fields; + } + + public Boolean getHasTemplates() { + return hasTemplates; + } + public void setHasTemplates(Boolean hasTemplates) { + this.hasTemplates = hasTemplates; + } + + public List getDescriptionTemplates() { + return descriptionTemplates; + } + public void setDescriptionTemplates(List descriptionTemplates) { + this.descriptionTemplates = descriptionTemplates; + } + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("section"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + rootElement.setAttribute("hasTemplates", String.valueOf(this.hasTemplates)); + List temp = this.fields.stream().filter(f -> f.getCategory().equals(FieldCategory.SYSTEM)).collect(Collectors.toList()); + List systemFieldsList = temp.stream().map(FieldModel::toSystemField).collect(Collectors.toList()); + Element systemFields = doc.createElement("systemFields"); + for (SystemField systemField : systemFieldsList) { + systemFields.appendChild(systemField.toXml(doc)); + } + rootElement.appendChild(systemFields); + Element descriptionTemplates = doc.createElement("descriptionTemplates"); + for (DescriptionTemplate descriptionTemplate : this.descriptionTemplates) { + descriptionTemplates.appendChild(descriptionTemplate.toXml(doc)); + } + rootElement.appendChild(descriptionTemplates); + temp = this.fields.stream().filter(f -> f.getCategory().equals(FieldCategory.EXTRA)).collect(Collectors.toList()); + List extraFieldList = temp.stream().map(FieldModel::toExtraField).collect(Collectors.toList()); + Element extraFields = doc.createElement("extraFields"); + for (ExtraField extraField : extraFieldList) { + extraFields.appendChild(extraField.toXml(doc)); + } + rootElement.appendChild(extraFields); + + return rootElement; + } + + @Override + public Section fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.label = item.getAttribute("label"); + this.description = item.getAttribute("description"); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + this.hasTemplates = Boolean.valueOf(item.getAttribute("hasTemplates")); + this.fields = new LinkedList<>(); + Element systemFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "systemFields"); + if (systemFields != null) { + NodeList systemFieldElements = systemFields.getChildNodes(); + for (int temp = 0; temp < systemFieldElements.getLength(); temp++) { + Node systemFieldElement = systemFieldElements.item(temp); + if (systemFieldElement.getNodeType() == Node.ELEMENT_NODE) { + SystemField systemField = new SystemField().fromXml((Element) systemFieldElement); + this.fields.add(new FieldModel().fromSystemField(systemField)); + } + } + } + this.descriptionTemplates = new LinkedList<>(); + Element descriptionTemplates = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "descriptionTemplates"); + if (descriptionTemplates != null) { + NodeList descriptionTemplateElements = descriptionTemplates.getChildNodes(); + for (int temp = 0; temp < descriptionTemplateElements.getLength(); temp++) { + Node descriptionTemplateElement = descriptionTemplateElements.item(temp); + if (descriptionTemplateElement.getNodeType() == Node.ELEMENT_NODE) { + this.descriptionTemplates.add(new DescriptionTemplate().fromXml((Element) descriptionTemplateElement)); + } + } + } + Element extraFields = (Element) XmlBuilder.getNodeFromListByTagName(item.getChildNodes(), "extraFields"); + if (extraFields != null) { + NodeList extraFieldElements = extraFields.getChildNodes(); + for (int temp = 0; temp < extraFieldElements.getLength(); temp++) { + Node extraFieldElement = extraFieldElements.item(temp); + if (extraFieldElement.getNodeType() == Node.ELEMENT_NODE) { + ExtraField extraField = new ExtraField().fromXml((Element) extraFieldElement); + this.fields.add(new FieldModel().fromExtraField(extraField)); + } + } + } + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java new file mode 100644 index 000000000..419a9ccd9 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/SystemField.java @@ -0,0 +1,94 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition; + +import eu.eudat.logic.utilities.interfaces.XmlSerializable; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.util.UUID; + +public class SystemField implements XmlSerializable { + + private UUID id; + private SystemFieldType type; + private String label; + private String placeholder; + private String description; + private boolean required; + private Integer ordinal; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public SystemFieldType getType() { + return type; + } + public void setType(SystemFieldType type) { + this.type = type; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public String getPlaceholder() { + return placeholder; + } + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + public String getDescription() { + return description; + } + public void setDescription(String description) { + this.description = description; + } + + public boolean isRequired() { + return required; + } + public void setRequired(boolean required) { + this.required = required; + } + + public Integer getOrdinal() { + return ordinal; + } + public void setOrdinal(Integer ordinal) { + this.ordinal = ordinal; + } + + + @Override + public Element toXml(Document doc) { + Element rootElement = doc.createElement("systemField"); + rootElement.setAttribute("id", this.getId().toString()); + rootElement.setAttribute("type", String.valueOf(this.type.getType())); + rootElement.setAttribute("label", this.label); + rootElement.setAttribute("placeholder", this.placeholder); + rootElement.setAttribute("description", this.description); + rootElement.setAttribute("required", String.valueOf(this.required)); + rootElement.setAttribute("ordinal", String.valueOf(this.ordinal)); + return rootElement; + } + + @Override + public SystemField fromXml(Element item) { + this.id = UUID.fromString(item.getAttribute("id")); + this.type = SystemFieldType.fromInteger(Integer.parseInt(item.getAttribute("type"))); + this.label = item.getAttribute("label"); + this.placeholder = item.getAttribute("placeholder"); + this.description = item.getAttribute("description"); + this.required = Boolean.parseBoolean(item.getAttribute("required")); + this.ordinal = Integer.valueOf(item.getAttribute("ordinal")); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java new file mode 100644 index 000000000..6aa7fc24e --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/ExtraFieldType.java @@ -0,0 +1,30 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum ExtraFieldType { + TEXT(0), RICH_TEXT(1), DATE(2), NUMBER(3); + + private Integer value; + + private ExtraFieldType(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + + public static ExtraFieldType fromInteger(Integer value) { + switch (value) { + case 0: + return TEXT; + case 1: + return RICH_TEXT; + case 2: + return DATE; + case 3: + return NUMBER; + default: + throw new RuntimeException("Unsupported ExtraFieldType Type"); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java new file mode 100644 index 000000000..cec77366d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/FieldCategory.java @@ -0,0 +1,27 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum FieldCategory { + SYSTEM(0), + EXTRA(1); + + private Integer value; + + private FieldCategory(Integer value) { + this.value = value; + } + + public Integer getValue() { + return value; + } + + public static FieldCategory fromInteger(Integer value) { + switch (value) { + case 0: + return SYSTEM; + case 1: + return EXTRA; + default: + throw new RuntimeException("Unsupported FieldCategory Type"); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java new file mode 100644 index 000000000..d7c36023a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/dmpprofiledefinition/types/SystemFieldType.java @@ -0,0 +1,55 @@ +package eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types; + +public enum SystemFieldType { + + TEXT(0), + HTML_TEXT(1), + RESEARCHERS(2), + ORGANIZATIONS(3), + LANGUAGE(4), + CONTACT(5), + FUNDER(6), + GRANT(7), + PROJECT(8), + LICENSE(9), + ACCESS_RIGHTS(10); + + private int type; + + SystemFieldType(int type) { + this.type = type; + } + + public int getType() { + return type; + } + + public static SystemFieldType fromInteger(int type) { + switch (type) { + case 0: + return TEXT; + case 1: + return HTML_TEXT; + case 2: + return RESEARCHERS; + case 3: + return ORGANIZATIONS; + case 4: + return LANGUAGE; + case 5: + return CONTACT; + case 6: + return FUNDER; + case 7: + return GRANT; + case 8: + return PROJECT; + case 9: + return LICENSE; + case 10: + return ACCESS_RIGHTS; + default: + throw new RuntimeException("Unsupported System Field Type"); + } + } +} \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java new file mode 100644 index 000000000..d0788c1af --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanBlueprintListingModel.java @@ -0,0 +1,93 @@ +package eu.eudat.models.data.listingmodels; + +import eu.eudat.data.entities.DMPProfile; +import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.models.DataModel; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint; +import org.w3c.dom.Document; + +import java.util.Date; +import java.util.UUID; + +public class DataManagementPlanBlueprintListingModel implements DataModel { + + private UUID id; + private String label; + private DataManagementPlanBlueprint definition; + private int status; + private Date created = null; + private Date modified = new Date(); + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + public DataManagementPlanBlueprint getDefinition() { + return definition; + } + public void setDefinition(DataManagementPlanBlueprint definition) { + this.definition = definition; + } + + public int getStatus() { + return status; + } + public void setStatus(int status) { + this.status = status; + } + + public Date getCreated() { + return created; + } + public void setCreated(Date created) { + this.created = created; + } + + public Date getModified() { + return modified; + } + public void setModified(Date modified) { + this.modified = modified; + } + + @Override + public DataManagementPlanBlueprintListingModel fromDataModel(DMPProfile entity) { + this.id = entity.getId(); + this.created = entity.getCreated(); + this.definition = new DataManagementPlanBlueprint().fromXml(XmlBuilder.fromXml(entity.getDefinition()).getDocumentElement()); + this.modified = entity.getModified(); + this.label = entity.getLabel(); + this.status = entity.getStatus(); + return this; + } + + @Override + public DMPProfile toDataModel() throws Exception { + Document document = XmlBuilder.getDocument(); + document.appendChild(this.definition.toXml(document)); + DMPProfile dmpProfile = new DMPProfile(); + dmpProfile.setCreated(this.created == null ? new Date() : this.created); + dmpProfile.setDefinition(XmlBuilder.generateXml(document)); + dmpProfile.setId(this.id); + dmpProfile.setLabel(this.label); + dmpProfile.setStatus(this.status); + dmpProfile.setModified(this.modified == null ? new Date() : this.modified); + return dmpProfile; + } + + @Override + public String getHint() { + return null; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java index c207ab1fb..1c79930b0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanOverviewModel.java @@ -1,8 +1,11 @@ package eu.eudat.models.data.listingmodels; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.DMPDatasetProfile; import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.DataModel; import eu.eudat.models.data.dataset.DatasetOverviewModel; import eu.eudat.models.data.dmp.AssociatedProfile; @@ -11,10 +14,7 @@ import eu.eudat.models.data.dmp.Researcher; import eu.eudat.models.data.doi.Doi; import eu.eudat.models.data.grant.GrantOverviewModel; -import java.util.Date; -import java.util.LinkedList; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; public class DataManagementPlanOverviewModel implements DataModel { @@ -205,8 +205,14 @@ public class DataManagementPlanOverviewModel implements DataModel(); - for (DatasetProfile datasetProfile : entity.getAssociatedDmps()) { - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(datasetProfile); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfile associatedProfile = new AssociatedProfile().fromData(dmpDescriptionProfile.getDatasetprofile()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.associatedProfiles.add(associatedProfile); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java index 5b3392689..1806e1eb7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DatasetDescriptionQuickWizardModel.java @@ -1,15 +1,13 @@ package eu.eudat.models.data.quickwizard; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.models.data.datasetprofile.DatasetProfileOverviewModel; import eu.eudat.models.data.dmp.DataManagementPlan; -import eu.eudat.data.entities.Dataset; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import java.util.Date; -import java.util.UUID; public class DatasetDescriptionQuickWizardModel extends PagedDatasetProfile { @@ -24,7 +22,7 @@ public class DatasetDescriptionQuickWizardModel extends PagedDatasetProfile { } - public DatasetWizardModel toDataModel(DataManagementPlan dmp, DatasetProfile profile){ + public DatasetWizardModel toDataModel(DataManagementPlan dmp, DescriptionTemplate profile){ DatasetWizardModel newDataset = new DatasetWizardModel(); newDataset.setLabel(datasetLabel); newDataset.setCreated(new Date()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java index d67f9724b..5f2be414a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/quickwizard/DmpQuickWizardModel.java @@ -1,5 +1,6 @@ package eu.eudat.models.data.quickwizard; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.entities.Grant; import eu.eudat.data.entities.Project; import eu.eudat.models.data.dmp.AssociatedProfile; @@ -107,12 +108,12 @@ public class DmpQuickWizardModel { } - public eu.eudat.data.entities.DatasetProfile getDatasetProfile() { - eu.eudat.data.entities.DatasetProfile datasetProfile = new eu.eudat.data.entities.DatasetProfile(); - datasetProfile.setDefinition(this.datasetProfile.getLabel()); - datasetProfile.setLabel(this.datasetProfile.getLabel()); - datasetProfile.setId(this.datasetProfile.getId()); - return datasetProfile; + public DescriptionTemplate getDatasetProfile() { + DescriptionTemplate descriptionTemplate = new DescriptionTemplate(); + descriptionTemplate.setDefinition(this.datasetProfile.getLabel()); + descriptionTemplate.setLabel(this.datasetProfile.getLabel()); + descriptionTemplate.setId(this.datasetProfile.getDescriptionTemplateId()); + return descriptionTemplate; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java index d7b29e2b3..256bdbe0a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java @@ -2,8 +2,8 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.data.entities.DatasetProfile; import com.fasterxml.jackson.databind.node.ArrayNode; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.entities.Tag; import eu.eudat.logic.managers.DatasetManager; @@ -280,12 +280,12 @@ public class DatasetRDAMapper { } - public eu.eudat.data.entities.Dataset toEntity(Dataset rda, DatasetProfile defaultProfile) { + public eu.eudat.data.entities.Dataset toEntity(Dataset rda, DescriptionTemplate defaultProfile) { eu.eudat.data.entities.Dataset entity = new eu.eudat.data.entities.Dataset(); entity.setLabel(rda.getTitle()); entity.setDescription(rda.getDescription()); try { - DatasetProfile profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(rda.getAdditionalProperties().get("template").toString())); + DescriptionTemplate profile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(rda.getAdditionalProperties().get("template").toString())); entity.setProfile(profile); }catch(Exception e) { logger.warn(e.getMessage(), e); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java index 2b3a2f61a..22b7dc0d9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DmpRDAMapper.java @@ -124,16 +124,15 @@ public class DmpRDAMapper { entity.setDois(new HashSet<>()); } } - if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty()) { - entity.setAssociatedDmps(((List) rda.getAdditionalProperties().get("templates")).stream().map(this::getProfile).filter(Objects::nonNull).collect(Collectors.toSet())); + if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty() && entity.getId() != null) { + entity.setAssociatedDmps(((List) rda.getAdditionalProperties().get("templates")).stream().map(x -> this.getProfile(x, entity.getId())).filter(Objects::nonNull).collect(Collectors.toSet())); } if (entity.getAssociatedDmps() == null) { entity.setAssociatedDmps(new HashSet<>()); } - if (profiles != null) { + if (profiles != null && entity.getId() != null) { for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); - entity.getAssociatedDmps().add(exProfile); + entity.getAssociatedDmps().add(this.getProfile(profile, entity.getId())); } } if (rda.getContributor() != null && !rda.getContributor().isEmpty() && rda.getContributor().get(0).getContributorId() != null) { @@ -142,7 +141,7 @@ public class DmpRDAMapper { entity.setCreated(rda.getCreated()); entity.setModified(rda.getModified()); entity.setDescription(rda.getDescription()); - DatasetProfile defaultProfile = ((DatasetProfile)entity.getAssociatedDmps().toArray()[0]); + DescriptionTemplate defaultProfile = ((DescriptionTemplate)entity.getAssociatedDmps().toArray()[0]); entity.setDataset(rda.getDataset().stream().map(rda1 -> datasetRDAMapper.toEntity(rda1, defaultProfile)).collect(Collectors.toSet())); if (rda.getProject().size() > 0) { Map result = ProjectRDAMapper.toEntity(rda.getProject().get(0), apiContext); @@ -158,7 +157,10 @@ public class DmpRDAMapper { return entity; } - private DatasetProfile getProfile(String id) { - return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().asQueryable().where(((builder, root) -> builder.equal(root.get("id"), UUID.fromString(id)))).getSingleOrDefault(); + private DMPDatasetProfile getProfile(String descriptionTemplateId, UUID dmpId) { + return apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().asQueryable().where(((builder, root) -> builder.and( + builder.equal(root.get("datasetprofile"), UUID.fromString(descriptionTemplateId)), + builder.equal(root.get("dmp"), dmpId)) + )).getSingleOrDefault(); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java index e94db3db8..7e88973c0 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java @@ -1,6 +1,7 @@ package eu.eudat.publicapi.managers; import eu.eudat.data.entities.Dataset; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.data.query.definition.helpers.ColumnOrderings; import eu.eudat.elastic.criteria.DatasetCriteria; import eu.eudat.elastic.repository.DatasetRepository; @@ -139,10 +140,10 @@ public class DatasetPublicManager { DatasetPublicListingModel listingPublicModel = new DatasetPublicListingModel().fromDataModel(item); /*DatasetProfileCriteria criteria = new DatasetProfileCriteria(); criteria.setGroupIds(Collections.singletonList(item.getProfile().getGroupId())); - List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); + List profiles = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().getWithCriteria(criteria).toList(); boolean islast = false; if (!profiles.isEmpty()) { - profiles = profiles.stream().sorted(Comparator.comparing(DatasetProfile::getVersion)).collect(Collectors.toList()); + profiles = profiles.stream().sorted(Comparator.comparing(DescriptionTemplate::getVersion)).collect(Collectors.toList()); islast = profiles.get(0).getId().equals(item.getProfile().getId()); } listingModel.setProfileLatestVersion(islast);*/ @@ -162,7 +163,7 @@ public class DatasetPublicManager { return pagedDatasetProfile; } - private eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(eu.eudat.data.entities.DatasetProfile profile) { + private eu.eudat.models.data.user.composite.DatasetProfile generateDatasetProfileModel(DescriptionTemplate profile) { Document viewStyleDoc = XmlBuilder.fromXml(profile.getDefinition()); Element root = (Element) viewStyleDoc.getDocumentElement(); eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewstyle = new eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel().fromXml(root); diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java index 10edac3ca..b04f57678 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/associatedprofile/AssociatedProfilePublicModel.java @@ -1,15 +1,18 @@ package eu.eudat.publicapi.models.associatedprofile; -import eu.eudat.data.entities.DatasetProfile; +import eu.eudat.data.entities.DescriptionTemplate; import eu.eudat.logic.utilities.interfaces.XmlSerializable; import org.w3c.dom.Document; import org.w3c.dom.Element; +import java.util.Map; import java.util.UUID; public class AssociatedProfilePublicModel implements XmlSerializable { private UUID id; + private UUID descriptionTemplateId; private String label; + private Map data; public UUID getId() { return id; @@ -19,6 +22,14 @@ public class AssociatedProfilePublicModel implements XmlSerializable getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + @Override public Element toXml(Document doc) { Element profile = doc.createElement("profile"); @@ -37,20 +56,20 @@ public class AssociatedProfilePublicModel implements XmlSerializable { +public class DatasetProfilePublicModel implements DataModel { private UUID id; private String label; @@ -24,15 +24,15 @@ public class DatasetProfilePublicModel implements DataModel(); - for (DatasetProfile datasetProfile : entity.getAssociatedDmps()) { - AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(datasetProfile); + for (DMPDatasetProfile dmpDescriptionProfile : entity.getAssociatedDmps()) { + AssociatedProfilePublicModel associatedProfile = new AssociatedProfilePublicModel().fromData(dmpDescriptionProfile.getDatasetprofile()); + associatedProfile.setId(dmpDescriptionProfile.getId()); + try { + associatedProfile.setData(new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {})); + } + catch (Exception e) { + associatedProfile.setData(null); + } this.associatedProfiles.add(associatedProfile); } } @@ -217,7 +228,7 @@ public class DataManagementPlanPublicModel implements DataModel
',1, now(),now()); +UPDATE public."DMP" SET ("Profile") = '1374c46d-55b5-472a-8e10-c6ee8c0b5f7f' WHERE "Profile" IS NULL; +UPDATE public."Dataset" SET ("DmpSectionIndex") = '3' WHERE "DmpSectionIndex" IS NULL; +UPDATE public."DMPDatasetProfile" SET ("data") = '{"dmpSectionIndex":[3]}' WHERE "data" IS NULL; + +ALTER TABLE public."Dataset" +ALTER COLUMN "DmpSectionIndex" SET NOT NULL; + +ALTER TABLE public."DMPDatasetProfile" +ALTER COLUMN "data" SET NOT NULL; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.016', '2023-09-12 12:00:00.000000+02', now(), 'Insert default blueprint, update profile of existing dmps and update DmpSectionIndex for each dataset.'); + +END$$; \ No newline at end of file diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 3cba707ac..e13c1e00b 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -47,7 +47,7 @@ const appRoutes: Routes = [ loadChildren: () => import('./ui/dataset/dataset.module').then(m => m.DatasetModule), data: { breadcrumb: true, - title: 'GENERAL.TITLES.DATASETS' + title: 'GENERAL.TITLES.DESCRIPTIONS' } }, { @@ -80,7 +80,7 @@ const appRoutes: Routes = [ loadChildren: () => import('./ui/admin/dmp-profile/dmp-profile.module').then(m => m.DmpProfileModule), data: { breadcrumb: true, - title: 'GENERAL.TITLES.DMP-PROFILES' + title: 'GENERAL.TITLES.DMP-BLUEPRINTS' } }, { @@ -99,6 +99,14 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.DATASET-PROFILES' } }, + { + path: 'description-types', + loadChildren: () => import('./ui/admin/description-types/description-types.module').then(m => m.DescriptionTypesModule), + data: { + breadcrumb: true, + title: 'GENERAL.TITLES.DESCRIPTION-TYPES' + } + }, { path: 'contact-support', loadChildren: () => import('./ui/contact/contact.module').then(m => m.ContactModule), diff --git a/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts b/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts new file mode 100644 index 000000000..e41dc95b9 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/description-template-type-status.ts @@ -0,0 +1,5 @@ +export enum DescriptionTemplateTypeStatus { + Draft = 0, + Finalized = 1, + Deleted = 99 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index 5186586e6..bbe2356b9 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -52,6 +52,7 @@ import { FaqService } from './services/faq/faq.service'; import { GlossaryService } from './services/glossary/glossary.service'; import { TermsOfServiceService } from './services/terms-of-service/terms-of-service.service'; import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service'; +import { DescriptionTemplateTypeService } from './services/description-template-type/description-template-type.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -132,7 +133,8 @@ export class CoreServiceModule { multi: true }, LanguageInfoService, - PrefillingService + PrefillingService, + DescriptionTemplateTypeService ], }; } diff --git a/dmp-frontend/src/app/core/formatting.module.ts b/dmp-frontend/src/app/core/formatting.module.ts index cac6237cb..fc082e27b 100644 --- a/dmp-frontend/src/app/core/formatting.module.ts +++ b/dmp-frontend/src/app/core/formatting.module.ts @@ -9,6 +9,7 @@ import { JsonParserPipe } from './pipes/json-parser.pipe'; import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe'; import {FieldValuePipe} from "@app/core/pipes/field-value.pipe"; import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; +import { DatasetInSectioPipe } from './pipes/dataset-in-section.pipe'; // // @@ -25,7 +26,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ], exports: [ NgForLimitPipe, @@ -35,7 +37,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ], providers: [ EnumUtils, @@ -47,7 +50,8 @@ import {ColumnClassPipe} from "@app/core/pipes/column-class.pipe"; DateTimeCultureFormatPipe, JsonParserPipe, FieldValuePipe, - ColumnClassPipe + ColumnClassPipe, + DatasetInSectioPipe ] }) export class FormattingModule { } diff --git a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts index 8f8ec30d7..68b0d64db 100644 --- a/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts +++ b/dmp-frontend/src/app/core/model/admin/dataset-profile/dataset-profile.ts @@ -3,6 +3,7 @@ import { UserInfoListingModel } from "../../user/user-info-listing"; export interface DatasetProfile { label: string; + type: string; sections: Section[]; pages: Page[]; status: number; diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts b/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts index 48a031cfa..ccbe8d43c 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-wizard.ts @@ -14,6 +14,7 @@ export interface DatasetWizardModel { description?: String; status?: number; dmp?: DmpModel; + dmpSectionIndex?: number; datasetProfileDefinition?: DatasetProfileDefinitionModel; registries?: RegistryModel[]; services?: ServiceModel[]; diff --git a/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts new file mode 100644 index 000000000..1b2812e09 --- /dev/null +++ b/dmp-frontend/src/app/core/model/description-template-type/description-template-type.ts @@ -0,0 +1,5 @@ +export interface DescriptionTemplateType { + id: string; + name: string; + status: number; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts new file mode 100644 index 000000000..77d74a616 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing.ts @@ -0,0 +1,10 @@ +import { DmpBlueprintDefinition } from "./dmp-blueprint"; + +export interface DmpBlueprintListing { + id: string; + label: string; + definition: DmpBlueprintDefinition; + status: number; + created: Date; + modified: Date; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts new file mode 100644 index 000000000..eda8fd506 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-blueprint/dmp-blueprint.ts @@ -0,0 +1,68 @@ +export interface DmpBlueprint { + id: string; + label: string; + definition: DmpBlueprintDefinition; + status: number; + created: Date; + modified: Date; + description: string; +} + +export interface DmpBlueprintDefinition { + sections: SectionDmpBlueprint[]; +} + +export interface SectionDmpBlueprint { + id: string; + label: string; + description: string; + ordinal: number; + fields: FieldInSection[]; + hasTemplates: boolean; + descriptionTemplates?: DescriptionTemplatesInSection[]; +} + +export interface FieldInSection { + id: string; + category: FieldCategory; + type: number; + label: string; + placeholder: string; + description: string; + required: boolean; + ordinal: number; +} + +export enum FieldCategory { + SYSTEM = 0, + EXTRA = 1 +} + +export enum SystemFieldType { + TEXT = 0, + HTML_TEXT = 1, + RESEARCHERS= 2, + ORGANIZATIONS = 3, + LANGUAGE = 4, + CONTACT = 5, + FUNDER = 6, + GRANT = 7, + PROJECT = 8, + LICENSE = 9, + ACCESS_RIGHTS = 10 +} + +export interface DescriptionTemplatesInSection { + id: string; + descriptionTemplateId: string; + label: string; + minMultiplicity: number; + maxMultiplicity: number; +} + +export enum ExtraFieldType { + TEXT = 0, + RICH_TEXT = 1, + DATE = 2, + NUMBER = 3 +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts new file mode 100644 index 000000000..8f0745359 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model.ts @@ -0,0 +1,28 @@ +import { FormGroup, FormBuilder } from "@angular/forms"; +import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; +import { ValidationContext } from "@common/forms/validation/validation-context"; + +export class DmpDatasetProfileSectionsFormModel { + public dmpSectionIndex: number[] = []; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: any): DmpDatasetProfileSectionsFormModel { + this.dmpSectionIndex = item.dmpSectionIndex; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + language: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators], + }); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] }); + return baseContext; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts new file mode 100644 index 000000000..043f4d525 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile.ts @@ -0,0 +1,8 @@ +import { DmpDatasetProfileSectionsFormModel } from "./dmp-dataset-profile-sections-form.model"; + +export interface DmpDatasetProfile { + id: string; + descriptionTemplateId: string; + label: string; + data: DmpDatasetProfileSectionsFormModel; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index 2ebc47fcc..d26912dc4 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -1,17 +1,15 @@ -import { Status } from "../../common/enum/status"; -import { DmpProfile, DmpProfileDefinition } from "../dmp-profile/dmp-profile"; +import { DmpProfileDefinition } from "../dmp-profile/dmp-profile"; import { OrganizationModel } from "../organisation/organization"; import { GrantListingModel } from "../grant/grant-listing"; import { ResearcherModel } from "../researcher/researcher"; import { UserModel } from "../user/user"; import { DmpDynamicField } from "./dmp-dynamic-field"; import { UserInfoListingModel } from "../user/user-info-listing"; -import { DatasetModel } from "../dataset/dataset"; import { ProjectModel } from "../project/project"; import { FunderModel } from "../funder/funder"; import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { ExtraPropertiesFormModel } from '@app/ui/dmp/editor/general-tab/extra-properties-form.model'; import { DatasetWizardModel } from '../dataset/dataset-wizard'; +import { DmpDatasetProfile } from "./dmp-dataset-profile/dmp-dataset-profile"; export interface DmpModel { id: string; @@ -27,7 +25,7 @@ export interface DmpModel { funder: FunderModel; datasets: DatasetWizardModel[]; datasetsToBeFinalized: string[]; - profiles: DmpProfile[]; + profiles: DmpDatasetProfile[]; organisations: OrganizationModel[]; researchers: ResearcherModel[]; associatedUsers: UserModel[]; diff --git a/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts b/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts new file mode 100644 index 000000000..7d0e12f6d --- /dev/null +++ b/dmp-frontend/src/app/core/pipes/dataset-in-section.pipe.ts @@ -0,0 +1,18 @@ +import { Pipe, PipeTransform } from "@angular/core"; +import { FormGroup } from "@angular/forms"; + +@Pipe({ + name: 'datasetInSection' +}) +export class DatasetInSectioPipe implements PipeTransform{ + + transform(datasets: FormGroup[], args: string): FormGroup[] { + let values = []; + for(var dataset of datasets){ + if(dataset.get('dmpSectionIndex').value == args){ + values.push(dataset); + } + } + return values; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts b/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts new file mode 100644 index 000000000..8f9a77042 --- /dev/null +++ b/dmp-frontend/src/app/core/query/dmp/dmp-blueprint-criteria.ts @@ -0,0 +1,5 @@ +import { BaseCriteria } from "../base-criteria"; + +export class DmpBlueprintCriteria extends BaseCriteria { + +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts new file mode 100644 index 000000000..a40b02569 --- /dev/null +++ b/dmp-frontend/src/app/core/services/description-template-type/description-template-type.service.ts @@ -0,0 +1,38 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpService } from '../http/base-http.service'; +import { Observable } from 'rxjs'; +import { DataTableData } from '@app/core/model/data-table/data-table-data'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; + +@Injectable() +export class DescriptionTemplateTypeService { + + private actionUrl: string; + private headers = new HttpHeaders(); + + constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { + this.actionUrl = configurationService.server + 'descriptionTemplateType/'; + } + + getTypes(): Observable> { + return this.http.get>(this.actionUrl + 'get', { headers: this.headers }); + } + + getSingle(id: string): Observable { + return this.http.get(this.actionUrl + 'get/' + id, { headers: this.headers }); + } + + createType(type: DescriptionTemplateType): Observable { + return this.http.post(this.actionUrl + 'create', type, { headers: this.headers }); + } + + updateType(type: DescriptionTemplateType): Observable { + return this.http.post(this.actionUrl + 'update', type, { headers: this.headers }); + } + + deleteType(id: string): Observable { + return this.http.delete(this.actionUrl + 'delete/' + id, { headers: this.headers }); + } +} diff --git a/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts index 9b9f16f39..94b666594 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp-profile.service.ts @@ -14,6 +14,9 @@ import { BaseHttpParams } from '../../../../common/http/base-http-params'; import { InterceptorType } from '../../../../common/http/interceptors/interceptor-type'; import { DmpProfileExternalAutocompleteCriteria } from '../../query/dmp/dmp-profile-external-autocomplete-criteria'; import { ConfigurationService } from '../configuration/configuration.service'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing'; +import { DmpBlueprint } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Injectable() export class DmpProfileService { @@ -29,14 +32,26 @@ export class DmpProfileService { return this.http.post>(this.actionUrl + 'getPaged', dataTableRequest, { headers: this.headers }); } + getPagedBlueprint(dataTableRequest: DataTableRequest): Observable> { + return this.http.post>(this.actionUrl + 'getPagedBlueprint', dataTableRequest, { headers: this.headers }); + } + getSingle(id: String): Observable { return this.http.get(this.actionUrl + 'getSingle/' + id, { headers: this.headers }); } + getSingleBlueprint(id: String): Observable { + return this.http.get(this.actionUrl + 'getSingleBlueprint/' + id, { headers: this.headers }); + } + createDmp(dataManagementPlanModel: DmpProfile): Observable { return this.http.post(this.actionUrl, dataManagementPlanModel, { headers: this.headers }); } + createBlueprint(dmpBlueprint: DmpBlueprint): Observable { + return this.http.post(this.actionUrl + 'blueprint', dmpBlueprint, { headers: this.headers }); + } + public downloadXML(id: string): Observable> { let headerXml: HttpHeaders = this.headers.set('Content-Type', 'application/xml') return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml }); 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 94e9ca3dc..b33a781c5 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 @@ -30,7 +30,7 @@ export class EnumUtils { case AppRole.Admin: return this.language.instant('TYPES.APP-ROLE.ADMIN'); case AppRole.User: return this.language.instant('TYPES.APP-ROLE.USER'); case AppRole.Manager: return this.language.instant('TYPES.APP-ROLE.MANAGER'); - case AppRole.DatasetTemplateEditor: return this.language.instant('TYPES.APP-ROLE.DATASET-TEMPLATE-EDITOR'); + case AppRole.DatasetTemplateEditor: return this.language.instant('TYPES.APP-ROLE.DESCRIPTION-TEMPLATE-EDITOR'); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts index d3cf2775e..059a1feb0 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor-model.ts @@ -15,6 +15,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { public status: number; public version: number; private description: string; + private type: string; private language: string; private users: UserInfoListingModel[] = []; @@ -22,6 +23,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { if (item.sections) { this.sections = item.sections.map(x => new SectionEditorModel().fromModel(x)); } if (item.pages) { this.pages = item.pages.map(x => new PageEditorModel().fromModel(x)); } this.label = item.label; + this.type = item.type; this.status = item.status; this.version = item.version; this.description = item.description; @@ -34,6 +36,7 @@ export class DatasetProfileEditorModel extends BaseFormModel { const formGroup: FormGroup = new FormBuilder().group({ label: [{ value: this.label, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.label')) }, [Validators.required]], description: [{ value: this.description, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.description')) }, [Validators.required]], + type: [{ value: this.type, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.type')) }, [Validators.required]], language: [{ value: this.language, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.language')) }, [Validators.required]], status: [{ value: this.status, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.status')) }], version: [{ value: this.version, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.version')) }], diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html index 03750188c..6604815b9 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.html @@ -142,8 +142,21 @@
- -
1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *
+
1.3 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-TYPE'| translate}} *
+ + + + {{ type.name }} + + + {{'GENERAL.VALIDATION.REQUIRED' | + translate}} + + +
+
+ +
1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-LANGUAGE'| translate}} *
@@ -157,7 +170,7 @@
-
1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
+
1.5 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts index be47cb207..904ab51ad 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.ts @@ -45,6 +45,9 @@ import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profil import { UserService } from '@app/core/services/user/user.service'; import { MatInput } from '@angular/material/input'; import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; +import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; const skipDisable: any[] = require('../../../../../assets/resources/skipDisable.json'); @@ -80,6 +83,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent tocEntryEnumValues = ToCEntryType; public userChipList:any[] = []; displayedColumns: String[] = ['name', 'email', 'button']; + descriptionTemplateTypes: DescriptionTemplateType[] = []; colorizeInvalid:boolean = false; inputUserState: 'untriggered'| 'triggered' = 'untriggered'; @@ -112,7 +116,8 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent private visibilityRulesService: VisibilityRulesService, private fb: FormBuilder, private sidenavService: SideNavService, - private userService: UserService + private userService: UserService, + private descriptionTemplateTypeService: DescriptionTemplateTypeService ) { super(); // this.profileID = route.snapshot.params['id']; @@ -227,6 +232,7 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent } }); + this.getDescriptionTemplateTypes(); combineLatest(this._inputUserButton$.asObservable(),this._inputUserField$.asObservable()) .pipe(takeUntil(this._destroyed)) @@ -600,6 +606,14 @@ export class DatasetProfileEditorComponent extends CheckDeactivateBaseComponent return filename; } + getDescriptionTemplateTypes(): DescriptionTemplateType[] { + this.descriptionTemplateTypeService.getTypes().pipe(takeUntil(this._destroyed)) + .subscribe(types => { + this.descriptionTemplateTypes = types.data.filter(type => type.status === DescriptionTemplateTypeStatus.Finalized); + }); + return this.descriptionTemplateTypes; + } + getLanguageInfos(): LanguageInfo[] { return this.languageInfoService.getLanguageInfoValues(); } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html index c1036626b..adb990e47 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html @@ -8,7 +8,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts new file mode 100644 index 000000000..2871d2c57 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.module.ts @@ -0,0 +1,21 @@ +import { NgModule } from '@angular/core'; +import { CommonModule } from '@angular/common'; +import { DescriptionTypesRoutingModule } from './description-types.routing'; +import { DescriptionTypesComponent } from './listing/description-types.component'; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; + +@NgModule({ + declarations: [ + DescriptionTypesComponent, + DescriptionTypeEditorComponent + ], + imports: [ + CommonModule, + CommonUiModule, + CommonFormsModule, + DescriptionTypesRoutingModule + ] +}) +export class DescriptionTypesModule { } diff --git a/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts new file mode 100644 index 000000000..fea0e116d --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/description-types.routing.ts @@ -0,0 +1,17 @@ +import { NgModule } from "@angular/core"; +import { RouterModule, Routes } from "@angular/router"; +import { AdminAuthGuard } from "@app/core/admin-auth-guard.service"; +import { DescriptionTypeEditorComponent } from './editor/description-type-editor.component'; +import { DescriptionTypesComponent } from "./listing/description-types.component"; + +const routes: Routes = [ + { path: '', component: DescriptionTypesComponent, canActivate: [AdminAuthGuard] }, + { path: 'new', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-NEW' } }, + { path: ':id', component: DescriptionTypeEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DESCRIPTION-TYPE-EDIT' } } +] + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class DescriptionTypesRoutingModule { } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html new file mode 100644 index 000000000..6c818cfab --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.html @@ -0,0 +1,38 @@ +
+
+
+
+

{{'DESCRIPTION-TYPE-EDITOR.NEW' | translate}}

+
+
+
+ + +
+ + + + {{formGroup.get('name').getError('backendError').message}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+ +
+
+
+ + +
+
+
+
+ +
+
diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss new file mode 100644 index 000000000..93d519a62 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.scss @@ -0,0 +1,24 @@ +.description-type-editor { + margin-top: 1.3rem; + margin-left: 1em; + margin-right: 3em; +} + +.action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts new file mode 100644 index 000000000..b430fc263 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-type-editor.component.ts @@ -0,0 +1,161 @@ +import { AfterViewInit, Component, OnInit } from '@angular/core'; +import { FormBuilder, FormGroup, Validators } from '@angular/forms'; +import { ActivatedRoute, ParamMap, Router } from '@angular/router'; +import { DescriptionTemplateTypeStatus } from '@app/core/common/enum/description-template-type-status'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { BaseComponent } from '@common/base/base.component'; +import { FormService } from '@common/forms/form-service'; +import { BackendErrorValidator } from '@common/forms/validation/custom-validator'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { ValidationContext } from '@common/forms/validation/validation-context'; +import { TranslateService } from '@ngx-translate/core'; +import { takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-description-type-editor', + templateUrl: './description-type-editor.component.html', + styleUrls: ['./description-type-editor.component.scss'] +}) +export class DescriptionTypeEditorComponent extends BaseComponent implements OnInit { + + formGroup: FormGroup = null; + descriptionTypeModel: DescriptionTypeEditorModel; + + isNew = true; + viewOnly = false; + descriptionTemplateTypeId: string; + + constructor( + private descriptionTemplateTypeService: DescriptionTemplateTypeService, + private formService: FormService, + private uiNotificationService: UiNotificationService, + private language: TranslateService, + private route: ActivatedRoute, + private router: Router + ) { + super(); + } + + ngOnInit(): void { + this.route.paramMap.pipe(takeUntil(this._destroyed)).subscribe((paramMap: ParamMap) => { + this.descriptionTemplateTypeId = paramMap.get('id'); + + if (this.descriptionTemplateTypeId != null) { + this.isNew = false; + this.descriptionTemplateTypeService.getSingle(this.descriptionTemplateTypeId) + .pipe(takeUntil(this._destroyed)).subscribe( + type => { + this.descriptionTypeModel = new DescriptionTypeEditorModel().fromModel(type); + if(this.descriptionTypeModel.status === DescriptionTemplateTypeStatus.Finalized){ + this.formGroup = this.descriptionTypeModel.buildForm(null, true); + this.viewOnly = true; + } + else{ + this.formGroup = this.descriptionTypeModel.buildForm(); + } + }, + error => this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error) + ); + } + else { + this.descriptionTypeModel = new DescriptionTypeEditorModel(); + this.descriptionTypeModel.status = DescriptionTemplateTypeStatus.Draft; + this.formGroup = this.descriptionTypeModel.buildForm(); + } + }); + } + + formSubmit(): void { + this.formService.touchAllFormFields(this.formGroup); + if (!this.isFormValid()) { return; } + this.onSubmit(); + } + + public isFormValid() { + return this.formGroup.valid; + } + + finalize() { + this.formGroup.get('status').setValue(DescriptionTemplateTypeStatus.Finalized); + this.onSubmit(); + } + + onSubmit(): void { + if(this.isNew){ + this.descriptionTemplateTypeService.createType(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(true), + error => this.onCallbackError(error) + ); + } + else{ + this.descriptionTemplateTypeService.updateType(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(false), + error => this.onCallbackError(error) + ); + } + } + + onCallbackSuccess(creation: boolean): void { + if(creation){ + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION'), SnackBarNotificationLevel.Success); + } + else{ + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + } + this.router.navigate(['/description-types']); + } + + onCallbackError(errorResponse: any) { + this.setErrorModel(errorResponse.error); + this.formService.validateAllFormFields(this.formGroup); + this.uiNotificationService.snackBarNotification(errorResponse.error.message, SnackBarNotificationLevel.Error); + } + + public setErrorModel(validationErrorModel: ValidationErrorModel) { + Object.keys(validationErrorModel).forEach(item => { + (this.descriptionTypeModel.validationErrorModel)[item] = (validationErrorModel)[item]; + }); + } + + public cancel(): void { + this.router.navigate(['/description-types']); + } + +} + +export class DescriptionTypeEditorModel { + public id: string; + public name: string; + public status: DescriptionTemplateTypeStatus; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: DescriptionTemplateType): DescriptionTypeEditorModel { + this.id = item.id; + this.name = item.name; + this.status = item.status; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + id: [this.id], + name: [{ value: this.name, disabled: disabled }, context.getValidation('name').validators], + status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators] + }); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'name', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'name')] }); + baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); + return baseContext; + } +} diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html new file mode 100644 index 000000000..27311bafe --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.html @@ -0,0 +1,51 @@ +
+
+
+
+

{{'DESCRIPTION-TYPES-LISTING.TITLE' | translate}}

+
+
+
+ +
+
+ + +
+ + + + + + {{'DESCRIPTION-TYPES-LISTING.COLUMNS.NAME' | translate}} + {{row.name}} + + + + {{'DESCRIPTION-TYPES-LISTING.COLUMNS.STATUS' | + translate}} +
{{parseStatus(row.status) | translate}}
+
+ + + + + + + + + + + +
+ + +
+
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss new file mode 100644 index 000000000..245b6aa81 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.scss @@ -0,0 +1,71 @@ +.mat-table { + margin-top: 47px; + border-radius: 4px; +} +.description-types-listing { + margin-top: 1.3rem; + margin-left: 1rem; + margin-right: 2rem; + + .mat-header-row{ + background: #f3f5f8; + } + .mat-card { + margin: 16px 0; + padding: 0px; + } + + .mat-row { + cursor: pointer; + min-height: 4.5em; + } + + mat-row:hover { + background-color: #eef5f6; + } + .mat-fab-bottom-right { + float: right; + z-index: 5; + } +} +// PAGINATOR +:host ::ng-deep .mat-paginator-container { + flex-direction: row-reverse !important; + justify-content: space-between !important; + background-color: #f6f6f6; + align-items: center; +} +.create-btn { + border-radius: 30px; + background-color: var(--secondary-color); + padding-left: 2em; + padding-right: 2em; + // color: #000; + + .button-text{ + display: inline-block; + } +} + +.dlt-btn { + color: rgba(0, 0, 0, 0.54); +} + +.status-chip{ + + border-radius: 20px; + padding-left: 1em; + padding-right: 1em; + padding-top: 0.2em; + font-size: .8em; +} + +.status-chip-finalized{ + color: #568b5a; + background: #9dd1a1 0% 0% no-repeat padding-box; +} + +.status-chip-draft{ + color: #00c4ff; + background: #d3f5ff 0% 0% no-repeat padding-box; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts new file mode 100644 index 000000000..99c79b984 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/description-types/listing/description-types.component.ts @@ -0,0 +1,154 @@ +import { DataSource } from '@angular/cdk/table'; +import { HttpErrorResponse } from '@angular/common/http'; +import { Component, OnInit, ViewChild } from '@angular/core'; +import { MatDialog } from '@angular/material/dialog'; +import { MatPaginator } from '@angular/material/paginator'; +import { MatSort } from '@angular/material/sort'; +import { Router } from '@angular/router'; +import { DescriptionTemplateType } from '@app/core/model/description-template-type/description-template-type'; +import { DescriptionTemplateTypeService } from '@app/core/services/description-template-type/description-template-type.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { BaseComponent } from '@common/base/base.component'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; +import { merge as observableMerge, Observable, of } from 'rxjs'; +import { map, startWith, switchMap, takeUntil } from 'rxjs/operators'; + +@Component({ + selector: 'app-description-types', + templateUrl: './description-types.component.html', + styleUrls: ['./description-types.component.scss'] +}) +export class DescriptionTypesComponent extends BaseComponent implements OnInit { + + @ViewChild(MatPaginator, { static: true }) _paginator: MatPaginator; + @ViewChild(MatSort, { static: true }) sort: MatSort; + + dataSource: DescriptionTypesDataSource | null; + displayedColumns: String[] = ['label', 'status', 'delete']; + + statuses = [ + { value: '0', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.DRAFT' }, + { value: '1', viewValue: 'DESCRIPTION-TYPES-LISTING.STATUS.FINALIZED' } + ]; + + constructor( + private descriptionTemplateTypeService: DescriptionTemplateTypeService, + private dialog: MatDialog, + private language: TranslateService, + private uiNotificationService: UiNotificationService, + private router: Router + ) { + super(); + } + + ngOnInit(): void { + this.refresh(); + } + + refresh() { + this.dataSource = new DescriptionTypesDataSource(this.descriptionTemplateTypeService, this._paginator, this.sort/*, this.criteria*/); + } + + rowClick(rowId: String) { + this.router.navigate(['description-types/' + rowId]); + } + + parseStatus(value: number): string{ + const stringVal = value.toString() + try{ + return this.statuses.find(status => status.value === stringVal).viewValue; + }catch{ + return stringVal; + } + } + + deleteTemplate(id: string){ + if(id){ + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.descriptionTemplateTypeService.deleteType(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Success); + this.refresh(); + }, + error => { + this.onCallbackError(error); + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DATASET-PROFILE-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } + } + ); + } + }); + + } + } + + onCallbackError(errorResponse: HttpErrorResponse) { + this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning); + } + + getStatusClass(status: number): string { + + if(status == 1){ + return 'status-chip-finalized' + } + + return 'status-chip-draft'; + } + +} + +export class DescriptionTypesDataSource extends DataSource { + + totalCount = 0; + + constructor( + private _service: DescriptionTemplateTypeService, + private _paginator: MatPaginator, + private _sort: MatSort + ) { + super(); + + } + + connect(): Observable { + const displayDataChanges = [ + this._paginator.page + //this._sort.matSortChange + ]; + + return observableMerge(...displayDataChanges).pipe( + startWith(null), + switchMap(() => { + return this._service.getTypes(); + }), + map(result => { + return result; + }), + map(result => { + if (!result) { return []; } + if (this._paginator.pageIndex === 0) { this.totalCount = result.totalCount; } + return result.data; + })); + } + + disconnect() { + // No-op + } +} diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts index 5059a98b0..b4b9496af 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.module.ts @@ -10,6 +10,8 @@ import { DialodConfirmationUploadDmpProfiles } from './listing/criteria/dialog-c import { DmpProfileCriteriaComponent } from './listing/criteria/dmp-profile-criteria.component'; import { DmpProfileListingComponent } from './listing/dmp-profile-listing.component'; import { NgxDropzoneModule } from "ngx-dropzone"; +import { DragDropModule } from '@angular/cdk/drag-drop'; +import { AutoCompleteModule } from "@app/library/auto-complete/auto-complete.module"; @NgModule({ imports: [ @@ -18,7 +20,9 @@ import { NgxDropzoneModule } from "ngx-dropzone"; UrlListingModule, ConfirmationDialogModule, DmpProfileRoutingModule, - NgxDropzoneModule + NgxDropzoneModule, + DragDropModule, + AutoCompleteModule ], declarations: [ DmpProfileEditorComponent, diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts index 21a9ef4b8..f5c51ec6b 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/dmp-profile.routing.ts @@ -7,8 +7,8 @@ import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; const routes: Routes = [ { path: '', component: DmpProfileListingComponent, canActivate: [AdminAuthGuard] }, - { path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-NEW' } }, - { path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-PROFILE-EDIT' } }, + { path: 'new', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-NEW' } }, + { path: ':id', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-EDIT' } }, ]; @NgModule({ diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts new file mode 100644 index 000000000..c90354afd --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model.ts @@ -0,0 +1,256 @@ +import { FormBuilder, FormGroup, Validators } from "@angular/forms"; +import { DescriptionTemplatesInSection, DmpBlueprint, DmpBlueprintDefinition, FieldCategory, FieldInSection, SectionDmpBlueprint } from "@app/core/model/dmp/dmp-blueprint/dmp-blueprint"; +import { BackendErrorValidator } from "@common/forms/validation/custom-validator"; +import { ValidationErrorModel } from "@common/forms/validation/error-model/validation-error-model"; +import { ValidationContext } from "@common/forms/validation/validation-context"; + +export class DmpBlueprintEditor { + public id: string; + public label: string; + public definition: DmpBlueprintDefinitionEditor = new DmpBlueprintDefinitionEditor(); + public status: number; + public created: Date; + public modified: Date; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: DmpBlueprint): DmpBlueprintEditor { + this.id = item.id; + this.label = item.label; + this.definition = new DmpBlueprintDefinitionEditor().fromModel(item.definition); + this.status = item.status; + this.created = item.created; + this.modified = item.modified; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], + status: [{ value: this.status, disabled: disabled }, context.getValidation('status')], + created: [{ value: this.created, disabled: disabled }, context.getValidation('created')], + modified: [{ value: this.modified, disabled: disabled }, context.getValidation('modified')], + }); + formGroup.addControl('definition', this.definition.buildForm()); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); + baseContext.validation.push({ key: 'definition', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'definition')] }); + baseContext.validation.push({ key: 'created', validators: [] }); + baseContext.validation.push({ key: 'modified', validators: [] }); + return baseContext; + } + +} + +export class DmpBlueprintDefinitionEditor { + + public sections: SectionDmpBlueprintEditor[] = new Array(); + + fromModel(item: DmpBlueprintDefinition): DmpBlueprintDefinitionEditor { + if (item.sections) { item.sections.map(x => this.sections.push(new SectionDmpBlueprintEditor().fromModel(x))); } + return this; + } + + buildForm(): FormGroup { + const formBuilder = new FormBuilder(); + const formGroup = formBuilder.group({}); + const sectionsFormArray = new Array(); + this.sections.forEach(item => { + const form: FormGroup = item.buildForm(); + sectionsFormArray.push(form); + }); + formGroup.addControl('sections', formBuilder.array(sectionsFormArray)); + return formGroup; + } +} + +export class SectionDmpBlueprintEditor { + public id: string; + public label: string; + public description: string; + public ordinal: number; + public fields: FieldInSectionEditor[] = new Array(); + public hasTemplates: boolean; + public descriptionTemplates: DescriptionTemplatesInSectionEditor[] = new Array(); + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: SectionDmpBlueprint): SectionDmpBlueprintEditor { + this.id = item.id; + this.label = item.label; + this.description = item.description; + this.ordinal = item.ordinal; + if (item.fields) { item.fields.map(x => this.fields.push(new FieldInSectionEditor().fromModel(x))); } + this.hasTemplates = item.hasTemplates; + if (item.descriptionTemplates) { item.descriptionTemplates.map(x => this.descriptionTemplates.push(new DescriptionTemplatesInSectionEditor().fromModel(x))); } + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], + description: [{ value: this.description, disabled: disabled }, context.getValidation('description')], + ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal')], + hasTemplates: [{ value: this.hasTemplates, disabled: disabled }, context.getValidation('hasTemplates')] + }); + const formBuilder = new FormBuilder(); + const fieldsFormArray = new Array(); + this.fields.forEach(item => { + const form: FormGroup = item.buildForm(); + fieldsFormArray.push(form); + }); + formGroup.addControl('fields', formBuilder.array(fieldsFormArray)); + const descriptionTemplatesFormArray = new Array(); + this.descriptionTemplates.forEach(item => { + const form: FormGroup = item.buildForm(); + descriptionTemplatesFormArray.push(form); + }); + formGroup.addControl('descriptionTemplates', formBuilder.array(descriptionTemplatesFormArray)); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] }); + baseContext.validation.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'ordinal')] }); + baseContext.validation.push({ key: 'hasTemplates', validators: [BackendErrorValidator(this.validationErrorModel, 'hasTemplates')] }); + baseContext.validation.push({ key: 'descriptionTemplates', validators: [BackendErrorValidator(this.validationErrorModel, 'descriptionTemplates')] }); + return baseContext; + } +} + +export class FieldInSectionEditor { + public id: string; + public category: FieldCategory; + public type: number; + public label: string; + public placeholder: string; + public description: string; + public required: boolean; + public ordinal: number; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: FieldInSection): FieldInSectionEditor { + this.id = item.id; + this.category = item.category; + this.type = item.type; + this.label = item.label; + this.placeholder = item.placeholder; + this.description = item.description; + this.required = item.required; + this.ordinal = item.ordinal; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], + category: [{ value: this.category, disabled: disabled }, context.getValidation('category')], + type: [{ value: this.type, disabled: disabled }, context.getValidation('type')], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], + placeholder: [{ value: this.placeholder, disabled: disabled }, context.getValidation('placeholder')], + description: [{ value: this.description, disabled: disabled }, context.getValidation('description')], + required: [{ value: this.required, disabled: disabled }, context.getValidation('required')], + ordinal: [{ value: this.ordinal, disabled: disabled }, context.getValidation('ordinal')] + }); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseContext.validation.push({ key: 'category', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'category')] }); + baseContext.validation.push({ key: 'type', validators: [BackendErrorValidator(this.validationErrorModel, 'type')] }); + baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'placeholder', validators: [BackendErrorValidator(this.validationErrorModel, 'placeholder')] }); + baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] }); + baseContext.validation.push({ key: 'required', validators: [BackendErrorValidator(this.validationErrorModel, 'required')] }); + baseContext.validation.push({ key: 'ordinal', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'ordinal')] }); + return baseContext; + } +} + +export class DescriptionTemplatesInSectionEditor { + public id: string; + public descriptionTemplateId: string; + public label: string; + public minMultiplicity: number; + public maxMultiplicity: number; + public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); + + fromModel(item: DescriptionTemplatesInSection): DescriptionTemplatesInSectionEditor { + this.id = item.id; + this.descriptionTemplateId = item.descriptionTemplateId; + this.label = item.label; + this.minMultiplicity = item.minMultiplicity; + this.maxMultiplicity = item.maxMultiplicity; + return this; + } + + buildForm(context: ValidationContext = null, disabled: boolean = false): FormGroup { + if (context == null) { context = this.createValidationContext(); } + const formGroup = new FormBuilder().group({ + id: [{ value: this.id, disabled: disabled }, context.getValidation('id')], + descriptionTemplateId: [{ value: this.descriptionTemplateId, disabled: disabled }, context.getValidation('descriptionTemplateId')], + label: [{ value: this.label, disabled: disabled }, context.getValidation('label')], + minMultiplicity: [{ value: this.minMultiplicity, disabled: disabled }, context.getValidation('minMultiplicity')], + maxMultiplicity: [{ value: this.maxMultiplicity, disabled: disabled }, context.getValidation('maxMultiplicity')] + }); + return formGroup; + } + + createValidationContext(): ValidationContext { + const baseContext: ValidationContext = new ValidationContext(); + baseContext.validation.push({ key: 'id', validators: [BackendErrorValidator(this.validationErrorModel, 'id')] }); + baseContext.validation.push({ key: 'descriptionTemplateId', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'descriptionTemplateId')] }); + baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'minMultiplicity', validators: [BackendErrorValidator(this.validationErrorModel, 'minMultiplicity')] }); + baseContext.validation.push({ key: 'maxMultiplicity', validators: [BackendErrorValidator(this.validationErrorModel, 'maxMultiplicity')] }); + return baseContext; + } +} + +// export class ExtraFieldsInSectionEditor { +// public id: string; +// public label: string; +// public description: string; +// public placeholder: string; +// public type: ExtraFieldType; +// public required: boolean; +// public ordinal: number; + +// fromModel(item: ExtraFieldInSection): ExtraFieldsInSectionEditor { +// this.id = item.id; +// this.label = item.label; +// this.description = item.description; +// this.placeholder = item.placeholder; +// this.type = item.type; +// this.required = item.required; +// this.ordinal = item.ordinal; +// return this; +// } + +// buildForm(): FormGroup { +// const formGroup = new FormBuilder().group({ +// id: [this.id], +// label: [this.label], +// description: [this.description], +// placeholder: [this.placeholder], +// type: [this.type], +// required: [this.required], +// ordinal: [this.ordinal] +// }); +// return formGroup; +// } +// } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html index e0bc6fda9..5c9c18514 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.html @@ -18,7 +18,7 @@
+ [disabled]="!this.isFormValid()" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}
@@ -33,17 +33,256 @@ -->
- - - - {{formGroup.get('label').getError('backendError').message}} + + Name + {{'GENERAL.VALIDATION.REQUIRED' | translate}} -

{{'DMP-PROFILE-EDITOR.FIELDS.TITLE' | translate}}

+

Sections

+ + +
+
+ +
+
+ + + Section {{sectionIndex + 1}} + drag_indicator + +
+
+
+ + Section name + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Section description + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+
+ +
+
+ +
+
+
+ + System fields + + {{f.label}} + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + +
+
+
+ +
+ +
+
+ +
+
+
+
+
+ {{fieldIndex + 1}} +
+
+ drag_indicator +
+
+
+ +
+ + System Field + + +
+
+ + Label + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Placeholder + + +
+
+ + Description + + +
+
+ Required +
+
+ delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
+ + +
+ + Type + + + {{getExtraFieldTypeValue(extraFieldType)}} + + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Label + + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
+ + Placeholder + + +
+
+ + Description + + +
+
+ + Required + +
+
+ delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
+ +
+
+
+
+
+ +
+ +
+
+ +
+
+
+ + Description Templates + +
+
+
+ +
+
+
+ + Description Templates + + + + +
+
+
+ +
+ +
+
+
+ + Label + + +
+
+ + Min Multiplicity + + +
+
+ + Max Multiplicity + + +
+
+
+
+
+
+
+
+
+ +
+ delete + {{'DATASET-PROFILE-EDITOR.STEPS.TOOLKIT.DELETE' | translate}} +
+
+
+
+
+
+
+
+
+
+
+ +
+
+
+ +
@@ -139,7 +378,7 @@
-->
-
diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss index b05bd906f..6cc8ea3a0 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss @@ -60,4 +60,62 @@ color: #FFF; border: 0px; } +} + +.dlt-section-btn { + margin: 0; + position: absolute; + top: 50%; + -ms-transform: translateY(-50%); + transform: translateY(-50%); +} + +.section-input { + position: relative; +} + +.section-input .arrows { + position: absolute; + top: 0; + left: 50%; + transform: translateX(-50%); +} + +.action-list-item{ + display: flex; + align-items: center; + cursor: pointer; + + .action-list-icon{ + font-size: 1.2em; + // padding-right: 1em; + width: 14px; + margin-right: 0.5em; + margin-left: -.09em; + height: auto; + color: var(--primary-color); + } + + .action-list-text{ + font-size: 1em; + color: var(--primary-color); + } +} + +.field-delete{ + align-items: center; + display: flex; + cursor: pointer; + + .field-delete-icon{ + font-size: 1.2em; + width: 14px; + color: var(--primary-color); + } + + .field-delete-text{ + font-size: 1em; + margin-left: 0.5em; + color: var(--primary-color); + } } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts index 55a0cff24..5c2c65ad1 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.ts @@ -1,6 +1,6 @@ -import { AfterViewInit, Component } from '@angular/core'; -import { FormArray, FormGroup } from '@angular/forms'; +import { AfterViewInit, Component, ViewChild } from '@angular/core'; +import { FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type'; import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status'; @@ -25,6 +25,20 @@ import { HttpClient } from '@angular/common/http'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { MatDialog } from '@angular/material/dialog'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component'; +import { DatasetPreviewDialogComponent } from '@app/ui/dmp/dataset-preview/dataset-preview-dialog.component'; +import { CdkDragDrop, CdkDropList, CdkDrag, moveItemInArray } from '@angular/cdk/drag-drop'; +import { DmpBlueprint, DmpBlueprintDefinition, ExtraFieldType, FieldCategory, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DescriptionTemplatesInSectionEditor, DmpBlueprintEditor, FieldInSectionEditor, SectionDmpBlueprintEditor } from './dmp-blueprint-editor.model'; +import { Guid } from '@common/types/guid'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; @Component({ @@ -37,19 +51,42 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie isNew = true; viewOnly = false; dmpProfileModel: DmpProfileEditorModel; + dmpBlueprintModel: DmpBlueprintEditor; formGroup: FormGroup = null; host: string; dmpProfileId: string; breadCrumbs: Observable; + dmpBlueprintsFormGroup: FormGroup = null; + + profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + + fieldList = [ + {label: 'Title', type: SystemFieldType.TEXT}, + {label: 'Description', type: SystemFieldType.HTML_TEXT}, + {label: 'Researchers', type: SystemFieldType.RESEARCHERS}, + {label: 'Organizations', type: SystemFieldType.ORGANIZATIONS}, + {label: 'Language', type: SystemFieldType.LANGUAGE}, + {label: 'Contact', type: SystemFieldType.CONTACT}, + {label: 'Funder', type: SystemFieldType.FUNDER}, + {label: 'Grant', type: SystemFieldType.GRANT}, + {label: 'Project', type: SystemFieldType.PROJECT}, + {label: 'License', type: SystemFieldType.LICENSE}, + {label: 'Access Rights', type: SystemFieldType.ACCESS_RIGHTS} + ]; + selectedSystemFields: string[] = []; + systemFieldListPerSection: Array> = new Array(); + constructor( private dmpProfileService: DmpProfileService, + private _service: DmpService, private route: ActivatedRoute, private router: Router, private language: TranslateService, private enumUtils: EnumUtils, private uiNotificationService: UiNotificationService, private formService: FormService, + private fb: FormBuilder, private configurationService: ConfigurationService, private httpClient: HttpClient, private matomoService: MatomoService, @@ -61,6 +98,16 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie ngAfterViewInit() { this.matomoService.trackPageView('Admin: DMP Profile Edit'); + + 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' + }; + this.route.params .pipe(takeUntil(this._destroyed)) .subscribe((params: Params) => { @@ -68,12 +115,13 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie if (this.dmpProfileId != null) { this.isNew = false; - this.dmpProfileService.getSingle(this.dmpProfileId).pipe(map(data => data as DmpProfile)) + this.dmpProfileService.getSingleBlueprint(this.dmpProfileId).pipe(map(data => data as DmpBlueprint)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { - this.dmpProfileModel = new DmpProfileEditorModel().fromModel(data); - this.formGroup = this.dmpProfileModel.buildForm(); - if (this.dmpProfileModel.status == DmpProfileStatus.Finalized) { + this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data); + this.formGroup = this.dmpBlueprintModel.buildForm(); + this.buildSystemFields(); + if (this.dmpBlueprintModel.status == DmpProfileStatus.Finalized) { this.formGroup.disable(); this.viewOnly = true } @@ -85,9 +133,12 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie }); } else { this.dmpProfileModel = new DmpProfileEditorModel(); + this.dmpBlueprintModel = new DmpBlueprintEditor(); setTimeout(() => { - this.formGroup = this.dmpProfileModel.buildForm(); - this.addField(); + // this.formGroup = this.dmpProfileModel.buildForm(); + // this.addField(); + this.dmpBlueprintModel.status = DmpProfileStatus.Draft; + this.formGroup = this.dmpBlueprintModel.buildForm(); }); this.breadCrumbs = observableOf([{ parentComponentName: 'DmpProfileListingComponent', @@ -96,11 +147,252 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie }]); } }); + + } + + buildSystemFields(){ + const sections = this.sectionsArray().controls.length; + for(let i = 0; i < sections; i++){ + let systemFieldsInSection = new Array(); + this.fieldsArray(i).controls.forEach((field) => { + if((field.get('category').value == FieldCategory.SYSTEM || field.get('category').value == 'SYSTEM')){ + systemFieldsInSection.push(this.fieldList.find(f => f.type == field.get('type').value).label); + } + }) + this.systemFieldListPerSection.push(systemFieldsInSection); + } + } + + filterProfiles(value: string): Observable { + const request = new DataTableRequest(null, null, { fields: ['+label'] }); + const criteria = new DatasetProfileCriteria(); + criteria.like = value; + request.criteria = criteria; + return this._service.searchDMPProfiles(request); + } + + sectionsArray(): FormArray { + //return this.dmpBlueprintsFormGroup.get('sections') as FormArray; + return this.formGroup.get('definition').get('sections') as FormArray; + } + + addSection(): void { + const section: SectionDmpBlueprintEditor = new SectionDmpBlueprintEditor(); + section.id = Guid.create().toString(); + section.ordinal = this.sectionsArray().length + 1; + section.hasTemplates = false; + this.sectionsArray().push(section.buildForm()); + } + + removeSection(sectionIndex: number): void { + this.sectionsArray().removeAt(sectionIndex); + } + + fieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('fields') as FormArray; + } + + addField(sectionIndex: number, fieldCategory: FieldCategory, fieldType?: number): void { + const field: FieldInSectionEditor = new FieldInSectionEditor(); + field.id = Guid.create().toString(); + field.ordinal = this.fieldsArray(sectionIndex).length + 1; + field.category = fieldCategory; + if(!isNullOrUndefined(fieldType)){ + field.type = fieldType + } + field.required = (!isNullOrUndefined(fieldType) && (fieldType == 0 || fieldType == 1)) ? true : false; + this.fieldsArray(sectionIndex).push(field.buildForm()); + } + + removeField(sectionIndex: number, fieldIndex: number): void { + this.fieldsArray(sectionIndex).removeAt(fieldIndex); + } + + systemFieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('systemFields') as FormArray; + } + + initSystemField(systemField?: SystemFieldType): FormGroup { + return this.fb.group({ + id: this.fb.control(Guid.create().toString()), + type: this.fb.control(systemField), + label: this.fb.control(''), + placeholder: this.fb.control(''), + description: this.fb.control(''), + required: this.fb.control(true), + ordinal: this.fb.control('') + }); + } + + addSystemField(sectionIndex: number, systemField?: SystemFieldType): void { + this.addField(sectionIndex, FieldCategory.SYSTEM, systemField); + } + + transfromEnumToString(type: SystemFieldType): string{ + return this.fieldList.find(f => f.type == type).label; + } + + selectedFieldType(systemField: string, type: SystemFieldType, sectionIndex: number): void { + let index = this.selectedSystemFields.indexOf(systemField); + if (index == -1) { + this.selectedSystemFields.push(systemField); + this.addSystemField(sectionIndex, type); + } + else { + this.selectedSystemFields.splice(index, 1); + this.removeSystemField(sectionIndex, type); + } + } + + systemFieldDisabled(systemField: SystemFieldType, sectionIndex: number) { + let i = 0; + for (let s in this.sectionsArray().controls) { + if (i != sectionIndex) { + for (let f of this.fieldsArray(i).controls) { + if ((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField) { + return true; + } + } + } + i++; + } + return false; + } + + removeSystemFieldWithIndex(sectionIndex: number, fieldIndex: number): void { + this.fieldsArray(sectionIndex).removeAt(fieldIndex); + } + + removeSystemField(sectionIndex: number, systemField: SystemFieldType): void { + let i = 0; + for(let f of this.fieldsArray(sectionIndex).controls){ + if((f.get('category').value == FieldCategory.SYSTEM || f.get('category').value == 'SYSTEM') && f.get('type').value == systemField){ + this.fieldsArray(sectionIndex).removeAt(i); + return; + } + i++; + } + } + + descriptionTemplatesArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('descriptionTemplates') as FormArray; + } + + addDescriptionTemplate(descriptionTemplate, sectionIndex: number): void { + this.descriptionTemplatesArray(sectionIndex).push(this.fb.group({ + label: this.fb.control(descriptionTemplate.value) + })); + } + + removeDescriptionTemplate(sectionIndex: number, templateIndex: number): void { + this.descriptionTemplatesArray(sectionIndex).removeAt(templateIndex); + } + + extraFieldsArray(sectionIndex: number): FormArray { + return this.sectionsArray().at(sectionIndex).get('extraFields') as FormArray; + } + + addExtraField(sectionIndex: number): void { + this.addField(sectionIndex, FieldCategory.EXTRA); + } + + removeExtraField(sectionIndex: number, fieldIndex: number): void { + this.fieldsArray(sectionIndex).removeAt(fieldIndex); + } + + getExtraFieldTypes(): Number[] { + let keys: string[] = Object.keys(ExtraFieldType); + keys = keys.slice(0, keys.length / 2); + const values: Number[] = keys.map(Number); + return values; + } + + getExtraFieldTypeValue(extraFieldType: ExtraFieldType): string { + switch (extraFieldType) { + case ExtraFieldType.TEXT: return 'Text'; + case ExtraFieldType.RICH_TEXT: return 'Rich Text'; + case ExtraFieldType.DATE: return 'Date'; + case ExtraFieldType.NUMBER: return 'Number'; + } + } + + drop(event: CdkDragDrop, sectionIndex: number) { + moveItemInArray(this.fieldsArray(sectionIndex).controls, event.previousIndex, event.currentIndex); + moveItemInArray(this.fieldsArray(sectionIndex).value, event.previousIndex, event.currentIndex); + } + + dropSections(event: CdkDragDrop) { + moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex); + moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex); + } + + moveItemInFormArray(formArray: FormArray, fromIndex: number, toIndex: number): void { + const dir = toIndex > fromIndex ? 1 : -1; + + const item = formArray.at(fromIndex); + for (let i = fromIndex; i * dir < toIndex * dir; i = i + dir) { + const current = formArray.at(i + dir); + formArray.setControl(i, current); + } + formArray.setControl(toIndex, item); + } + + // clearForm(): void{ + // this.dmpBlueprintsFormGroup.reset(); + // } + + onRemoveTemplate(event, sectionIndex: number) { + const profiles = this.descriptionTemplatesArray(sectionIndex).controls; + const foundIndex = profiles.findIndex(profile => profile.get('descriptionTemplateId').value === event.id); + foundIndex !== -1 && this.descriptionTemplatesArray(sectionIndex).removeAt(foundIndex); + } + + // onPreviewTemplate(event, sectionIndex: number) { + // 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.sectionsArray().at(sectionIndex).get('descriptionTemplates').value;//this.formGroup.get('profiles').value; + // const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); + // profile.id = Guid.create().toString(); + // profile.descriptionTemplateId = event.id; + // profile.label = event.label; + // profiles.push(profile.buildForm()); + // this.sectionsArray().at(sectionIndex).get('descriptionTemplates').setValue(profiles);//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(item, sectionIndex){ + const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); + profile.id = Guid.create().toString(); + profile.descriptionTemplateId = item.id; + profile.label = item.label; + this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm()); } formSubmit(): void { this.formService.touchAllFormFields(this.formGroup); if (!this.isFormValid()) { return; } + if(!this.hasDescriptionTemplates()) { + this.showValidationErrorsDialog(undefined, ["At least one section should have description templates."]); + return; + } this.onSubmit(); } @@ -108,8 +400,27 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie return this.formGroup.valid; } + hasDescriptionTemplates(): boolean { + const dmpBlueprint: DmpBlueprint = this.formGroup.value; + return (dmpBlueprint.definition.sections.filter(s => s.hasTemplates == true).length > 0) ? true : false; + } + + private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { + + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + errorMessages:errmess, + projectOnly: projectOnly + }, + }); + + } + onSubmit(): void { - this.dmpProfileService.createDmp(this.formGroup.value) + this.dmpProfileService.createBlueprint(this.formGroup.value) .pipe(takeUntil(this._destroyed)) .subscribe( complete => this.onCallbackSuccess(), @@ -137,13 +448,13 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.router.navigate(['/dmp-profiles']); } - addField() { - (this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm()); - } + // addField() { + // (this.formGroup.get('definition').get('fields')).push(new DmpProfileFieldEditorModel().buildForm()); + // } - removeField(index: number) { - (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); - } + // removeField(index: number) { + // (this.formGroup.get('definition').get('fields')).controls.splice(index, 1); + // } getDMPProfileFieldDataTypeValues(): Number[] { let keys: string[] = Object.keys(DmpProfileFieldDataType); diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html index 733ea2248..582bb35ce 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.html @@ -13,7 +13,7 @@
diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts index 9ffd48074..b4189b030 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.ts @@ -71,7 +71,7 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit this.criteria.setRefreshCallback(() => this.refresh()); this.breadCrumbs = observableOf([{ parentComponentName: null, - label: this.languageService.instant('NAV-BAR.DMP-TEMPLATES'), + label: this.languageService.instant('NAV-BAR.DMP-BLUEPRINTS-CAPS'), url: '/dmp-profiles' }]); }); diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index 795ff063d..18fa44347 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -22,7 +22,7 @@
- +
@@ -49,13 +49,13 @@
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
@@ -69,7 +69,7 @@
0
{{'DASHBOARD.DMPS' | translate}}
0
- {{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} + {{'DASHBOARD.DESCRIPTIONS' | translate}}
0
{{'DASHBOARD.GRANTS' | translate}}
0
@@ -83,7 +83,7 @@ {{'DASHBOARD.DMPS' | translate}}
{{dashboardStatisticsData?.totalDataSetCount}}
- {{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} + {{'DASHBOARD.DESCRIPTIONS' | translate}}
{{dashboardStatisticsData?.totalGrantCount}}
{{'DASHBOARD.GRANTS' | translate}} @@ -147,7 +147,7 @@
{{'DASHBOARD.EMPTY-LIST' | translate}}
diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html index 565092451..d0b819ce2 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -66,7 +66,6 @@ delete{{ 'DMP-LISTING.ACTIONS.DELETE' | translate }} more_horiz - --> - -

{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DATASETS') | translate}}

+

{{(isPublic ? 'GENERAL.TITLES.EXPLORE' : 'GENERAL.TITLES.DESCRIPTIONS') | translate}}

diff --git a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html index b5bea4415..a6ab5e51f 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html +++ b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.html @@ -1,7 +1,7 @@
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.DESCRIPTION' | translate}}
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{dataset.modified | dateTimeCultureFormatter: "d MMMM y"}}
{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{dataset.dmpPublishedAt | dateTimeCultureFormatter: "d MMMM y"}}
@@ -27,7 +27,7 @@
+ +
+ +
+ +
+ + + + + +
+
+
DMP Blueprint
+
+
    + +
    +
    +
  1. {{section.label}}
  2. +
      +
    1. +
      +
      {{'DMP-EDITOR.STEPPER.DATASET' | translate}}: {{ dataset.get('label').value }}
      + close + check +
      +
    2. +
    + +
    +
    +
+
+
+ +
+
{{'DMP-EDITOR.STEPPER.NEXT' | translate}}
+ chevron_right +
+ + + + +
+
+ +
+
+
+
+
+
0.1 Title of DMP *
+ + Title + + + +
+
+
0.2 Description of DMP *
+ + +
+
+
0.3 Blueprint of DMP *
+ + Select blueprint + + + +
+
+
+ +
+
+
+
+

or continue with

+
+
+ +
+
+
+
+
+
+
+
+
+ +
+
+
+
+ + + diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss new file mode 100644 index 000000000..3d4fd45d8 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss @@ -0,0 +1,429 @@ +@media (max-width: 768px) { + .main-content { + padding: 30px 0px; + } + + button { + font-size: small; + } +} + +.form-container { + height: calc(100vh - 124px); + margin-top: 6rem; +} + +.fixed-editor-header { + // position: fixed; + // width: calc(100% - 310px); + z-index: 3; + background-color: whitesmoke; +} + +.editor-header { + height: 64px; + background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #00000029; + padding: 0.6rem; + margin: 30px 0px 0px 0px; + border-radius: 4px; + opacity: 1; + + .info { + flex: 2; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + } +} + +.datasetsInSection { + counter-reset: item +} + +.title { + text-align: left; + font-weight: 400; + font-size: 14px; + color: #ffffff; + opacity: 0.75; +} + +.subtitle { + text-align: left; + color: #ffffff; + font-weight: 700; + font-size: 16px; + opacity: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} + +.save-btn, .dmp-export-btn { + background: #ffffff 0% 0% no-repeat padding-box !important; + border-radius: 30px; + opacity: 1; + width: 110px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; + font-weight: 700; + color: var(--primary-color); +} + +.dmp-stepper { + position: fixed; + // height: 100%; + display: flex; + flex-direction: column; + height: calc(100vh - 190px); + overflow-y: auto; +} + +.stepper-title { + text-align: left; + font-weight: 300; + font-size: 20px; + letter-spacing: 0px; + color: #212121; + opacity: 0.6; + margin: 2.875rem 0rem 2.875rem 0rem; + padding-left: 1rem; +} + +.stepper-list li { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + padding: 0.3rem 0.1rem; + opacity: 0.6; + cursor: pointer; + max-width: 290px; +} + +.stepper-list li:hover { + background-color: #ececec; + border-radius: 6px; +} + +.stepper-list .active { + color: #212121; + font-weight: 700; + opacity: 1; +} + +.stepper-list .active-dataset { + color: #212121; + font-weight: 700; + opacity: 1; + .label { + width: 100%; + height: 27px; + line-height: 27px; + background-color: var(--secondary-color); + color: #5d5d5d; + border-radius: 4px; + font-weight: 400; + font-size: 14px; + justify-content: left; + display: flex; + align-items: center; + padding-left: 0.625rem; + padding-right: 0.625rem; + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + display: inline-block; + } +} + +mat-icon.size-16 { + width: 16px; + height: 16px; + line-height: 16px; + font-size: 16px; + margin-top: 0.4rem; +} + +.remove-dataset { + color: #f16868; +} + +.remove-dataset:hover { + color: #f16868; +} + +.stepper-actions { + display: flex; + padding-left: 1rem; + margin-top: auto; + margin-bottom: 0.5rem; + // margin-top: 5rem; + // flex-grow: 8; +} + +.stepper-btn { + border-radius: 30px; + opacity: 1; + width: 154px; + min-height: 40px; + display: flex; + justify-content: center; + align-items: center; + font-size: 14px; +} + +.previous { + color: #212121; + background: #f5f5f5 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + border: 2px solid #212121; + font-weight: 500; + cursor: pointer; +} + +.add-dataset-btn { + background: var(--secondary-color) 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 500; + white-space: normal; + word-wrap: break-word; + line-height: normal; + text-align: left; + font-size: 13.8px; +} + +.add-dataset-option { + list-style-type: none; +} + +.add-dataset-action { + display: flex; + align-items: center; + cursor: pointer; +} + +.next { + background: var(--primary-color) 0% 0% no-repeat padding-box; + color: white; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 400; + cursor: pointer; +} + +.dataset-next { + background: var(--secondary-color) 0% 0% no-repeat padding-box; + color: #212121; + box-shadow: 0px 3px 6px #1e202029; + font-weight: 700; + cursor: pointer; +} + +.previous-disabled, +.add-dataset-btn-disabled { + border: 1px solid #b5b5b5; + color: #b5b5b5 !important; + cursor: auto !important; +} + +.next-disabled { + background: #cbcbcb 0% 0% no-repeat padding-box; + box-shadow: 0px 3px 6px #1e202029; + color: white; + cursor: auto !important; +} + +.form { + // position: relative; + // left: 362px; + // width: calc(100% - 366px); + + position: relative; + left: 362px; + width: calc(100% - 366px); + overflow-y: auto; + height: calc(100vh - 218px); +} + +.formForStep0 { + position: relative; + width: 100%; + overflow-y: auto; + height: calc(100vh - 218px); +} + +.action-btn { + border-radius: 30px; + background-color: var(--secondary-color); + border: 1px solid transparent; + padding-left: 2em; + padding-right: 2em; + box-shadow: 0px 3px 6px #1E202029; + + transition-property: background-color, color; + transition-duration: 200ms; + transition-delay: 50ms; + transition-timing-function: ease-in-out; + &:disabled{ + background-color: #CBCBCB; + color: #FFF; + border: 0px; + } +} + +.blueprint-section { + text-align: left; + font-weight: 400; + letter-spacing: 0px; + color: #212121; + opacity: 1; + margin: 3rem 0rem 3rem 0rem; +} + +.changes { + font-weight: 400; + color: #ffffff; +} + +.discard-btn { + background: transparent; + border: 1px solid #ffffff; + color: white; + border-radius: 30px; + opacity: 1; + width: 110px; + height: 40px; + display: flex; + justify-content: center; + align-items: center; +} + +a { + color: #000000; +} + +a:hover { + color: var(--primary-color-3); +} + +.main-content { + height: 100vh !important; + margin-top: -80px; +} + +.dmp-blueprint-form { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0.15px; + color: #7d7d7d; + opacity: 1; + margin-bottom: 1rem; +} + +.section-info { + .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; + } + + .input-form { + text-align: left; + font-weight: 400; + font-size: 16px; + letter-spacing: 0.15px; + color: #7d7d7d; + opacity: 1; + margin-bottom: 1rem; + } + + .insert-manually { + text-decoration: underline; + color: var(--primary-color-3); + cursor: pointer; + font-size: 1rem; + font-weight: 400; + } + + .not-found { + // cursor: pointer; + font-size: 1rem; + font-weight: 400; + padding: 0rem 0.5rem 0rem 0rem; + } + + .not-found-template { + font-size: 0.875rem; + font-weight: 400; + padding: 0rem 0.5rem 0rem 0rem; + color: #212121; + } + + .disabled-toggle { + font-size: 1rem; + font-weight: 400; + padding: 0rem 0.5rem 0rem 0rem; + color: #e0e0e0 !important; + text-decoration: none; + } + + .input-btn { + border: none; + color: #aaaaaa; + background-color: #ffffff00; + cursor: pointer; + } + + .input-btn :hover { + color: var(--primary-color-3) !important; + } +} + +.heading2 { + 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; +} + +::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-outline { + background: #fafafa !important; +} + +::ng-deep .input-form .mat-form-field-appearance-outline .mat-form-field-infix { + font-size: 1rem; + padding: 0.6em 0 1em 0 !important; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts new file mode 100644 index 000000000..b77b73ca1 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -0,0 +1,1053 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormControl, FormGroup, Validators } from '@angular/forms'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { SingleAutoCompleteConfiguration } from '@app/library/auto-complete/single/single-auto-complete-configuration'; +import { DmpBlueprintEditor } from '@app/ui/admin/dmp-profile/editor/dmp-blueprint-editor.model'; +import { debounceTime, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators'; +import { DmpEditorModel } from '../editor/dmp-editor.model'; +import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model'; +import { FunderFormModel } from '../editor/grant-tab/funder-form-model'; +import { GrantTabModel } from '../editor/grant-tab/grant-tab-model'; +import { ProjectFormModel } from '../editor/grant-tab/project-form-model'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { LanguageInfoService } from '@app/core/services/culture/language-info-service'; +import { LanguageInfo } from '@app/core/model/language-info'; +import { UserModel } from '@app/core/model/user/user'; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { TranslateService } from '@ngx-translate/core'; +import { ExternalSourcesService } from '@app/core/services/external-sources/external-sources.service'; +import { Observable, interval } from 'rxjs'; +import { ExternalSourceItemModel } from '@app/core/model/external-sources/external-source-item'; +import { OrganisationService } from '@app/core/services/organisation/organisation.service'; +import { MatDialog } from '@angular/material/dialog'; +import { AddResearcherComponent } from '../editor/add-researcher/add-researcher.component'; +import { AddOrganizationComponent } from '../editor/add-organization/add-organization.component'; +import { RequestItem } from '@app/core/query/request-item'; +import { LicenseCriteria } from '@app/core/query/license/license-criteria'; +import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; +import { DatasetProfileCriteria } from '@app/core/query/dataset-profile/dataset-profile-criteria'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { AvailableProfilesComponent } from '../editor/available-profiles/available-profiles.component'; +import { DatasetPreviewDialogComponent } from '../dataset-preview/dataset-preview-dialog.component'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { FormValidationErrorsDialogComponent } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.component'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; +import { DmpModel } from '@app/core/model/dmp/dmp'; +import { ActivatedRoute, Params, Router } from '@angular/router'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { DmpToDatasetDialogComponent } from '../dmp-to-dataset/dmp-to-dataset-dialog.component'; +import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; +import { FormService } from '@common/forms/form-service'; +import { DmpDatasetProfile } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile'; +import { DmpDatasetProfileSectionsFormModel } from '@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile-sections-form.model'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { Principal } from '@app/core/model/auth/principal'; +import { Role } from '@app/core/common/enum/role'; +import { LockModel } from '@app/core/model/lock/lock.model'; +import { Guid } from '@common/types/guid'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; +import { GrantEditorModel } from '@app/ui/grant/editor/grant-editor.model'; +import { CheckDeactivateBaseComponent } from '@app/library/deactivate/deactivate.component'; + +interface Visible { + value: boolean; + name: string; +} + +@Component({ + selector: 'app-dmp-editor-blueprint', + templateUrl: './dmp-editor-blueprint.component.html', + styleUrls: ['./dmp-editor-blueprint.component.scss'] +}) +export class DmpEditorBlueprintComponent extends CheckDeactivateBaseComponent implements OnInit { + + canDeactivate(): boolean { + return !this.isDirty(); + } + + saving = false; + + isNew = true; + isUserOwner: boolean = true; + isNewVersion = false; + isFinalized = false; + isClone = false; + hasChanges = false; + isDiscarded = false; + + isCreateNew = false; + isCreateNewProject = false; + isCreateNewFunder = false; + + dmp: DmpEditorModel; + dmpSectionIndex: number = 0; + formGroup: FormGroup = null; + formGroupRawValue: any; + datasets = new FormArray([]); + + associatedUsers: Array; + people: Array; + + lock: LockModel; + lockStatus: Boolean = false; + + step: number = 0; + stepsBeforeDatasets: number = 4; + maxStep: number = 4; + + scrollTop: number; + hintErrors: boolean = false; + + selectedDmpBlueprintDefinition: DmpBlueprintDefinition = null; + + sectionTemplates: Array> = new Array>(); + + private associates: UserModel[] = []; + + visibles: Visible[] = [ + { value: true, name: 'DMP-EDITOR.VISIBILITY.PUBLIC' }, + { value: false, name: 'DMP-EDITOR.VISIBILITY.RESTRICTED' } + ] + + licenseAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.licenseSearch.bind(this), + initialItems: (excludedItems: any[]) => this.licenseSearch('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'] + }; + + profilesAutoCompleteConfiguration: MultipleAutoCompleteConfiguration; + + constructor( + private dmpProfileService: DmpProfileService, + private authService: AuthService, + private route: ActivatedRoute, + private router: Router, + private configurationService: ConfigurationService, + private languageInfoService: LanguageInfoService, + private language: TranslateService, + private externalSourcesService: ExternalSourcesService, + private organizationService: OrganisationService, + private dmpService: DmpService, + private uiNotificationService: UiNotificationService, + private formService: FormService, + private dialog: MatDialog, + private lockService: LockService, + private matomoService: MatomoService + ) { + super(); + } + + ngOnInit(): void { + this.matomoService.trackPageView('DMP Editor'); + this.route.params + .pipe(takeUntil(this._destroyed)) + .subscribe((params: Params) => { + const itemId = params['id']; + + if (itemId != null) { + this.isNew = false; + this.dmpService.getSingle(itemId).pipe(map(data => data as DmpModel)) + .pipe(takeUntil(this._destroyed)) + .subscribe(async data => { + this.lockService.checkLockStatus(data.id).pipe(takeUntil(this._destroyed)).subscribe(lockStatus => { + this.lockStatus = lockStatus; + + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.extraProperties = new ExtraPropertiesFormModel(); + this.dmp.fromModel(data); + this.formGroup = this.dmp.buildForm(); + + this.datasets = this.formGroup.get('datasets') as FormArray; + + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value.id) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.step = 1; + this.addProfiles(this.dmp.profiles); + }); + } + this.maxStep = this.formGroup.get('datasets') ? this.maxStep + this.formGroup.get('datasets').value.length - 1 : this.maxStep; + + this.setIsUserOwner(); + if (!this.isUserOwner) { + + if(this.isUserMember()){ + this.router.navigate(['plans', 'overview', itemId]); + return; + } + this.isFinalized = true; + this.formGroup.disable(); + } + + if (this.dmp.status === DmpStatus.Finalized || lockStatus) { + this.isFinalized = true; + this.formGroup.disable(); + } + + if (this.authService.current() != null) { + if (!lockStatus) { + this.lock = new LockModel(data.id, this.getUserFromDMP()); + + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => { + this.lock.id = Guid.parse(result); + interval(this.configurationService.lockInterval).pipe(takeUntil(this._destroyed)).subscribe(() => this.pumpLock()); + }); + } + } + + this.associatedUsers = data.associatedUsers; + this.people = data.users; + this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.formChanged(); + }); + if(this.lockStatus){ + this.dialog.open(PopupNotificationDialogComponent,{data:{ + title:this.language.instant('DMP-EDITOR.LOCKED.TITLE'), + message:this.language.instant('DMP-EDITOR.LOCKED.MESSAGE') + }, maxWidth:'30em'}); + } + }); + }); + } + else { + this.dmp = new DmpEditorModel(); + this.dmp.grant = new GrantTabModel(); + this.dmp.project = new ProjectFormModel(); + this.dmp.funder = new FunderFormModel(); + this.dmp.extraProperties = new ExtraPropertiesFormModel(); + this.dmp.extraProperties.visible = false; + this.dmp.extraProperties.contact = this.authService.current().id; + this.formGroup = this.dmp.buildForm(); + + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value.id) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.step = 1; + this.addProfiles(); + }); + } + this.registerFormEventsForDmpBlueprint(); + + if (!this.isUserOwner) { + this.formGroup.disable(); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('publicDate').value)) { + this.formGroup.get('extraProperties').get('publicDate').patchValue(new Date()); + } + + const principal = this.authService.current(); + let associate: UserModel = { + id: principal.id, + name: principal.name, + appRoles: principal.authorities, + email: principal.email + }; + this.associates.push(associate); + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('contact').value)) { + this.formGroup.get('extraProperties').get('contact').patchValue(associate.id); + } + if (isNullOrUndefined(this.formGroup.get('extraProperties').get('language').value)) { + this.formGroup.get('extraProperties').get('language').patchValue('en'); + } + + try{ + const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; + 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' + }; + } + + setIsUserOwner() { + if (this.dmp) { + const principal: Principal = this.authService.current(); + this.isUserOwner = !!this.dmp.users.find(x => (x.role === Role.Owner) && (x.id === principal.id) ); + } + } + + isUserMember(): boolean{ + try{ + const principal: Principal = this.authService.current(); + return !!this.dmp.users.find(x => (x.role === Role.Member) && (x.id === principal.id) ); + }catch{ + return false; + } + } + + getUserFromDMP(): any { + if (this.dmp) { + const principal: Principal = this.authService.current(); + return this.dmp.users.find(x => x.id === principal.id); + } + } + + private pumpLock() { + this.lock.touchedAt = new Date(); + this.lockService.createOrUpdate(this.lock).pipe(takeUntil(this._destroyed)).subscribe(async result => this.lock.id = Guid.parse(result)); + } + + public isDirty(): boolean { + return this.formGroup && this.formGroup.dirty && this.hasChanges; + } + + public discard() { + let messageText = ""; + let confirmButtonText = ""; + let cancelButtonText = ""; + if (this.isNew) { + messageText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-MESSAGE'); + confirmButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-CONFIRM'); + cancelButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-NEW-DENY'); + } else { + messageText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-MESSAGE'); + confirmButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-CONFIRM'); + cancelButtonText = this.language.instant('DATASET-EDITOR.ACTIONS.DISCARD.DISCARD-EDITED-DENY'); + } + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + restoreFocus: false, + data: { + message: messageText, + confirmButton: confirmButtonText, + cancelButton: cancelButtonText, + isDeleteConfirmation: true + }, + maxWidth: '40em' + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // this.backToDmp(this.formGroup.get('dmp').value.id) + setTimeout(x => { + this.discardChanges(); + }); + } + }); + } + + public discardChanges() { + this.isDiscarded = true; + this.hasChanges = false; + if (!this.isNew) { + let grantControl; + if (this.formGroup.get('grant').get('existGrant')) { + grantControl = new GrantTabModel(); + grantControl.fromModel(this.formGroup.get('grant').get('existGrant').value); + } else { + grantControl = new GrantEditorModel(); + grantControl.fromModel(this.formGroup.get('grant').value); + } + grantControl.buildForm() + + this.formGroup.patchValue(JSON.parse(JSON.stringify(this.formGroupRawValue))); + + if (this.formGroup.get('grant').get('existGrant')) { + this.formGroup.get('grant').get('existGrant').setValue(grantControl.existGrant); + } else { + this.formGroup.get('grant').setValue(grantControl); + } + } else { + this.formGroup.reset(); + this.formGroup.get("status").setValue(DmpStatus.Draft); + this.formGroup.get('extraProperties').get('visible').setValue(false); + this.formGroup.get('extraProperties').get('contact').setValue(this.authService.current().id); + this.formGroup.get('associatedUsers').setValue([]); + } + this.isDiscarded = false; + } + + save() { + this.formSubmit(false); + } + + formSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void { + this.saving = true; + this.formService.touchAllFormFields(this.formGroup); + + if(!this._isDMPDescriptionValid()){ + const errmess = this._buildDMPDescriptionErrorMessages(); + this.showValidationErrorsDialog(undefined, errmess); + this.hintErrors = true; + this.saving = false; + return; + } + this.onSubmit(addNew, showAddDatasetDialog); + } + + public formChanged() { + if (!this.isDiscarded) { + this.hasChanges = true; + } + } + + selectDefaultBlueprint() { + this.dmpProfileService.getSingleBlueprint('86635178-36a6-484f-9057-a934e4eeecd5') + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.nextStep(); + }); + } + + selectBlueprint() { + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.nextStep(); + } + + nextStep() { + this.step = this.step < this.maxStep ? this.step + 1 : this.step; + this.resetScroll(); + // if (this.step >= this.stepsBeforeDatasets) { + // this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value; + // } + } + + previousStep() { + this.step = this.step !== 0 ? this.step - 1 : this.step; + this.resetScroll(); + // if (this.step >= this.stepsBeforeDatasets) { + // this.datasetId = this.datasets.at(this.step - this.stepsBeforeDatasets).get('id').value; + // } + } + + changeStep(index: number, dataset?: FormControl) { + this.step = index; + this.resetScroll(); + // if (dataset) { this.datasetId = dataset.get('id').value }; + } + + private resetScroll() { + document.getElementById('editor-form').scrollTop = 0; + } + + hasProfile(): boolean { + return this.formGroup.get('profiles') && this.formGroup.get('profiles').value && this.formGroup.get('profiles').value.length > 0; + } + + addDataset(dmpSectionIndex: number) { + this.saving = true; + + if(!this._isDMPDescriptionValid()){ + const errmess = this._buildDMPDescriptionErrorMessages(); + this.showValidationErrorsDialog(undefined, errmess); + this.hintErrors = true; + this.saving = false; + return; + } + + + // const showDialog = this.hasProfile() && this.isNew; + this.dmpSectionIndex = dmpSectionIndex; + this.onSubmit(true, false); + // this.formSubmit(true, false); + + + + + // Add dataset to list + // if (!this.formGroup.get('datasets')) { + // this.formGroup.addControl('datasets', new FormBuilder().array(new Array())); + // } + // this.formGroup.get('datasets')['controls'].push(new DatasetWizardEditorModel().buildForm()); + // this.datasets = this.formGroup.get('datasets') as FormArray; + // this.step = this.stepsBeforeDatasets + this.formGroup.get('datasets')['controls'].length - 1; + // this.maxStep = this.maxStep + this.formGroup.get('datasets')['controls'].length - 1; + } + + onSubmit(addNew?: boolean, showAddDatasetDialog?: boolean): void { + this.scrollTop = document.getElementById('editor-form').scrollTop; + // return; + this.dmpService.createDmp(this.formGroup.getRawValue()) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.formGroup.get('id').setValue(complete.id); + this.formGroup.get('modified').setValue(complete.modified); + this.hasChanges = false; + if (showAddDatasetDialog) { + this.addDatasetOpenDialog(complete); + } + if (addNew) { + this.onCallbackSuccessAddNew(complete); + } + else { this.onCallbackSuccess(complete) } + }, + error => { + this.formGroup.get('status').setValue(DmpStatus.Draft); + this.onCallbackError(error); + } + ); + // this.dmpService.createDmpWithDatasets(this.formGroup.getRawValue()) + // .pipe(takeUntil(this._destroyed)) + // .subscribe( + // complete => { + // if (showAddDatasetDialog) { + // this.addDatasetOpenDialog(complete); + // } + // else if (this.step < this.stepsBeforeDatasets) { this.onCallbackSuccess(complete) } + // else { this.onCallbackSuccess(complete, this.datasetId) } + // }, + // error => { + // this.formGroup.get('status').setValue(DmpStatus.Draft); + // this.onCallbackError(error); + // } + // ) + } + + addDatasetOpenDialog(dmp: DmpModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '500px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ADD-DATASET'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.NO'), + isDeleteConfirmation: false + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + // this.router.navigate(['datasets/new/' + id]); + this.addDataset(this.dmpSectionIndex); + } else { + dmp.id != null ? this.router.navigate(['/plans', 'edit', dmp.id]) : this.router.navigate(['/plans']); + } + }); + } + + onCallbackSuccess(dmp?: DmpModel, datasetId?: string): void { + + // On save keep editor position + this.uiNotificationService.snackBarNotification(this.isNew ? this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-CREATION') : this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + if (dmp) { + if(this.isNew){ + this.router.navigate(['/plans', 'edit', dmp.id]); + } + let dmpEditorModel: DmpEditorModel; + dmpEditorModel = new DmpEditorModel(); + dmpEditorModel.grant = new GrantTabModel(); + dmpEditorModel.project = new ProjectFormModel(); + dmpEditorModel.funder = new FunderFormModel(); + dmpEditorModel.extraProperties = new ExtraPropertiesFormModel(); + dmpEditorModel.fromModel(dmp); + this.formGroupRawValue = JSON.parse(JSON.stringify(this.formGroup.getRawValue())); + this.associatedUsers = dmp.associatedUsers; + this.people = dmp.users; + + setTimeout(() => { this.formGroup = null; }); + setTimeout(() => { + this.formGroup = dmpEditorModel.buildForm(); + this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.formChanged(); + });}); + setTimeout(() => { document.getElementById('editor-form').scrollTop = this.scrollTop; }); + this.saving = false; + this.isNew = false; + } else { + this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); }); + } + + // Uncomment to not keep editor position on save + // if (dmp.id != null) { + // datasetId ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id], { queryParams: { dataset: datasetId } }); }) : this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans', 'edit', dmp.id]); }) + // } else { + // this.router.navigate(['/reload']).then(() => { this.router.navigate(['/plans']); }); + // } + } + + onCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(error.error.message, SnackBarNotificationLevel.Error); + this.setErrorModel(error.error); + this.saving = false; + //this.validateAllFormFields(this.formGroup); + } + + public setErrorModel(validationErrorModel: ValidationErrorModel) { + Object.keys(validationErrorModel).forEach(item => { + (this.dmp.validationErrorModel)[item] = (validationErrorModel)[item]; + }); + } + + onCallbackSuccessAddNew(dmp?: DmpModel) { + // this.editDataset(dmp.id, true, this.isNew && !this.formGroup.get('datasets').value.length); + this.editDataset(dmp.id, true, false); + this.saving = false; + } + + editDataset(id: string, isNew: boolean, showModal:boolean = false) { + + + if(showModal){ + const dialogRef = this.dialog.open(DmpToDatasetDialogComponent, { + width: '500px', + autoFocus: false, + restoreFocus: false, + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (isNew) { + this.router.navigate(['/datasets', 'new', id, this.dmpSectionIndex]); + } else { + this.router.navigate(['/datasets', 'edit', id]); + } + } + }); + }else{ + if (isNew) { + this.router.navigate(['/datasets', 'new', id, this.dmpSectionIndex]); + } else { + this.router.navigate(['/datasets', 'edit', id]); + } + + } + + + } + + //checks if the dpm is valid not taking into account the datasets validity + private _isDMPDescriptionValid():boolean{ + + const form: FormGroup = this.formGroup; + if(form.controls){ + return Object.keys(form.controls) + .map(controlName=>{//get validity of each control + if(controlName === 'datasets'){//we dont care if datasets are valid + return true; + } + return !form.get(controlName).invalid;//!! in case the control is disabled, we consider it valid + }) + .reduce((isFormValid,isControlValid)=>{//aggregate validities + return isControlValid && isFormValid; + }, true); + } + return true; + } + + private showValidationErrorsDialog(projectOnly?: boolean, errmess?: string[]) { + + if(errmess){ + + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + errorMessages:errmess, + projectOnly: projectOnly + }, + }); + }else{ + const dialogRef = this.dialog.open(FormValidationErrorsDialogComponent, { + disableClose: true, + autoFocus: false, + restoreFocus: false, + data: { + formGroup: this.formGroup, + projectOnly: projectOnly + }, + }); + } + + } + + private _buildDMPDescriptionErrorMessages(): string[]{//not including datasets + const errmess: string[] = []; + Object.keys(this.formGroup.controls).forEach(controlName=>{ + if(controlName != 'datasets' && this.formGroup.get(controlName).invalid){ + errmess.push(...this._buildErrorMessagesForAbstractControl(this.formGroup.get(controlName), controlName)); + } + }) + + return errmess; + } + + // takes as an input an abstract control and gets its error messages[] + private _buildErrorMessagesForAbstractControl(aControl: AbstractControl, controlName: string):string[]{ + const errmess:string[] = []; + + if(aControl.invalid){ + + if(aControl.errors){ + //check if has placeholder + if( (aControl).nativeElement !== undefined && (aControl).nativeElement !== null){ + const placeholder = this._getPlaceHolder(aControl); + if(placeholder){ + controlName = placeholder; + } + } + const errorMessage = this._getErrorMessage(aControl, controlName); + + errmess.push(...errorMessage); + } + /*in case the aControl is FormControl then the it should have provided its error messages above. + No need to check case of FormControl below*/ + + if(aControl instanceof FormGroup){ + + const fg = aControl as FormGroup; + //check children + Object.keys(fg.controls).forEach(controlName=>{ + errmess.push(...this._buildErrorMessagesForAbstractControl(fg.get(controlName), controlName)); + }); + }else if(aControl instanceof FormArray){ + + const fa = aControl as FormArray; + + fa.controls.forEach((control,index)=>{ + errmess.push(... this._buildErrorMessagesForAbstractControl(control, `${controlName} --> ${index+1}`)); + }); + + } + + } + + return errmess; + } + + private _getErrorMessage(formControl: AbstractControl, name: string): string[] { + const errors: string[] = []; + Object.keys(formControl.errors).forEach(key => { + if (key === 'required') { errors.push(this.language.instant(name + ": " + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED'))); } + // if (key === 'required') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + this.getPlaceHolder(formControl) + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.REQUIRED')); } + else if (key === 'email') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.EMAIL')); } + else if (key === 'min') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MIN-VALUE', { 'min': formControl.getError('min').min })); } + else if (key === 'max') { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.MAX-VALUE', { 'max': formControl.getError('max').max })); } + else { errors.push(this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.THIS-FIELD') + ' "' + name + '" ' + this.language.instant('GENERAL.FORM-VALIDATION-DISPLAY-DIALOG.HAS-ERROR') + ', ' + formControl.errors[key].message); } + }); + return errors; + } + + private _getPlaceHolder(formControl: any): string { + if (formControl.nativeElement.localName === 'input' || formControl.nativeElement.localName === 'textarea' + || formControl.nativeElement.localName === 'richTextarea') { + return formControl.nativeElement.getAttribute('placeholder'); + } else if (formControl.nativeElement.localName === 'mat-select') { + return formControl.nativeElement.getAttribute('placeholder'); + } else if (formControl.nativeElement.localName === 'app-single-auto-complete') { + return (Array.from(formControl.nativeElement.firstChild.children).filter((x: any) => x.localName === 'input')[0] as any).getAttribute('placeholder'); + } 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'); + } + } + + filterProfiles(value: string): Observable { + const request = new DataTableRequest(null, null, { fields: ['+label'] }); + const criteria = new DatasetProfileCriteria(); + criteria.like = value; + request.criteria = criteria; + return this.dmpService.searchDMPProfiles(request); + } + + registerFormEventsForDmpBlueprint(): void { + this.formGroup.get('profile').valueChanges + .pipe( + takeUntil(this._destroyed)) + .subscribe(Option => { + if (Option instanceof Object) { + this.selectedDmpBlueprintDefinition = Option.definition; + this.addProfiles(); + } + else { + this.selectedDmpBlueprintDefinition = null; + } + }) + } + + private addProfiles(profiles?: DmpDatasetProfile[]) { + for(let i = 0; i < this.selectedDmpBlueprintDefinition.sections.length; i++){ + this.sectionTemplates.push(new Array()); + } + const templates: Array = new Array(); + this.selectedDmpBlueprintDefinition.sections.forEach(section => { + if (profiles !== undefined) { + profiles.filter(profile => profile.data.dmpSectionIndex.includes(section.ordinal - 1)).forEach(profile => this.sectionTemplates[section.ordinal - 1].push({id: profile.descriptionTemplateId, label: profile.label, description: ""})); + } + else { + section.descriptionTemplates.forEach(template => { + this.sectionTemplates[section.ordinal - 1].push({id: template.descriptionTemplateId, label: template.label, description: ""}) + let found: DmpDatasetProfile = templates.find(dmpDatasetProfile => dmpDatasetProfile.id == template.descriptionTemplateId); + if (found === undefined) { + let data: DmpDatasetProfileSectionsFormModel= new DmpDatasetProfileSectionsFormModel(); + data.dmpSectionIndex.push(section.ordinal - 1); + let id = null; + if (profiles !== undefined) { + let existedProfile = profiles.find(profile => profile.descriptionTemplateId == template.descriptionTemplateId); + if (existedProfile !== undefined) { + id = existedProfile.id; + } + } + let profile: DmpDatasetProfile = { + id: id, + descriptionTemplateId: template.descriptionTemplateId, + label: template.label, + data: data + }; + templates.push(profile); + } + else { + found.data.dmpSectionIndex.push(section.ordinal - 1); + } + }); + } + }); + (profiles !== undefined) ? this.formGroup.get('profiles').setValue(profiles) : this.formGroup.get('profiles').setValue(templates); + + } + + dmpBlueprintAutoCompleteConfiguration: SingleAutoCompleteConfiguration = { + filterFn: this.dmpBlueprintSearch.bind(this), + initialItems: (extraData) => this.dmpBlueprintSearch(''), + displayFn: (item) => item['label'], + titleFn: (item) => item['label'] + }; + + dmpBlueprintSearch(query: string) { + let fields: Array = new Array(); + var request = new DataTableRequest(0, 10, { fields: fields }); + request.criteria = new DmpBlueprintCriteria(); + return this.dmpProfileService.getPagedBlueprint(request).pipe(map(x => x.data)); + } + + getLanguageInfos(): LanguageInfo[] { + return this.languageInfoService.getLanguageInfoValues(); + } + + getAssociates(): UserModel[] { + let associates: UserModel[]; + if (this.formGroup.get('associatedUsers').value && this.formGroup.get('associatedUsers').value.length > 0) { + associates = []; + } else { + associates = this.associates; + } + //associates = (this.formGroup.get('researchers').value as any[]); + associates = associates.concat(this.formGroup.get('associatedUsers').value); + return associates; + } + + organisationsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + filterFn: this.filterOrganisations.bind(this), + initialItems: (excludedItems: any[]) => this.filterOrganisations('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'], + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')) + }; + researchersAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + filterFn: this.filterResearchers.bind(this), + initialItems: (excludedItems: any[]) => this.filterResearchers('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x.id).indexOf(resultItem.id) === -1))), + displayFn: (item) => item['name'], + titleFn: (item) => item['name'], + subtitleFn: (item) => item['tag'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['tag'] : (item['key'] ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item['key'] : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE')) + }; + + // Researchers + filterResearchers(value: string): Observable { + return this.externalSourcesService.searchDMPResearchers({ criteria: { name: value, like: null } }); + } + + addResearcher(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddResearcherComponent, { + data: this.formGroup.get('researchers') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const fullName = result.firstName + " " + result.lastName; + const newItem = { + label: null, + name: fullName, + id: null, + status: 0, + key: "Internal", + reference: result.reference + }; + const researchersArray = this.formGroup.get('researchers').value || []; + researchersArray.push(newItem); + this.formGroup.get('researchers').setValue(researchersArray); + } + }); + } + + // Organizations + showOrganizationCreator(): boolean { + return this.configurationService.allowOrganizationCreator; + } + + filterOrganisations(value: string): Observable { + return this.organizationService.searchGeneralOrganisations({ criteria: { labelLike: value } }); + } + + cantAddOrganizations(): boolean { + if (!isNullOrUndefined(this.formGroup.get('organizations'))) { + return this.formGroup.get('organiztions').disabled; + } else { + return false; + } + } + + addOrganization(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AddOrganizationComponent, { + data: this.formGroup.get('organisations') + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + const fullName = result.name; + const newItem = { + label: null, + name: fullName, + id: null, + status: 0, + key: "Internal", + reference: result.reference + }; + const organizationsArray = this.formGroup.get('organisations').value || []; + organizationsArray.push(newItem); + this.formGroup.get('organisations').setValue(organizationsArray); + } + }); + } + + showToggleButton() { + return (!this.isFinalized && this.isUserOwner) || this.isClone; + } + + licenseSearch(query: string): Observable { + const request = new RequestItem(); + request.criteria = new LicenseCriteria(); + request.criteria.like = query; + request.criteria.type = ''; + return this.externalSourcesService.searchLicense(request); + } + + allAvailableProfiles(event: MouseEvent) { + event.stopPropagation(); + const dialogRef = this.dialog.open(AvailableProfilesComponent, { + data: { + profiles: this.formGroup.get('profiles') + } + }); + + return false; + } + + 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(event, sectionIndex: number){ + try{ + const profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; + let found = profiles.find((value) => value.id === event.id); + if(found !== undefined) { + if(found.data.dmpSectionIndex.indexOf(sectionIndex) === -1){ + found.data.dmpSectionIndex.push(sectionIndex); + } + else{ + this.sectionTemplates[sectionIndex].pop(); + } + } + else{ + let dmpDatasetProfileSection: DmpDatasetProfileSectionsFormModel = new DmpDatasetProfileSectionsFormModel(); + dmpDatasetProfileSection.dmpSectionIndex = [sectionIndex]; + profiles.push({id: null, descriptionTemplateId: event.id, label: event.label, data: dmpDatasetProfileSection}); + } + this.formGroup.get('profiles').setValue(profiles); + // const profileCounts: Map = new Map(); + // profiles.forEach((value) => profileCounts.set(value.id, (profileCounts.get(value.id) !== undefined ? profileCounts.get(value.id): 0 ) + 1)); + // const duplicateProfiles = profiles.filter((value) => { + // let isOk = profileCounts.get(value.id) > 1; + // if (isOk) { + // profileCounts.set(value.id, 0); + // } + // return isOk; + // }); + // duplicateProfiles.forEach((value) => profiles.splice(profiles.lastIndexOf(value), 1)); + // profiles.sort((a,b)=> a.label.localeCompare(b.label)); + }catch{ + console.info('Could not sort Dataset Templates') + } + } + +} diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index d6060d4b1..be42b903d 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -57,6 +57,7 @@ import { } from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module'; import {DatasetPreviewDialogComponent} from './dataset-preview/dataset-preview-dialog.component'; import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-editor.module"; +import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component'; @NgModule({ imports: [ @@ -110,7 +111,8 @@ import {RichTextEditorModule} from "@app/library/rich-text-editor/rich-text-edit FundingInfoComponent, DatasetInfoComponent, LicenseInfoComponent, - DatasetPreviewDialogComponent + DatasetPreviewDialogComponent, + DmpEditorBlueprintComponent ], entryComponents: [ DmpInvitationDialogComponent, diff --git a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts index 26295c3c0..3f8e41b86 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.routing.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.routing.ts @@ -8,6 +8,7 @@ import { DmpOverviewComponent } from './overview/dmp-overview.component'; import { DmpCloneComponent } from './clone/dmp-clone.component'; import { AuthGuard } from '@app/core/auth-guard.service'; import { CanDeactivateGuard } from '@app/library/deactivate/can-deactivate.guard'; +import { DmpEditorBlueprintComponent } from './dmp-editor-blueprint/dmp-editor-blueprint.component'; const routes: Routes = [ { @@ -34,7 +35,7 @@ const routes: Routes = [ }, { path: 'edit/:id', - component: DmpEditorComponent, + component: DmpEditorBlueprintComponent, data: { breadcrumb: true, title: 'GENERAL.TITLES.DMP-EDIT' @@ -76,7 +77,7 @@ const routes: Routes = [ // }, { path: 'new', - component: DmpEditorComponent, + component: DmpEditorBlueprintComponent, canActivate: [AuthGuard], data: { breadcrumbs: 'new', diff --git a/dmp-frontend/src/app/ui/dmp/editor/available-profiles/available-profiles.component.html b/dmp-frontend/src/app/ui/dmp/editor/available-profiles/available-profiles.component.html index 5949af616..412c02c9f 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/available-profiles/available-profiles.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/available-profiles/available-profiles.component.html @@ -1,4 +1,4 @@ -

{{ 'DMP-EDITOR.DATASET-TEMPLATE-LIST.TITLE' | translate }}

+

{{ 'DMP-EDITOR.DESCRIPTION-TEMPLATE-LIST.TITLE' | translate }}

@@ -12,7 +12,7 @@

- {{ 'DMP-EDITOR.DATASET-TEMPLATE-LIST.TEXT' | translate }} {{datasetsprofiles.selectedOptions.selected.length}} + {{ 'DMP-EDITOR.DESCRIPTION-TEMPLATE-LIST.TEXT' | translate }} {{datasetsprofiles.selectedOptions.selected.length}}

- +
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html index bd09b9352..491cb45f0 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.html @@ -6,7 +6,7 @@
-
4.1 {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}*
+
4.1 {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}}*
{{'DMP-EDITOR.DATASET-INFO.HINT' | translate}}
info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html index 37a0be5d1..0210e3819 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.html @@ -76,8 +76,8 @@
  • {{'DMP-EDITOR.STEPPER.LICENSE-INFO' | translate}}
  • -
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}} (1)
  • -
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}} (done)
  • +
  • {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}} (1)
  • +
  • {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}} (done)
  • @@ -91,7 +91,7 @@ @@ -108,7 +108,7 @@
  • diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts index 43bcbea87..008f10bd2 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.model.ts @@ -2,8 +2,7 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; import { DmpProfileFieldDataType } from '@app/core/common/enum/dmp-profile-field-type'; import { DmpProfileType } from '@app/core/common/enum/dmp-profile-type'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; -import { DatasetModel } from '@app/core/model/dataset/dataset'; -import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile'; +import { DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile'; import { DmpProfileField } from '@app/core/model/dmp-profile/dmp-profile-field'; import { DmpModel } from '@app/core/model/dmp/dmp'; import { DmpDynamicField } from '@app/core/model/dmp/dmp-dynamic-field'; @@ -23,8 +22,7 @@ import { ValidationContext } from '@common/forms/validation/validation-context'; import { ExtraPropertiesFormModel } from './general-tab/extra-properties-form.model'; import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model'; -import { DatasetsAutoCompleteFieldDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/datasets-autocomplete-field-data-editor-mode'; -import { DatasetWizardModel } from '@app/core/model/dataset/dataset-wizard'; +import { DmpDatasetProfile } from "@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile"; export class DmpEditorModel { public id: string; @@ -41,7 +39,7 @@ export class DmpEditorModel { public funder: FunderFormModel; public organisations: OrganizationModel[] = []; public researchers: ResearcherModel[] = []; - public profiles: DmpProfile[] = []; + public profiles: DmpDatasetProfile[] = []; public datasets: DatasetWizardEditorModel[] = []; // public datasets: DatasetModel[] = []; public datasetsToBeFinalized: string[] = []; diff --git a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html index 7dfd317d6..2582589cc 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.html @@ -1,19 +1,19 @@
    -
    + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.FUNDER-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -38,31 +38,32 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}}
    -
    - -
    -
    -
    - {{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-FUNDER' | translate}} -
    -
    - {{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}} - {{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}} + +
    +
    +
    + {{'QUICKWIZARD.CREATE-ADD.CREATE.QUICKWIZARD_CREATE.ACTIONS.EXIST-FUNDER' | translate}} +
    +
    + {{'DMP-EDITOR.FUNDING-INFO.FIND' | translate}} + {{'DMP-EDITOR.ACTIONS.INSERT-MANUALLY' | translate}} +
    -
    -
    + + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.GRANTS-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -107,18 +108,18 @@
    -
    -
    + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.PROJECT-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    @@ -162,9 +163,9 @@
    -
    -
    - + + diff --git a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts index 72ba47c11..e06095ce6 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/funding-info/funding-info.component.ts @@ -28,6 +28,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { @Input() isClone: boolean = false; @Input() isNewVersion: boolean; + @Input() type: number; + @Input() formGroup: FormGroup; @Input() grantformGroup: FormGroup; @Input() projectFormGroup: FormGroup; @@ -71,7 +73,7 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { return ''; } - ngOnInit() { + ngOnInit() { const grantRequestItem: RequestItem = new RequestItem(); grantRequestItem.criteria = new GrantCriteria(); diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html index e83c9cb4d..495dc022a 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.html @@ -17,7 +17,7 @@ . {{ 'DMP-LISTING.GRANT' | translate }}: {{dmp.grant}} -
    {{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ dmp.datasets.length }}) +
    {{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ dmp.datasets.length }})
    @@ -29,7 +29,7 @@
    open_in_new{{'DMP-LISTING.ACTIONS.EXPORT' | translate}} - add{{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}} + add{{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}} group_add{{'DMP-LISTING.ACTIONS.INVITE-SHORT' | translate}} filter_none{{'DMP-LISTING.ACTIONS.CLONE' | translate}} library_books{{'DMP-LISTING.ACTIONS.VIEW-VERSION' | translate}} diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 0d69b4b3a..f64512914 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -87,7 +87,7 @@
    horizontal_rule
    -
    {{'DMP-OVERVIEW.DATASETS-USED' | translate}}
    +
    {{'DMP-OVERVIEW.DESCRIPTIONS-USED' | translate}}
    diff --git a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts index 5005d9a0a..64fd7278f 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts +++ b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard-editor.model.ts @@ -17,6 +17,7 @@ import { ValidationContext } from '@common/forms/validation/validation-context'; import { DmpStatus } from '@app/core/common/enum/dmp-status'; import { ExtraPropertiesFormModel } from '../editor/general-tab/extra-properties-form.model'; import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; +import { DmpDatasetProfile } from "@app/core/model/dmp/dmp-dataset-profile/dmp-dataset-profile"; export class DmpWizardEditorModel { public id: string; @@ -33,7 +34,7 @@ export class DmpWizardEditorModel { public project: ProjectFormModel; public organisations: OrganizationModel[] = []; public researchers: ResearcherModel[] = []; - public profiles: DmpProfile[] = []; + public profiles: DmpDatasetProfile[] = []; public associatedUsers: UserModel[] = []; public users: UserInfoListingModel[] = []; public definition: DmpProfileDefinition; diff --git a/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html b/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html index b9e9cafb4..989e43042 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html +++ b/dmp-frontend/src/app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component.html @@ -1,6 +1,6 @@
    -
    {{'DATASET-LISTING.SELECT-DATASETS-TO-CLONE' | translate}} {{titlePrefix}}
    +
    {{'DATASET-LISTING.SELECT-DESCRIPTIONS-TO-CLONE' | translate}} {{titlePrefix}}
    @@ -10,6 +10,6 @@
    -
    {{'DATASET-LISTING.SELECT-DATASETS-NONE' | translate}}
    +
    {{'DATASET-LISTING.SELECT-DESCRIPTIONS-NONE' | translate}}
    diff --git a/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html b/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html index bd512164c..937ccc065 100644 --- a/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html +++ b/dmp-frontend/src/app/ui/misc/navigation/navigation.component.html @@ -11,7 +11,7 @@ {{'NAV-BAR.DMPS' | translate}} {{'NAV-BAR.DATASETS' | translate}} {{'NAV-BAR.USERS' | translate}} - {{'NAV-BAR.DMP-PROFILES' | + {{'NAV-BAR.DMP-BLUEPRINTS' | translate}} {{'NAV-BAR.DATASETS-ADMIN' | translate}} diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.html b/dmp-frontend/src/app/ui/navbar/navbar.component.html index 0c9b6c9b9..5d8f62fd5 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.html +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.html @@ -101,7 +101,7 @@ diff --git a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts index 496ba5cb3..088f44d84 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/dmp-editor/dmp-editor-wizard-model.ts @@ -24,7 +24,7 @@ export class DmpEditorWizardModel { this.label = item.label; this.status = item.status; this.description = item.description; - this.datasetProfile = item.profiles[0]; + this.datasetProfile = {id: item.profiles[0].descriptionTemplateId, label: item.profiles[0].label, description: ""}; this.language = item.language; return this; } diff --git a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts index c417425b2..48bccf255 100644 --- a/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts +++ b/dmp-frontend/src/app/ui/sidebar/sidebar.component.ts @@ -31,7 +31,7 @@ export const GENERAL_ROUTES: RouteInfo[] = [ ]; export const DMP_ROUTES: RouteInfo[] = [ { path: '/plans', title: 'SIDE-BAR.MY-DMPS', icon: 'library_books' }, - { path: '/datasets', title: 'SIDE-BAR.MY-DATASETS', icon: 'dns' }, + { path: '/datasets', title: 'SIDE-BAR.MY-DESCRIPTIONS', icon: 'dns' }, // { path: '/quick-wizard', title: 'SIDE-BAR.QUICK-WIZARD', icon: 'play_circle_outline' }, // { path: '/plans/new', title: 'SIDE-BAR.ADD-EXPERT', icon: 'playlist_add' } ]; @@ -51,15 +51,16 @@ export const PUBLIC_ROUTES: RouteInfo[] = [ // ]; export const ADMIN_ROUTES: RouteInfo[] = [ - { path: '/dmp-profiles', title: 'SIDE-BAR.DMP-TEMPLATES', icon: 'library_books' }, - { path: '/dataset-profiles', title: 'SIDE-BAR.DATASET-TEMPLATES', icon: 'library_books' }, + { path: '/dmp-profiles', title: 'SIDE-BAR.DMP-BLUEPRINTS', icon: 'library_books' }, + { path: '/dataset-profiles', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' }, + { path: '/description-types', title: 'SIDE-BAR.DESCRIPTION-TEMPLATE-TYPES', icon: 'library_books' }, { path: '/users', title: 'SIDE-BAR.USERS', icon: 'people' }, { path: '/language-editor', title: 'SIDE-BAR.LANGUAGE-EDITOR', icon: 'language' }, { path: '/user-guide-editor', title: 'SIDE-BAR.GUIDE-EDITOR', icon: 'import_contacts' } ]; export const DATASET_TEMPLATE_ROUTES: RouteInfo[] = [ - { path: '/dataset-profiles', title: 'SIDE-BAR.DATASET-TEMPLATES', icon: 'library_books' } + { path: '/dataset-profiles', title: 'SIDE-BAR.DESCRIPTION-TEMPLATES', icon: 'library_books' } ]; export const INFO_ROUTES: RouteInfo[] = [ diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 06d9ed19b..19bf1293f 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index b23e12d74..ed899b777 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -28,6 +28,8 @@ "UNSUCCESSFUL-LOGIN": "Unsuccessful Login", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Successful Delete", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "This template can not deleted, because Datasets are associated with it", + "SUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE": "Successful Delete", + "UNSUCCESSFUL-DESCRIPTION-TEMPLATE-TYPE-DELETE": "This type can not deleted, because Descriptions are associated with it", "SUCCESSFUL-DELETE": "Successful Delete", "UNSUCCESSFUL-DELETE": "Unsuccessful Delete", "UNSUCCESSFUL-EMAIL-SEND": "Failed sending email", @@ -133,12 +135,13 @@ "QUICK-WIZARD": "New DMP (Wizard)", "PLANS-NEW": "New DMP (Expert)", "DMP-NEW": "New DMP", - "DATASETS": "My Datasets", - "EXPLORE": "Published Datasets", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Add Dataset (Wizard)", "GRANTS": "My Grants", - "DMP-PROFILES": "DMP Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Dataset Templates", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Users", "PROFILE": "My Profile", "LOGIN": "Login", @@ -151,10 +154,12 @@ "DATASET-NEW": "New Dataset", "GRANT-NEW": "New Grant", "GRANT-EDIT": "View/Edit Grant", - "DMP-PROFILE-NEW": "New DMP Template", - "DMP-PROFILE-EDIT": "Edit DMP Template", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "New Dataset Template", "DATASET-PROFILES-EDIT": "Edit Dataset Template", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Published DMP Overview", "DATASET-PUBLIC-EDIT": "View Published Dataset", "DMP-PUBLIC-EDIT": "View Published DMP", @@ -219,11 +224,11 @@ "DMPS": "DMPs", "MY-DMPS": "MY DMPs", "DATASETS": "Datasets", - "DATASET": "Dataset", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Explore {{ APP_NAME_CAPS }}", "USERS": "Users", "DATASETS-ADMIN": "Dataset Templates", - "DMP-PROFILES": "DMP Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "About", "MY-DATASET-DESCRIPTIONS": "MY DATASETS", "DATASET-DESCRIPTION-WIZARD": "Dataset wizard", @@ -233,7 +238,7 @@ "DMP-WIZARD": "DMP Wizard", "DATASET-TEMPLATES": "DATASET TEMPLATES", "TEMPLATE": "TEMPLATE", - "DMP-TEMPLATES": "DMP TEMPLATES", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "USERS", "START-NEW-DMP": "Start new DMP", "START-NEW-DMP-TXT": "Start fresh or continue work in {{ APP_NAME }}! Create a new DMP or upload an existing DMP to {{ APP_NAME }}", @@ -259,18 +264,19 @@ "QUICK-WIZARD-DATASET": "Add Dataset (Wizard)", "ADD-EXPERT": "New DMP (Expert)", "MY-DATASET-DESC": "My Dataset Desc.", - "MY-DATASETS": "My Datasets", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "My Grants", "HISTORY": "HISTORY", "HISTORY-VISITED": "LAST VISITED", "HISTORY-EDITED": "LAST EDITED", "PUBLIC": "PUBLISHED", "PUBLIC-DMPS": "Public DMPs", - "PUBLIC-DESC": "Public Dataset Desc.", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "ACCOUNT", "ADMIN": "ADMIN", - "DATASET-TEMPLATES": "Dataset Templates", - "DMP-TEMPLATES": "DMP Templates", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Users", "LANGUAGE-EDITOR": "Language Editor", "GUIDE-EDITOR": "User Guide Editor", @@ -281,23 +287,25 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "New API Client", - "NEW-PROFILE": "New Dataset Template", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "New Version Of ", "NEW-PROFILE-CLONE": "New Clone Of " }, "FIELDS": { - "DATASET-TITLE": "Dataset Template Name", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Description", "ROLES": "Roles" }, "STEPS": { "GENERAL-INFO": { "TITLE": "General Info", - "DATASET-TEMPLATE-NAME": "Dataset template name", - "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Dataset template.", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Description", "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Dataset is about, it's scope and objectives.", - "DATASET-TEMPLATE-LANGUAGE": "Dataset template language", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Select a language", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", @@ -314,7 +322,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Chapter Name", - "PAGE-NAME-HINT": "Set a name for the dataset chapter.", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Description", "PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the chapter is about.", "ACTIONS": { @@ -615,7 +623,7 @@ "FINALIZED": "Finalized", "PUBLISHED": "Published", "VERSION": "Version", - "CONTAINED-DATASETS": "Contained Datasets", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Information in a DMP show how datasets have been collected and/or generated, how they have been processed and analysed, i.e. using which tools, standards, methodologies etc, but also where and how datasets are backed up, published and preserved, including any costs associated with personnel dedicated for data curation/ stewardship activities or costs for acquiring or building data management services.", "TEXT-INFO-QUESTION": "Not sure how a DMP looks in practice? Browse Public DMPs and", "LINK-ZENODO": "LIBER community in Zenodo", @@ -642,8 +650,7 @@ "INVITE-AUTHORS": "Invite authors", "INVITE-SHORT": "Invite", "ADD-DATASET": "Add Dataset To DMP", - "ADD-DATASET-DESCRIPTION": "Add dataset", - "ADD-DATASET-SHORT": "Add Dataset", + "ADD-DESCRIPTION-SHORT": "Add Description", "DATASETS": "List All DMP Datasets", "NEW-VERSION": "New Version", "START-NEW-VERSION": "Start New Version", @@ -745,7 +752,7 @@ "DOWNLOAD-PDF": "Download PDF", "DOWNLOAD-XML": "Download XML", "DOWNLOAD-DOCX": "Download DOCX", - "COPY-DATASET": "Copy Dataset", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Update Template", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +801,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "DΜP Authors", "RESEARCHERS": "Researchers", - "DATASETS-USED": "Datasets used", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Collaborators", "PUBLIC": "Public", "PRIVATE": "Private", @@ -829,7 +836,7 @@ } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Dataset authors", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "The requested dataset is deleted", "FORBIDEN-DATASET": "You are not allowed to access this dataset" @@ -846,9 +853,9 @@ }, "DATASET-LISTING": { "TITLE": "Datasets", - "DATASET-DESCRIPTION": "Dataset", - "SELECT-DATASETS-TO-CLONE": "Select which datasets to include in the new DMP. Selected datasets will be editable.", - "SELECT-DATASETS-NONE": "Not available Datasets for this DMP.", + "DESCRIPTION": "Description", + "SELECT-DESCRIPTIONS-TO-CLONE": "Select which descriptions to include in the new DMP. Selected descriptions will be editable.", + "SELECT-DESCRIPTIONS-NONE": "Not available Descriptions for this DMP.", "TEXT-INFO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In {{ APP_NAME }}, a DMP can contain as many dataset descriptions as the datasets it documents. Browse ", "TEXT-INFO-REST": " for a look at datasets described in {{ APP_NAME }} DMPs", "LINK-PUBLIC-DATASETS": "Public Datasets", @@ -913,7 +920,7 @@ "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Dataset Templates", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Name", "REFERNCE": "Reference", @@ -941,9 +948,24 @@ "CLONE": "Clone", "NEW-VERSION": "New Version", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "All Dataset Template Versions", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Delete", - "CREATE-DATASET-TEMPLATE": "Create Dataset Template" + "CREATE-DESCRIPTION-TEMPLATE": "Create Description Template" + } + }, + "DESCRIPTION-TYPES-LISTING": { + "TITLE": "Description Types", + "CREATE-TYPE": "Create Description Type", + "COLUMNS": { + "NAME": "Name", + "STATUS": "Status" + }, + "STATUS":{ + "DRAFT": "Draft", + "FINALIZED": "Finalized" + }, + "ACTIONS": { + "DELETE": "Delete" } }, "DATASET-UPLOAD": { @@ -962,9 +984,20 @@ "UNSUCCESSFUL": "Something went wrong" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "New DMP Template", + "NEW": "New DMP Blueprint", "EDIT": "Edit" }, "FIELDS": { @@ -1024,7 +1057,7 @@ "EDIT": "Edit", "EDIT-DMP": "Editing DMP", "ADD-DATASET": "Adding dataset", - "EDIT-DATASET": "Editing Dataset", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Clone", "NEW-VERSION": "New Version", "CREATE-DATASET": "Creating Dataset", @@ -1044,7 +1077,7 @@ "TEMPLATES": "Templates", "TEMPLATE": "DMP Template", "DATASET-TEMPLATES": "Related Dataset Templates", - "SELECT-TEMPLATE": "Select a template to describe your dataset", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "DMP Template", "PROJECT": "Project", "GRANT": "Grant", @@ -1065,7 +1098,7 @@ "PUBLICATION": "Publication Date", "CONTACT": "Contact", "COST": "Costs", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Go To DMP Grant", @@ -1094,9 +1127,9 @@ "SUCCESSFUL-DOI": "Successful DOI creation", "UNSUCCESSFUL-FINALIZE": "Unsuccessful DMP finalization" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Available Dataset Templates", - "TEXT": "Dataset Profiles selected: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1141,7 @@ "MAIN-INFO": "Main info", "FUNDING-INFO": "Funding", "DATASET-SELECTION": "Dataset selection", - "DATASET-INFO": "Dataset info", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "License", "DATASET": "Dataset", "PREVIOUS": "Previous", @@ -1138,7 +1171,7 @@ "INTRO": "A DMP in {{ APP_NAME }} consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research datasets that highlight the steps followed and the means used across data management activities.", "SECOND-INTRO": "Datasets are documented following pre-defined templates which set the content of dataset descriptions. In {{ APP_NAME }}, a DMP can contain as many dataset descriptions as the datasets it documents.", "FIND": "Couldn't find a suitable one?", - "HINT": "Select a template to describe your datasets. You may select more than one template." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Each DMP can contain specific license informatation over how much open and available it is, that way you can determine who can see your dataset and for how long that data will be private", @@ -1160,8 +1193,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "DMP Templates", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Name", "STATUS": "Status", @@ -1218,8 +1251,8 @@ "NONE": "-", "TAGS": "Tags", "SELECT-TAGS": "Select Tags", - "LIKE": "Search Datasets", - "DRAFT-LIKE": "Search Draft Datasets", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Select Grants", "ROLE": "Role", "ORGANIZATION": "Organization", @@ -1255,12 +1288,12 @@ "TITLE": { "NEW": "New Data Management Plan", "EDIT": "Edit", - "INTRO": "You are using the Dataset editor. Answer here questions that describe your data management activities.", - "INTRO-TIP": "Tip: Add new datasets to describe different types of data or disciplinary data to avoid mixing information." + "INTRO": "You are using the Description editor. Answer here questions that describe your data management activities.", + "INTRO-TIP": "Tip: Add new descriptions to describe different types of data or disciplinary data to avoid mixing information." }, "FIELDS": { "NAME": "Name of the Dataset", - "TITLE": "Title of Dataset", + "TITLE": "Title of Description", "DESCRIPTION": "Description", "PROFILE": "Template", "URI": "Uri", @@ -1298,7 +1331,7 @@ "EXTERNAL-LINK": "Provide an external URL link" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "A brief description of what the ", "TITLE-REST": " is about it’s scope and objectives." }, @@ -1370,7 +1403,7 @@ "ADMIN": "Admin", "USER": "User", "MANAGER": "Manager", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1681,7 @@ "DATA-MANAGEMENT-PLANS": "DATA MANAGEMENT PLANS", "PERSONAL-USAGE": "Personal Usage", "PUBLIC-USAGE": "Public Usage", - "DATASET-DESCRIPTIONS": "Datasets", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Datasets", "PUBLIC-DMPS": "Public DMPs", "PUBLIC-DATASETS": "Public Datasets", @@ -1661,8 +1694,7 @@ "DMP-ABOUT-END": ", that highlight the steps followed and the means used across data management activities.", "SELECT-DMP": "Select a DMP for your Dataset", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Add Dataset", - "ADD-DATASET": "Add Dataset", + "ADD-DESCRIPTION": "Add Description", "ADD-DMP-DESCRIPTION": "Add DMP Description" }, "TOUR-GUIDE": { @@ -1746,7 +1778,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index ac0e52f8d..000e95524 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Grabar", - "LINK-NEW": "Nuevo enlace", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Enlazar nueva cuenta", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index 3eac2f970..febf8828c 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index f9833d476..4a7081d74 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Spremi", - "LINK-NEW": "Poveži novo", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Poveži novi korisnički račun", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index 5a29a4c1c..9faaa7840 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Zapisz", - "LINK-NEW": "Połącz nowy", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Połącz nowe konto", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 86ed84324..224e22848 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Guardar", - "LINK-NEW": "Ligar a nova(o)", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Ligar a nova conta", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 00f2823f7..36be035d2 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index 0dc21c855..373fe675e 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Save", - "LINK-NEW": "Link new", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Link new account", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index 955d887e9..d9359c7a4 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -1746,7 +1746,7 @@ }, "ACTIONS": { "SAVE": "Kaydet", - "LINK-NEW": "Yeni bağlantı", + "LINK-NEW": "Link {{ APP_NAME_CAPS }} accounts", "LINK-NEW-ACCOUNT": "Yeni hesabı bağla", "UNLINK-ACCOUNT": "Unlink", "UNLINK-ACCOUNT-DISABLED": "You can't unlink your main profile's email", diff --git a/dmp-frontend/src/assets/resources/skipDisable.json b/dmp-frontend/src/assets/resources/skipDisable.json index b0d92f82e..c791c76b3 100644 --- a/dmp-frontend/src/assets/resources/skipDisable.json +++ b/dmp-frontend/src/assets/resources/skipDisable.json @@ -1,5 +1,6 @@ [ "DatasetProfileEditorModel.description", + "DatasetProfileEditorModel.type", "DatasetProfileEditorModel.label", "SectionEditorModel.title", "SectionEditorModel.description",