diff --git a/.gitignore b/.gitignore index 2190e52ff..f5a3637cc 100644 --- a/.gitignore +++ b/.gitignore @@ -48,3 +48,4 @@ bin/ *.classpath openDMP/dmp-backend/uploads/ openDMP/dmp-backend/tmp/ +dmp-frontend/.angular/ 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..f2348d016 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanBlueprintCriteria.java @@ -0,0 +1,16 @@ +package eu.eudat.data.dao.criteria; + +import eu.eudat.data.entities.DMPProfile; + +public class DataManagementPlanBlueprintCriteria extends Criteria { + + private Integer status; + + public Integer getStatus() { + return status; + } + public void setStatus(Integer status) { + this.status = status; + } + +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanCriteria.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanCriteria.java index 6b8de9a48..4dab4e2f0 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanCriteria.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/criteria/DataManagementPlanCriteria.java @@ -1,6 +1,7 @@ package eu.eudat.data.dao.criteria; import eu.eudat.data.entities.DMP; +import eu.eudat.data.entities.DMPProfile; import eu.eudat.data.entities.Grant; import java.util.Date; @@ -10,6 +11,7 @@ import java.util.UUID; public class DataManagementPlanCriteria extends Criteria { private Date periodStart; private Date periodEnd; + private DMPProfile profile; private List grants; private boolean allVersions; private List groupIds; @@ -37,6 +39,13 @@ public class DataManagementPlanCriteria extends Criteria { this.periodEnd = periodEnd; } + public DMPProfile getProfile() { + return profile; + } + public void setProfile(DMPProfile profile) { + this.profile = profile; + } + public List getGrants() { return grants; } 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/DMPDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java index ac8ce47d7..215b373c0 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DMPDaoImpl.java @@ -42,6 +42,8 @@ public class DMPDaoImpl extends DatabaseAccess implements DMPDao { query.where((builder, root) -> builder.lessThan(root.get("created"), criteria.getPeriodEnd())); if (criteria.getPeriodStart() != null) query.where((builder, root) -> builder.greaterThan(root.get("created"), criteria.getPeriodStart())); + if (criteria.getProfile() != null) + query.where((builder, root) -> builder.equal(root.get("profile"), criteria.getProfile())); if (criteria.getGrants() != null && !criteria.getGrants().isEmpty()) query.where(((builder, root) -> root.get("grant").in(criteria.getGrants()))); if (!criteria.getAllVersions()) @@ -75,7 +77,7 @@ public class DMPDaoImpl extends DatabaseAccess implements DMPDao { query.where((builder, root) -> root.join("users", JoinType.LEFT).join("user", JoinType.LEFT).get("id").in(criteria.getCollaborators())); } if (criteria.getDatasetTemplates() != null && !criteria.getDatasetTemplates().isEmpty()) { - query.where((builder, root) -> root.join("associatedDmps", JoinType.LEFT).get("id").in(criteria.getDatasetTemplates())); + query.where((builder, root) -> root.join("associatedDmps", JoinType.LEFT).get("datasetprofile").get("id").in(criteria.getDatasetTemplates())); } if (criteria.getGrantStatus() != null) { if (criteria.getGrantStatus().equals(GrantStateType.FINISHED.getValue().shortValue())) 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..7033473c2 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,20 @@ 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() + "%")); + if (criteria.getStatus() != null) { + if (criteria.getStatus() == DMPProfile.Status.FINALIZED.getValue()) { + query.where((builder, root) -> builder.equal(root.get("status"), DMPProfile.Status.FINALIZED.getValue())); + } else if (criteria.getStatus() == DMPProfile.Status.SAVED.getValue()) { + query.where((builder, root) -> builder.equal(root.get("status"), DMPProfile.Status.SAVED.getValue())); + } + } + 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..1ce13234d --- /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.and(builder.equal(root.get("name"), name), builder.notEqual(root.get("status"), DescriptionTemplateType.Status.DELETED.getValue()))).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..388a024a7 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/query/items/dmpblueprint/DataManagementPlanBlueprintTableRequest.java @@ -0,0 +1,27 @@ +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() + "%")); + if (this.getCriteria().getStatus() != null) + query.where((builder, root) -> builder.equal(root.get("status"), this.getCriteria().getStatus())); + 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/Dataset.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java index c53f08d29..3a4e135ba 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dataset.java @@ -231,7 +231,9 @@ public class Dataset implements ElasticEntity { if (this.group != null) { builder.field("group", this.group.toString()); } - builder.field("grant", this.grant.toString()); + if (this.grant != null) { + builder.field("grant", this.grant.toString()); + } if (collaborators != null) { builder.startArray("collaborators"); this.collaborators.forEach(x -> { @@ -300,7 +302,9 @@ public class Dataset implements ElasticEntity { this.status = Short.valueOf((String) fields.get("status")); this.dmp = UUID.fromString((String) fields.get("dmp")); this.group = UUID.fromString((String) fields.get("group")); - this.grant = UUID.fromString((String) fields.get("grant")); + if (fields.get("grant") != null) { + this.grant = UUID.fromString((String) fields.get("grant")); + } if (fields.get("created") != null) this.created = Date.from(Instant.parse((String) fields.get("created"))); if (fields.get("modified") != 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/elastic/src/main/java/eu/eudat/elastic/entities/Dmp.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dmp.java index 8d5129521..70d981522 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dmp.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Dmp.java @@ -323,7 +323,9 @@ public class Dmp implements ElasticEntity { if (fields.get(MapKey.DATASETS.getName()) != null) { this.datasets = ((List>) fields.get(MapKey.DATASETS.getName())).stream().map(map -> new Dataset().fromElasticEntity(map)).collect(Collectors.toList()); } - this.grant = UUID.fromString((String) fields.get(MapKey.GRANT.getName())); + if (fields.containsKey(MapKey.GRANT.getName()) && fields.get(MapKey.GRANT.getName()) != null) { + this.grant = UUID.fromString((String) fields.get(MapKey.GRANT.getName())); + } if (fields.get(MapKey.GRANTSTATUS.getName()) != null) { this.grantStatus = Short.valueOf(fields.get(MapKey.GRANTSTATUS.getName()).toString()); } diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java index dcc158405..8364d6c57 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/DatasetRepository.java @@ -146,7 +146,7 @@ public class DatasetRepository extends ElasticRepository 0) { searchSourceBuilder.size(criteria.getSize()); @@ -206,7 +206,7 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setDatasetTemplates(criteria.getDatasetTemplates().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.template", criteria.getDatasetTemplates().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -269,14 +270,17 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setDmps(criteria.getDmps().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.dmp", criteria.getDmps().stream().map(UUID::toString).collect(Collectors.toList()))); } if (criteria.getGroupIds() != null && criteria.getGroupIds().size() > 0) { + criteria.setGroupIds(criteria.getGroupIds().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.group", criteria.getGroupIds().stream().map(UUID::toString).collect(Collectors.toList()))); } if (criteria.getGrants() != null && criteria.getGrants().size() > 0) { + criteria.setGrants(criteria.getGrants().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.grant", criteria.getGrants().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -285,6 +289,7 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setCollaborators(criteria.getCollaborators().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.collaborators.id.keyword", criteria.getCollaborators().stream().map(UUID::toString).collect(Collectors.toList()))); } @@ -295,10 +300,12 @@ public class DatasetRepository extends ElasticRepository 0) { + criteria.setOrganiztions(criteria.getOrganiztions().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.organizations.id", criteria.getOrganiztions())); } if (criteria.getTags() != null && criteria.getTags().size() > 0) { + criteria.setTags(criteria.getTags().stream().filter(Objects::nonNull).collect(Collectors.toList())); boolQuery = boolQuery.should(QueryBuilders.termsQuery("datasets.tags.name", criteria.getTags().stream().map(Tag::getName).collect(Collectors.toList()))); } diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index 4eb9021f9..a0c40b9f0 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -34,7 +34,7 @@ gr.cite.opendmp repositorydepositbase - 1.0.3 + 1.0.4 @@ -46,6 +46,10 @@ org.springframework.boot spring-boot-starter-mail + + org.springframework.boot + spring-boot-starter-webflux + diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java index b0bf85aea..729c8cd05 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java @@ -22,22 +22,15 @@ public class AboutController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public AboutController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getAbout(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } 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..c8ad839e0 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; @@ -58,41 +57,42 @@ public class Admin extends BaseController { @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/addDmp"}, consumes = "application/json", produces = "application/json") - public ResponseEntity addDmp(@Valid @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN ,DATASET_PROFILE_MANAGER}) Principal principal) { + public ResponseEntity addDmp(@Valid @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN ,DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { //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()); } @Transactional @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) { + public ResponseEntity> updateDmp(@PathVariable String id, @RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { 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())); @@ -124,8 +124,8 @@ 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()); + public ResponseEntity> getPreview(@RequestBody DatasetProfile profile, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) throws Exception { + 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,11 +156,12 @@ 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()); datasetProfile.setLanguage(profile.getLanguage()); + datasetProfile.setType(profile.getType().getName()); return this.datasetProfileManager.getDocument(datasetProfile, profile.getLabel()); } else { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("NOT AUTHORIZE")); @@ -173,12 +174,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 +187,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..d7f6fc7ea 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,7 +2,10 @@ 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.exceptions.dmpblueprint.DmpBlueprintUsedException; import eu.eudat.logic.managers.DataManagementProfileManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; @@ -10,6 +13,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; @@ -26,6 +30,7 @@ import java.io.IOException; import java.util.List; import static eu.eudat.types.Authorities.ADMIN; +import static eu.eudat.types.Authorities.DATASET_PROFILE_MANAGER; /** * Created by ikalyvas on 3/21/2018. @@ -51,6 +56,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 +71,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) { + 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,24 +85,51 @@ 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)); + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/clone/{id}"}, consumes = "application/json", produces = "application/json") + public ResponseEntity> clone(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) { + DataManagementPlanBlueprintListingModel dmpBlueprint = this.dataManagementProfileManager.getSingleBlueprint(id, principal); + dmpBlueprint.setLabel(dmpBlueprint.getLabel() + " new "); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(dmpBlueprint)); + } + + @Transactional + @RequestMapping(method = RequestMethod.DELETE, value = {"{id}"}, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity> inactivate(@PathVariable String id, @ClaimedAuthorities(claims = {ADMIN}) Principal principal) { + try { + this.dataManagementProfileManager.inactivate(id); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (DmpBlueprintUsedException exception) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.UNSUCCESS_DELETE).message(exception.getMessage())); + } + } + @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 { + ResponseEntity getXml( @RequestHeader("Content-Type") String contentType, @PathVariable String id, Principal principal) throws IOException { if (contentType.equals("application/xml")) { - DataManagementPlanProfileListingModel dataManagementPlanProfileListingModel = this.dataManagementProfileManager.getSingle(id, principal); - return this.dataManagementProfileManager.getDocument(dataManagementPlanProfileListingModel,dataManagementPlanProfileListingModel.getLabel()); + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = this.dataManagementProfileManager.getSingleBlueprint(id, principal); + return this.dataManagementProfileManager.getDocument(dataManagementPlanBlueprintListingModel); }else { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("NOT AUTHORIZE")); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("NOT AUTHORIZE")); } } @RequestMapping(method = RequestMethod.POST, value = {"/upload"}) public ResponseEntity setDatasetProfileXml(@RequestParam("file") MultipartFile file, - @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws IllegalAccessException,IOException,Exception{ - 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>() + @ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel.DmpBlueprint dmpBlueprintModel = this.dataManagementProfileManager.createDmpProfileFromXml(file); + DataManagementPlanBlueprintListingModel dmpBlueprint = dmpBlueprintModel.toDmpProfileCompositeModel(file.getOriginalFilename()); + this.dataManagementProfileManager.createOrUpdateBlueprint(dmpBlueprint, principal); + 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/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index a2a1926f6..2427314d6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -260,7 +260,7 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.POST, value = {"/clone/{id}"}, consumes = "application/json", produces = "application/json") public @ResponseBody ResponseEntity> clone(@PathVariable UUID id, @RequestBody eu.eudat.models.data.dmp.DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { - UUID cloneId = this.dataManagementPlanManager.clone(dataManagementPlan, principal); + UUID cloneId = this.dataManagementPlanManager.clone(id, dataManagementPlan, principal); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).payload(cloneId)); } 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 5f16cb390..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; @@ -8,6 +9,7 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import eu.eudat.models.data.helpers.common.AutoCompleteLookupItem; +import eu.eudat.models.data.helpers.common.AutoCompleteOptionsLookupItem; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.models.data.properties.PropertiesModel; import eu.eudat.models.data.security.Principal; @@ -55,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)); @@ -63,11 +65,19 @@ 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); } + @RequestMapping(method = RequestMethod.POST, value = {"/search/autocompleteOptions"}, consumes = "application/json", produces = "application/json") + public ResponseEntity getDataForAutocompleteOptions(@RequestBody RequestItem lookupItem) { + AutoCompleteData data = new AutoCompleteData(); + data.setAutoCompleteSingleDataList(lookupItem.getCriteria().getAutoCompleteSingleDataList()); + 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/DatasetProfiles.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java index 372ad6b1d..45ec4d925 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DatasetProfiles.java @@ -6,6 +6,7 @@ import eu.eudat.logic.managers.DatasetProfileManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; +import eu.eudat.models.data.datasetprofile.DatasetProfileWithPrefillingPropertyModel; import eu.eudat.models.data.helpers.responses.ResponseItem; import eu.eudat.types.ApiMessageCode; import org.springframework.beans.factory.annotation.Autowired; @@ -42,5 +43,12 @@ public class DatasetProfiles extends BaseController { List datasetProfileTableData = this.datasetProfileManager.getAll(tableRequestItem); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); } + + @RequestMapping(method = RequestMethod.POST, value = {"/datasetprofiles/getAllWithPrefilling"}, produces = "application/json") + public @ResponseBody + ResponseEntity>> getAllWithPrefilling(@RequestBody DatasetProfileTableRequestItem tableRequestItem) { + List datasetProfileTableData = this.datasetProfileManager.getAllWithPrefilling(tableRequestItem); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(datasetProfileTableData)); + } } 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 8c5b003fa..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); @@ -256,7 +257,8 @@ public class Datasets extends BaseController { public @ResponseBody ResponseEntity> createOrUpdate(@RequestBody DatasetWizardModel profile, Principal principal) throws Exception { DatasetWizardModel dataset = new DatasetWizardModel().fromDataModel(this.datasetManager.createOrUpdate(profile, principal)); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); + dataset.setTags(profile.getTags()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(dataset)); } @Transactional 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/EmailMergeConfirmation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java index d1e89b493..96f959078 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailMergeConfirmation.java @@ -32,16 +32,16 @@ public class EmailMergeConfirmation { @Transactional @RequestMapping(method = RequestMethod.GET, value = {"/{emailToken}"}) public @ResponseBody - ResponseEntity emailConfirmation(@PathVariable(value = "emailToken") String token) { + ResponseEntity> emailConfirmation(@PathVariable(value = "emailToken") String token) { try { - this.emailConfirmationManager.confirmEmail(token); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + String emailToBeMerged = this.emailConfirmationManager.confirmEmail(token); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(emailToBeMerged).status(ApiMessageCode.SUCCESS_MESSAGE)); } catch (HasConfirmedEmailException | TokenExpiredException ex) { if (ex instanceof TokenExpiredException) { - return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); } else { - return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseItem().status(ApiMessageCode.WARN_MESSAGE)); + return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseItem().status(ApiMessageCode.WARN_MESSAGE)); } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java index 0aa9ff078..5badd7959 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java @@ -21,22 +21,15 @@ public class FaqController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public FaqController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getFaq(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java index f46e0f4f0..5e6a783bd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java @@ -21,22 +21,15 @@ public class GlossaryController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public GlossaryController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getGlossary(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java index c6c3335d6..7d39c2630 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Prefillings.java @@ -11,6 +11,7 @@ import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; import java.util.List; +import java.util.Map; import java.util.UUID; @RestController @@ -26,8 +27,8 @@ public class Prefillings { } @RequestMapping(method = RequestMethod.GET, value = {"/prefilling/list"}, produces = "application/json") - public ResponseEntity>> getPrefillingList(@RequestParam String like, @RequestParam String configId) { - List prefillingList = prefillingManager.getPrefillings(like, configId); + public ResponseEntity>> getPrefillingList(@RequestParam String like) { + List prefillingList = prefillingManager.getPrefillings(like); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(prefillingList).status(ApiMessageCode.NO_MESSAGE)); } @@ -36,4 +37,10 @@ public class Prefillings { DatasetWizardModel datasetWizardModel = prefillingManager.getPrefilledDataset(id, configId, profileId); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetWizardModel).status(ApiMessageCode.NO_MESSAGE)); } + + @RequestMapping(method = RequestMethod.POST, value = {"/prefilling/generateUsingData"}, produces = "application/json") + public ResponseEntity> getPrefillingDataset(@RequestBody Map data, @RequestParam String configId, @RequestParam UUID profileId) throws Exception { + DatasetWizardModel datasetWizardModel = prefillingManager.getPrefilledDatasetUsingData(data, configId, profileId); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(datasetWizardModel).status(ApiMessageCode.NO_MESSAGE)); + } } 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..970d95b28 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 @@ -48,9 +46,9 @@ public class QuickWizardController extends BaseController { Funder funderEntity; //Create Funder if (quickWizard.getFunder() == null) { - throw new Exception("Funder is a mandatory entity"); + funderEntity = null; } else if (quickWizard.getFunder().getExistFunder() == null && quickWizard.getFunder().getLabel() == null) { - throw new Exception("Funder is a mandatory entity"); + funderEntity = null; } else if (quickWizard.getFunder().getExistFunder() == null && quickWizard.getFunder().getLabel() != null) { funderEntity = this.quickWizardManager.createOrUpdate(quickWizard.getFunder().toDataFunder(), principal); } else { @@ -60,9 +58,9 @@ public class QuickWizardController extends BaseController { eu.eudat.data.entities.Grant grantEntity; //Create Grant if (quickWizard.getGrant() == null) { - throw new Exception("Grant is a mandatory entity"); + grantEntity = null; } else if (quickWizard.getGrant().getExistGrant() == null && quickWizard.getGrant().getLabel() == null) { - throw new Exception("Grant is a mandatory entity"); + grantEntity = null; } else if (quickWizard.getGrant().getExistGrant() == null) { grantEntity = this.quickWizardManager.createOrUpdate(quickWizard.getGrant().toDataGrant(), principal); } else { @@ -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/controllers/Saml2MetadataController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java index 9f95273c7..4563e2f9f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java @@ -5,6 +5,7 @@ import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.sam import eu.eudat.logic.security.validators.configurableProvider.Saml2SSOUtils; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.saml2.AuthnRequestModel; import eu.eudat.types.ApiMessageCode; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpHeaders; @@ -56,14 +57,14 @@ public class Saml2MetadataController extends BaseController { } @RequestMapping(method = RequestMethod.GET, value = {"authnRequest/{configurableProviderId}"}) public @ResponseBody - ResponseEntity> getAuthnRequest(@PathVariable String configurableProviderId) { + ResponseEntity getAuthnRequest(@PathVariable String configurableProviderId) { Saml2ConfigurableProvider saml2ConfigurableProvider = (Saml2ConfigurableProvider) this.configLoader.getConfigurableProviders().getProviders().stream() .filter(prov -> prov.getConfigurableLoginId().equals(configurableProviderId)) .findFirst().orElse(null); if (saml2ConfigurableProvider != null) { try { - String authnRequestXml = Saml2SSOUtils.getAuthnRequest(saml2ConfigurableProvider); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(authnRequestXml)); + AuthnRequestModel authnRequest = Saml2SSOUtils.getAuthnRequest(saml2ConfigurableProvider); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(authnRequest)); } catch (Exception e) { return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create authentication request.")); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java index d9d015193..2875f6c07 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java @@ -21,22 +21,15 @@ public class TermsOfServiceController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public TermsOfServiceController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getTermsOfService(@PathVariable(name = "lang") String lang) throws IOException { -// long files = 0; -// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { -// files = paths.count(); -// } -// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java index f513238cf..cd7cb9dae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java @@ -34,22 +34,15 @@ public class UserGuideController { private Environment environment; private MaterialManager materialManager; - private final MetricsManager metricsManager; @Autowired public UserGuideController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; this.materialManager = materialManager; - this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { - long files = 0; - try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { - files = paths.count(); - } - metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { return this.materialManager.getResponseEntity(lang, paths); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java b/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java index 40cf806c1..a7891b49f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java +++ b/dmp-backend/web/src/main/java/eu/eudat/criteria/RecentActivityCriteria.java @@ -3,6 +3,7 @@ package eu.eudat.criteria; public class RecentActivityCriteria { private String like; private String order; + private Integer status; public String getLike() { return like; @@ -19,4 +20,12 @@ public class RecentActivityCriteria { public void setOrder(String order) { this.order = order; } + + public Integer getStatus() { + return status; + } + + public void setStatus(Integer status) { + this.status = status; + } } 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/exceptions/dmpblueprint/DmpBlueprintUsedException.java b/dmp-backend/web/src/main/java/eu/eudat/exceptions/dmpblueprint/DmpBlueprintUsedException.java new file mode 100644 index 000000000..3d5e7ec95 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/exceptions/dmpblueprint/DmpBlueprintUsedException.java @@ -0,0 +1,18 @@ +package eu.eudat.exceptions.dmpblueprint; + +public class DmpBlueprintUsedException extends RuntimeException { + public DmpBlueprintUsedException() { + } + + public DmpBlueprintUsedException(String message) { + super(message); + } + + public DmpBlueprintUsedException(String message, Throwable cause) { + super(message, cause); + } + + public DmpBlueprintUsedException(Throwable cause) { + super(cause); + } +} 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..2300fa6e7 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,9 @@ package eu.eudat.logic.builders.entity; +import eu.eudat.data.entities.DescriptionTemplate; +import eu.eudat.data.entities.DescriptionTemplateType; 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,12 +12,14 @@ import java.util.UUID; /** * Created by ikalyvas on 2/15/2018. */ -public class DatasetProfileBuilder extends Builder { +public class DatasetProfileBuilder extends Builder { private UUID id; private String label; + private DescriptionTemplateType type; + private Set dataset; private String definition; @@ -41,6 +44,11 @@ public class DatasetProfileBuilder extends Builder { return this; } + public DatasetProfileBuilder type(DescriptionTemplateType type) { + this.type = type; + return this; + } + public DatasetProfileBuilder dataset(Set dataset) { this.dataset = dataset; return this; @@ -77,17 +85,18 @@ 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); + descriptionTemplate.setType(type); + 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..c515636c0 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,8 @@ 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.data.entities.DescriptionTemplateType; import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; import eu.eudat.logic.builders.entity.DatasetProfileBuilder; import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel; @@ -17,8 +19,9 @@ 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) throws Exception { ViewStyleModel viewStyleModel = new ViewStyleModel(); + viewStyleModel.setEnablePrefilling(profile.isEnablePrefilling()); 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)); Document viewStyleDoc = XmlBuilder.getDocument(); @@ -34,22 +37,31 @@ public class AdminManager { profile.setLanguage("en"); } - eu.eudat.data.entities.DatasetProfile datasetProfile = apiContext.getOperationsContext().getBuilderFactory().getBuilder(DatasetProfileBuilder.class).definition(xml).label(profile.getLabel()) + DescriptionTemplateType type; + try { + type = apiContext.getOperationsContext().getDatabaseRepository().getDescriptionTemplateTypeDao().findFromName(profile.getType()); + } + catch (Exception e) { + throw new Exception("Description template type '" + profile.getType() + "' could not be found."); + } + + 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()) + .type(type) .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 +72,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/DashBoardManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java index cfbdeb6b6..73fef5fff 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DashBoardManager.java @@ -91,7 +91,9 @@ public class DashBoardManager { for (DMP dmp : dmps) { numberOfDatasets = numberOfDatasets + dmp.getDataset().stream() .filter(item -> item.getStatus() == Dataset.Status.FINALISED.getValue()).count(); - grants.add(dmp.getGrant()); + if (dmp.getGrant() != null) { + grants.add(dmp.getGrant()); + } } statistics.setTotalDataManagementPlanCount((long) dmps.size()); @@ -221,11 +223,17 @@ public class DashBoardManager { } DatasetCriteria datasetCriteria = new DatasetCriteria(); datasetCriteria.setLike(tableRequest.getCriteria().getLike()); + if(tableRequest.getCriteria().getStatus() != null) { + datasetCriteria.setStatus(tableRequest.getCriteria().getStatus()); + } datasetCriteria.setAllVersions(false); datasetCriteria.setIsPublic(!isAuthenticated); DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); dataManagementPlanCriteria.setAllVersions(false); dataManagementPlanCriteria.setLike(tableRequest.getCriteria().getLike()); + if(tableRequest.getCriteria().getStatus() != null) { + dataManagementPlanCriteria.setStatus(tableRequest.getCriteria().getStatus()); + } dataManagementPlanCriteria.setIsPublic(!isAuthenticated); dataManagementPlanCriteria.setOnlyPublic(!isAuthenticated); 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 cb2e8a2bc..5573ea2b5 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 @@ -1,10 +1,13 @@ package eu.eudat.logic.managers; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; 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 +28,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 +53,9 @@ 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.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; import eu.eudat.models.data.funder.FunderDMPEditorModel; import eu.eudat.models.data.grant.GrantDMPEditorModel; import eu.eudat.models.data.helpermodels.Tuple; @@ -65,7 +68,7 @@ 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.commons.lang3.StringUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; @@ -87,7 +90,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; @@ -112,6 +114,7 @@ public class DataManagementPlanManager { private ApiContext apiContext; private DatasetManager datasetManager; + private DataManagementProfileManager dataManagementProfileManager; private DatabaseRepository databaseRepository; private Environment environment; private RDAManager rdaManager; @@ -121,10 +124,11 @@ public class DataManagementPlanManager { private List repositoriesDeposit; @Autowired - public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, + public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, DataManagementProfileManager dataManagementProfileManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager, ConfigLoader configLoader, List repositoriesDeposit) { this.apiContext = apiContext; this.datasetManager = datasetManager; + this.dataManagementProfileManager = dataManagementProfileManager; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; this.rdaManager = rdaManager; @@ -142,6 +146,7 @@ public class DataManagementPlanManager { public DataTableData getPaged(DataManagementPlanTableRequest dataManagementPlanTableRequest, Principal principal, String fieldsGroup) throws Exception { UUID principalID = principal.getId(); List dmps = null; + QueryableList items = null; QueryableList authItems = null; Long totalData = 0L; @@ -408,7 +413,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 +454,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 +471,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())) @@ -477,20 +483,34 @@ public class DataManagementPlanManager { } DMP newDmp = dataManagementPlan.toDataModel(); + if(dataManagementPlan.getProfile() != null){ + DMPProfile dmpProfile = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().find(dataManagementPlan.getProfile()); + newDmp.setProfile(dmpProfile); + } if (newDmp.getStatus() == (int) DMP.DMPStatus.FINALISED.getValue()) { checkDmpValidationRules(newDmp); } UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); newDmp.setCreator(user); - createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); - createFunderIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getFunderDao()); - createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao()); - if (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty()) { - newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.ORGANIZATIONS, principal)) { + createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.RESEARCHERS, principal)) { + createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + createFunderIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getFunderDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + createGrantIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao()); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + if (newDmp.getProject() != null && newDmp.getGrant() != null && (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty())) { + newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + } + createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao()); + } } - createProjectIfItDoesntExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getProjectDao()); DMP dmp; if (dataManagementPlan.getId() != null) { @@ -510,16 +530,44 @@ public class DataManagementPlanManager { } } - if (newDmp.getGrant().getType().equals(Grant.GrantType.INTERNAL.getValue())) { - checkIfUserCanEditGrant(newDmp, user); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null && newDmp.getGrant().getType().equals(Grant.GrantType.INTERNAL.getValue())) { + checkIfUserCanEditGrant(newDmp, user); + } + assignGrandUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + assignFunderUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + assignProjectUserIfInternal(newDmp, user); } - assignGrandUserIfInternal(newDmp, user); - assignFunderUserIfInternal(newDmp, user); - assignProjectUserIfInternal(newDmp, user); - apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().createOrUpdate(newDmp.getGrant()); + if(newDmp.getId() != null){ + UUID dmpId = newDmp.getId(); + List dmpDatasetProfiles = apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("dmp").get("id"), dmpId)).toList(); + for (DMPDatasetProfile dmpDatasetProfile : dmpDatasetProfiles) { + if (newDmp.getAssociatedDmps().stream().filter(dmpDatasetProfile1 -> dmpDatasetProfile1.getId() != null).noneMatch(dmpDatasetProfile1 -> dmpDatasetProfile1.getId().equals(dmpDatasetProfile.getId()))) { + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().delete(dmpDatasetProfile); + } + } + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + } + + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null) { + 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()) { @@ -595,7 +643,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())) @@ -609,10 +657,18 @@ public class DataManagementPlanManager { checkDmpValidationRules(tempDMP); } UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); - createOrganisationsIfTheyDontExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); - createResearchersIfTheyDontExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); - createFunderIfItDoesntExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getFunderDao()); - createGrantIfItDoesntExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao()); + if(this.dataManagementProfileManager.fieldInBlueprint(tempDMP.getProfile(), SystemFieldType.ORGANIZATIONS, principal)) { + createOrganisationsIfTheyDontExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(tempDMP.getProfile(), SystemFieldType.RESEARCHERS, principal)) { + createResearchersIfTheyDontExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(tempDMP.getProfile(), SystemFieldType.FUNDER, principal)) { + createFunderIfItDoesntExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getFunderDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(tempDMP.getProfile(), SystemFieldType.GRANT, principal)) { + createGrantIfItDoesntExist(tempDMP, apiContext.getOperationsContext().getDatabaseRepository().getGrantDao()); + } DMP result = createOrUpdate(dataManagementPlan, principal); @@ -645,35 +701,62 @@ public class DataManagementPlanManager { if (latestVersionDMP.get(0).getVersion().equals(oldDmp.getVersion())) { DMP newDmp = dataManagementPlan.toDataModel(); + newDmp.setProfile(oldDmp.getProfile()); + newDmp.setProperties(oldDmp.getProperties()); + newDmp.setDmpProperties(oldDmp.getDmpProperties()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); newDmp.setCreator(user); - createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); - - createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); - createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); - if (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty()) { - newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.ORGANIZATIONS, principal)) { + createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.RESEARCHERS, principal)) { + createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + if (newDmp.getProject() != null && newDmp.getGrant() != null && (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty())) { + newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + } + createProjectIfItDoesntExist(newDmp, databaseRepository.getProjectDao()); + } } - createProjectIfItDoesntExist(newDmp, databaseRepository.getProjectDao()); newDmp.setGroupId(oldDmp.getGroupId()); newDmp.setVersion(oldDmp.getVersion() + 1); newDmp.setId(null); - checkIfUserCanEditGrant(newDmp, user); - assignGrandUserIfInternal(newDmp, user); - assignFunderUserIfInternal(newDmp, user); - assignProjectUserIfInternal(newDmp, user); - if (newDmp.getGrant().getStartdate() == null) { - newDmp.getGrant().setStartdate(new Date()); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null && newDmp.getGrant().getType().equals(Grant.GrantType.INTERNAL.getValue())) { + checkIfUserCanEditGrant(newDmp, user); + } + assignGrandUserIfInternal(newDmp, user); } - if (newDmp.getGrant().getEnddate() == null) { - newDmp.getGrant().setEnddate(Date.from(Instant.now().plus(365, ChronoUnit.DAYS))); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + assignFunderUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + assignProjectUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null) { + if (newDmp.getGrant().getStartdate() == null) { + newDmp.getGrant().setStartdate(new Date()); + } + if (newDmp.getGrant().getEnddate() == null) { + newDmp.getGrant().setEnddate(Date.from(Instant.now().plus(365, ChronoUnit.DAYS))); + } + databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); + } } - databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); DMP tempDmp = databaseRepository.getDmpDao().createOrUpdate(newDmp); newDmp.setId(tempDmp.getId()); + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } // Assign creator. //assignUser(newDmp, user); @@ -703,32 +786,60 @@ public class DataManagementPlanManager { } } - public UUID clone(DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { + public UUID clone(UUID uuid, DataManagementPlanNewVersionModel dataManagementPlan, Principal principal) throws Exception { + DMP oldDmp = databaseRepository.getDmpDao().find(uuid); DMP newDmp = dataManagementPlan.toDataModel(); + newDmp.setProfile(oldDmp.getProfile()); + newDmp.setProperties(oldDmp.getProperties()); + newDmp.setDmpProperties(oldDmp.getDmpProperties()); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); newDmp.setCreator(user); - createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); - createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); - - createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); - createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); - if (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty()) { - newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.ORGANIZATIONS, principal)) { + createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.RESEARCHERS, principal)) { + createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + createFunderIfItDoesntExist(newDmp, databaseRepository.getFunderDao()); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + createGrantIfItDoesntExist(newDmp, databaseRepository.getGrantDao()); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + if (newDmp.getProject() != null && newDmp.getGrant() != null && (newDmp.getProject().getLabel() == null || newDmp.getProject().getLabel().trim().isEmpty())) { + newDmp.setProject(newDmp.getProject().projectFromGrant(newDmp.getGrant())); + } + createProjectIfItDoesntExist(newDmp, databaseRepository.getProjectDao()); + } } - createProjectIfItDoesntExist(newDmp, databaseRepository.getProjectDao()); newDmp.setGroupId(UUID.randomUUID()); newDmp.setVersion(0); newDmp.setId(null); - checkIfUserCanEditGrant(newDmp, user); - assignGrandUserIfInternal(newDmp, user); - assignFunderUserIfInternal(newDmp, user); - assignProjectUserIfInternal(newDmp, user); - databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null && newDmp.getGrant().getType().equals(Grant.GrantType.INTERNAL.getValue())) { + checkIfUserCanEditGrant(newDmp, user); + } + assignGrandUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.FUNDER, principal)) { + assignFunderUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.PROJECT, principal)) { + assignProjectUserIfInternal(newDmp, user); + } + if(this.dataManagementProfileManager.fieldInBlueprint(newDmp.getProfile(), SystemFieldType.GRANT, principal)) { + if (newDmp.getGrant() != null) { + databaseRepository.getGrantDao().createOrUpdate(newDmp.getGrant()); + } + } DMP tempDmp = databaseRepository.getDmpDao().createOrUpdate(newDmp); newDmp.setId(tempDmp.getId()); + for(DMPDatasetProfile dmpDatasetProfile : newDmp.getAssociatedDmps()){ + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } assignUser(newDmp, user); copyDatasets(newDmp, databaseRepository.getDatasetDao()); @@ -869,7 +980,7 @@ public class DataManagementPlanManager { } private void createFunderIfItDoesntExist(DMP newDmp, FunderDao funderDao) { - if (newDmp.getGrant().getFunder() != null) { + if (newDmp.getGrant() != null && newDmp.getGrant().getFunder() != null) { Funder funder = newDmp.getGrant().getFunder(); FunderCriteria criteria = new FunderCriteria(); if (funder.getReference() != null) { @@ -992,7 +1103,9 @@ public class DataManagementPlanManager { datasetElastic.setStatus(dataset1.getStatus()); datasetElastic.setDmp(dataset1.getDmp().getId()); datasetElastic.setGroup(dataset1.getDmp().getGroupId()); - datasetElastic.setGrant(dataset1.getDmp().getGrant().getId()); + if(this.dataManagementProfileManager.fieldInBlueprint(dataset1.getDmp().getProfile(), SystemFieldType.GRANT, null)) { + datasetElastic.setGrant(dataset1.getDmp().getGrant().getId()); + } if (dataset1.getDmp().getUsers() != null) { datasetElastic.setCollaborators(dataset1.getDmp().getUsers().stream().map(user -> { Collaborator collaborator = new Collaborator(); @@ -1013,7 +1126,9 @@ public class DataManagementPlanManager { }).collect(Collectors.toList())); } datasetElastic.setPublic(dataset1.getDmp().isPublic()); - datasetElastic.setGrantStatus(dataset1.getDmp().getGrant().getStatus()); + if(this.dataManagementProfileManager.fieldInBlueprint(dataset1.getDmp().getProfile(), SystemFieldType.GRANT, null)) { + datasetElastic.setGrantStatus(dataset1.getDmp().getGrant().getStatus()); + } try { eu.eudat.elastic.entities.Dataset oldDatasetElastic = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().findDocument(dataset.getId().toString()); @@ -1192,7 +1307,7 @@ public class DataManagementPlanManager { } public FileEnvelope getWordDocument(String id, Principal principal, ConfigLoader configLoader, Boolean versioned) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); VisibilityRuleService visibilityRuleService = new VisibilityRuleServiceImpl(); DatasetWizardModel dataset = new DatasetWizardModel(); XWPFDocument document = configLoader.getDocument(); @@ -1250,116 +1365,310 @@ 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.getOrdinal() + ". " + section.getLabel(), 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(); + if (systemField.getType() == SystemFieldType.LANGUAGE) continue; + XWPFParagraph systemFieldParagraph = document.createParagraph(); +// systemFieldParagraph.setSpacingBetween(1.0); + XWPFRun runSyStemFieldTitle = systemFieldParagraph.createRun(); + runSyStemFieldTitle.setText(systemField.getLabel() + ": "); + 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 = systemFieldParagraph.createRun(); + runTitle.setText(dmpEntity.getLabel()); + runTitle.setColor("116a78"); + break; + case HTML_TEXT: + wordBuilder.addParagraphContent(dmpEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); + break; + case RESEARCHERS: + for (Researcher researcher : dmpEntity.getResearchers()) { + XWPFRun runResearcher = systemFieldParagraph.createRun(); + runResearcher.addBreak(); + runResearcher.setText(researcher.getLabel()); + runResearcher.setColor("116a78"); + } + break; + case ORGANIZATIONS: + for (Organisation organisation : dmpEntity.getOrganisations()) { + XWPFRun runOrganisation = systemFieldParagraph.createRun(); + runOrganisation.addBreak(); + runOrganisation.setText(organisation.getLabel()); + runOrganisation.setColor("116a78"); + } + break; +// case LANGUAGE: +// XWPFRun runLanguage = systemFieldParagraph.createRun(); +// runLanguage.setText(objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class).get("language").toString()); +// runLanguage.setColor("116a78"); +// break; + case CONTACT: + XWPFRun runContact = systemFieldParagraph.createRun(); + runContact.setText(dmpEntity.getCreator() == null ? "" : dmpEntity.getCreator().getName()); + runContact.setColor("116a78"); + break; + case FUNDER: + if (dmpEntity.getGrant() != null && dmpEntity.getGrant().getFunder() != null) { + XWPFRun runFunder = systemFieldParagraph.createRun(); + runFunder.setText(dmpEntity.getGrant().getFunder().getLabel()); + runFunder.setColor("116a78"); + } + break; + case GRANT: + if (dmpEntity.getGrant() != null) { + XWPFRun runGrant = systemFieldParagraph.createRun(); + runGrant.setText(dmpEntity.getGrant().getLabel()); + runGrant.setColor("116a78"); + } + break; + case PROJECT: + if (dmpEntity.getProject() != null) { + XWPFRun runProject = systemFieldParagraph.createRun(); + runProject.setText(dmpEntity.getProject().getLabel()); + runProject.setColor("116a78"); + } + break; + case LICENSE: + Map extraProperties = objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class); + if (extraProperties.containsKey("license")) { + Map license = ((Map) extraProperties.get("license")); + if (license != null && !StringUtils.isEmpty(license.get("pid"))) { + XWPFRun runLicense = systemFieldParagraph.createRun(); + runLicense.setText(license.get("pid").toString()); + runLicense.setColor("116a78"); + } + } + break; + case ACCESS_RIGHTS: + Map extraPropertiesMap = objectMapper.readValue(dmpEntity.getExtraProperties(), HashMap.class); + if (extraPropertiesMap.containsKey("visible")) { + XWPFRun runAccessRights = systemFieldParagraph.createRun(); + runAccessRights.setText(Boolean.valueOf(extraPropertiesMap.get("visible").toString()) ? "Public" : "Restricted"); + runAccessRights.setColor("116a78"); + } + break; + } + //document.createParagraph(); + } else if (field.getCategory() == FieldCategory.EXTRA) { - document.createParagraph(); + Map dmpProperties = objectMapper.readValue(dmpEntity.getProperties(), HashMap.class); + if (dmpProperties != null && (!dmpProperties.containsKey(field.getId().toString()) || StringUtils.isEmpty((String) dmpProperties.get(field.getId().toString())))) + continue; + ExtraField extraField = field.toExtraField(); + XWPFParagraph extraFieldParagraph = document.createParagraph(); + extraFieldParagraph.setSpacingBetween(1.0); + XWPFRun runExtraFieldLabel = extraFieldParagraph.createRun(); + runExtraFieldLabel.setText(extraField.getLabel() + ": "); + runExtraFieldLabel.setColor("000000"); +// if(extraField.getDescription() != null && !extraField.getDescription().isEmpty()){ +// XWPFRun runExtraFieldDescription = extraFieldParagraph.createRun(); +// runExtraFieldDescription.setText(extraField.getDescription()); +// runExtraFieldDescription.setColor("116a78"); +// } + XWPFRun runExtraFieldInput = extraFieldParagraph.createRun(); + switch (extraField.getType()) { + case TEXT: + runExtraFieldInput.setText((String) dmpProperties.get(field.getId().toString())); + runExtraFieldInput.setColor("116a78"); + break; + case RICH_TEXT: + wordBuilder.addParagraphContent(dmpProperties.get(field.getId().toString()), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); +// runExtraFieldInput.setText((String) dmpProperties.get(field.getId().toString())); +// runExtraFieldInput.setColor("116a78"); + break; + case DATE: + runExtraFieldInput.setText((String) dmpProperties.get(field.getId().toString())); + runExtraFieldInput.setColor("116a78"); + break; + case NUMBER: + runExtraFieldInput.setText((String) dmpProperties.get(field.getId().toString())); + runExtraFieldInput.setColor("116a78"); + break; + } -// /*XWPFParagraph externalReferencesParagraph = document.createParagraph(); -// externalReferencesParagraph.setStyle("Heading3"); -// XWPFRun externalReferencesRun = externalReferencesParagraph.createRun(); -// externalReferencesRun.setText("External References"); -// externalReferencesRun.setColor("2E75B6"); -// externalReferencesRun.setBold(true); -// externalReferencesRun.setFontSize(12); + } + } + + //if(!section.getDescriptionTemplates().isEmpty()){ + final Boolean isFinalized = dmpEntity.getStatus() == DMP.DMPStatus.FINALISED.getValue(); + final Boolean isPublic = dmpEntity.isPublic(); + List datasets = 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)).collect(Collectors.toList()); + + if (datasets.size() > 0) + wordBuilder.addParagraphContent("Descriptions", document, ParagraphStyle.HEADER2, BigInteger.ZERO, 0); + for (Dataset datasetEntity : datasets) { + + + 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(datasetEntity.getLabel()); + //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 descriptionParagraph = document.createParagraph(); +// XWPFRun descriptionParagraphRun = descriptionParagraph.createRun(); +// descriptionParagraphRun.setText("Description: "); +// descriptionParagraphRun.setColor("000000"); + wordBuilder.addParagraphContent(datasetEntity.getDescription(), document, ParagraphStyle.HTML, BigInteger.ZERO, 0); + + 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("Type: "); + runDatasetDescription1.setColor("000000"); + XWPFRun runDatasetDescription = datasetDescParagraph.createRun(); + runDatasetDescription.setText(datasetEntity.getProfile().getType().getName()); + 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++) { @@ -1381,7 +1690,13 @@ public class DataManagementPlanManager { wordBuilder.fillFooter(dmpEntity, null, document, false); - String fileName = "DMP_" + dmpEntity.getGrant().getLabel(); + String fileName; + if (dmpEntity.getGrant() != null && dmpEntity.getGrant().getLabel() != null) { + fileName = "DMP_" + dmpEntity.getGrant().getLabel(); + } + else { + fileName = "DMP_" + dmpEntity.getLabel(); + } if (versioned) { fileName += "_" + dmpEntity.getVersion(); } @@ -1450,9 +1765,9 @@ public class DataManagementPlanManager { Element dmpProfileId = xmlDoc.createElement("dmpProfileId"); dmpProfileId.setTextContent(dmpProfile.getId().toString()); dmpProfileElement.appendChild(dmpProfileId); - Element values = xmlDoc.createElement("values"); - values.setTextContent(dmpProfile.getDefinition()); - dmpProfileElement.appendChild(values); +// Element values = xmlDoc.createElement("values"); +// values.setTextContent(dmpProfile.getDefinition()); +// dmpProfileElement.appendChild(values); } dmpElement.appendChild(dmpProfileElement); @@ -1492,53 +1807,59 @@ public class DataManagementPlanManager { // Funder. Element funder = xmlDoc.createElement("funder"); - Element funderLabel = xmlDoc.createElement("label"); - Element funderId = xmlDoc.createElement("id"); - funderLabel.setTextContent(dmp.getGrant().getFunder().getLabel()); - funderId.setTextContent(dmp.getGrant().getFunder().getId().toString()); - funder.appendChild(funderLabel); - funder.appendChild(funderId); - if(dmp.getGrant().getFunder().getReference() != null){ - String referencePrefix = dmp.getGrant().getFunder().getReference().split(":")[0]; - String shortReference = dmp.getGrant().getFunder().getReference().substring(referencePrefix.length() + 1); - Element funderReference = xmlDoc.createElement("reference"); - funderReference.setTextContent(shortReference); - funder.appendChild(funderReference); + if (this.dataManagementProfileManager.fieldInBlueprint(dmp.getProfile(), SystemFieldType.GRANT, principal) && this.dataManagementProfileManager.fieldInBlueprint(dmp.getProfile(), SystemFieldType.FUNDER, principal) && dmp.getGrant() != null) { + Element funderLabel = xmlDoc.createElement("label"); + Element funderId = xmlDoc.createElement("id"); + funderLabel.setTextContent(dmp.getGrant().getFunder().getLabel()); + funderId.setTextContent(dmp.getGrant().getFunder().getId().toString()); + funder.appendChild(funderLabel); + funder.appendChild(funderId); + if (dmp.getGrant().getFunder().getReference() != null) { + String referencePrefix = dmp.getGrant().getFunder().getReference().split(":")[0]; + String shortReference = dmp.getGrant().getFunder().getReference().substring(referencePrefix.length() + 1); + Element funderReference = xmlDoc.createElement("reference"); + funderReference.setTextContent(shortReference); + funder.appendChild(funderReference); + } } dmpElement.appendChild(funder); // Grant. Element grant = xmlDoc.createElement("grant"); - Element grantLabel = xmlDoc.createElement("label"); - Element grantId = xmlDoc.createElement("id"); - grantLabel.setTextContent(dmp.getGrant().getLabel()); - grantId.setTextContent(dmp.getGrant().getId().toString()); - grant.appendChild(grantLabel); - grant.appendChild(grantId); - if(dmp.getGrant().getReference() != null) { - String referencePrefix = dmp.getGrant().getReference().split(":")[0]; - String shortReference = dmp.getGrant().getReference().substring(referencePrefix.length() + 1); - Element grantReference = xmlDoc.createElement("reference"); - grantReference.setTextContent(shortReference); - grant.appendChild(grantReference); + if (this.dataManagementProfileManager.fieldInBlueprint(dmp.getProfile(), SystemFieldType.GRANT, principal) && dmp.getGrant() != null) { + Element grantLabel = xmlDoc.createElement("label"); + Element grantId = xmlDoc.createElement("id"); + grantLabel.setTextContent(dmp.getGrant().getLabel()); + grantId.setTextContent(dmp.getGrant().getId().toString()); + grant.appendChild(grantLabel); + grant.appendChild(grantId); + if (dmp.getGrant().getReference() != null) { + String referencePrefix = dmp.getGrant().getReference().split(":")[0]; + String shortReference = dmp.getGrant().getReference().substring(referencePrefix.length() + 1); + Element grantReference = xmlDoc.createElement("reference"); + grantReference.setTextContent(shortReference); + grant.appendChild(grantReference); + } } dmpElement.appendChild(grant); // Project. Element project = xmlDoc.createElement("project"); - Element projectId = xmlDoc.createElement("id"); - Element projectLabel = xmlDoc.createElement("label"); - Element projectDescription = xmlDoc.createElement("description"); - Element projectStartDate = xmlDoc.createElement("start"); - Element projectEndDate = xmlDoc.createElement("end"); - projectId.setTextContent(dmp.getProject().getId().toString()); - projectLabel.setTextContent(dmp.getProject().getLabel()); - projectDescription.setTextContent(dmp.getProject().getDescription()); - projectStartDate.setTextContent(dmp.getProject().getStartdate().toString()); - projectEndDate.setTextContent(dmp.getProject().getEnddate().toString()); - project.appendChild(projectId); - project.appendChild(projectLabel); - project.appendChild(projectDescription); - project.appendChild(projectStartDate); - project.appendChild(projectEndDate); + if (this.dataManagementProfileManager.fieldInBlueprint(dmp.getProfile(), SystemFieldType.PROJECT, principal) && dmp.getProject() != null) { + Element projectId = xmlDoc.createElement("id"); + Element projectLabel = xmlDoc.createElement("label"); + Element projectDescription = xmlDoc.createElement("description"); + Element projectStartDate = xmlDoc.createElement("start"); + Element projectEndDate = xmlDoc.createElement("end"); + projectId.setTextContent(dmp.getProject().getId().toString()); + projectLabel.setTextContent(dmp.getProject().getLabel()); + projectDescription.setTextContent(dmp.getProject().getDescription()); + projectStartDate.setTextContent(dmp.getProject().getStartdate().toString()); + projectEndDate.setTextContent(dmp.getProject().getEnddate().toString()); + project.appendChild(projectId); + project.appendChild(projectLabel); + project.appendChild(projectDescription); + project.appendChild(projectStartDate); + project.appendChild(projectEndDate); + } dmpElement.appendChild(project); Element organisationsElement = xmlDoc.createElement("organisations"); @@ -1566,8 +1887,33 @@ public class DataManagementPlanManager { researchersElement.appendChild(researcherElement); } dmpElement.appendChild(researchersElement); - Element datasetsElement = xmlDoc.createElement("datasets"); + Element extraFields = xmlDoc.createElement("extraFields"); + Map dmpProperties = new ObjectMapper().readValue(dmp.getProperties(), new TypeReference>() {}); + DataManagementPlanBlueprint blueprint = this.dataManagementProfileManager.getSingleBlueprint(dmp.getProfile().getId().toString(), principal).getDefinition(); + blueprint.getSections().forEach(section -> { + section.getFields().forEach(fieldModel -> { + if (fieldModel.getCategory() == FieldCategory.EXTRA) { + Element extraField = xmlDoc.createElement("extraField"); + Element extraFieldId = xmlDoc.createElement("id"); + extraFieldId.setTextContent(fieldModel.getId().toString()); + Element extraFieldLabel = xmlDoc.createElement("label"); + extraFieldLabel.setTextContent(fieldModel.getLabel()); + Element extraFieldValue = xmlDoc.createElement("value"); + Object value = dmpProperties.get(fieldModel.getId().toString()); + if (value != null) { + extraFieldValue.setTextContent((String) value); + } + extraField.appendChild(extraFieldId); + extraField.appendChild(extraFieldLabel); + extraField.appendChild(extraFieldValue); + extraFields.appendChild(extraField); + } + }); + }); + dmpElement.appendChild(extraFields); + + Element datasetsElement = xmlDoc.createElement("datasets"); for (Dataset dataset : datasets) { Element datasetElement = xmlDoc.createElement("dataset"); datasetElement.setAttribute("name", dataset.getLabel()); @@ -1576,6 +1922,10 @@ public class DataManagementPlanManager { datasetElement.appendChild(datasetDescriptionElement); datasetDescriptionElement.setTextContent(dataset.getDescription()); + Element datasetDmpSectionIndex = xmlDoc.createElement("dmpSectionIndex"); + datasetElement.appendChild(datasetDmpSectionIndex); + datasetDmpSectionIndex.setTextContent(String.valueOf(dataset.getDmpSectionIndex())); + Element datsetProfileElement = xmlDoc.createElement("profile-id"); datasetElement.appendChild(datsetProfileElement); datsetProfileElement.setTextContent(dataset.getProfile().getId().toString()); @@ -1596,23 +1946,33 @@ public class DataManagementPlanManager { datasetElement.appendChild(xmlBuilder.createPages(pagedDatasetProfile.getPages(), visibilityRuleService, xmlDoc)); datasetsElement.appendChild(datasetElement); } - Element profiles = xmlDoc.createElement("profiles"); + 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); + Element profileInSections = xmlDoc.createElement("profileInSections"); + Map data = new ObjectMapper().readValue(dmpDescriptionProfile.getData(), new TypeReference>() {}); + List sections = (List) data.get("dmpSectionIndex"); + for(int section: sections) { + Element profileInSection = xmlDoc.createElement("section"); + profileInSection.setTextContent(String.valueOf(section)); + profileInSections.appendChild(profileInSection); + } + profile.appendChild(profileInSections); profiles.appendChild(profile); } dmpElement.appendChild(profiles); @@ -1623,7 +1983,12 @@ public class DataManagementPlanManager { writer.close(); FileEnvelope fileEnvelope = new FileEnvelope(); fileEnvelope.setFile(xmlFile); - fileEnvelope.setFilename("DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion() + ".xml"); + if (dmp.getGrant() != null && dmp.getGrant().getLabel() != null) { + fileEnvelope.setFilename("DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion() + ".xml"); + } + else { + fileEnvelope.setFilename("DMP_" + dmp.getLabel() + "_" + dmp.getVersion() + ".xml"); + } return fileEnvelope; } @@ -1641,7 +2006,13 @@ public class DataManagementPlanManager { .collect(Collectors.toSet())); String result = rdaManager.convertToRDA(dmp); - String fileName = "DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion(); + String fileName; + if (dmp.getGrant() != null && dmp.getGrant().getLabel() != null) { + fileName = "DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion(); + } + else { + fileName = "DMP_" + dmp.getLabel() + "_" + dmp.getVersion(); + } fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", "").replace(" ", "_").replace(",", "_"); String uuid = UUID.randomUUID().toString(); File file = new File(this.environment.getProperty("temp.temp") + uuid + ".json"); @@ -1712,59 +2083,83 @@ public class DataManagementPlanManager { // Creates new dataManagementPlan to fill it with the data model that was parsed from the xml. // Creates properties. DataManagementPlanEditorModel dm = new DataManagementPlanEditorModel(); - DataManagementPlanProfile dmpProfile = new DataManagementPlanProfile(); - List fieldList = new LinkedList<>(); - Field field = new Field(); - field.setLabel(dataManagementPlans.get(0).getDmpProfile().getDmpProfileName()); - field.setId(dataManagementPlans.get(0).getDmpProfile().getDmpProfileId()); + DmpProfileImportModel dmpProfileImportModel = dataManagementPlans.get(0).getDmpProfile(); + UUID profileId = null; + if (dmpProfileImportModel != null) { + profileId = dmpProfileImportModel.getDmpProfileId(); + } + else { + profileId = UUID.fromString("86635178-36a6-484f-9057-a934e4eeecd5"); + } + dm.setProfile(profileId); - fieldList.add(field); - dmpProfile.setFields(fieldList); - /*Tuple tuple = new Tuple(); - tuple.setId(dataManagementPlans.get(0).getDmpProfile().getDmpProfileId()); - tuple.setLabel(dataManagementPlans.get(0).getDmpProfile().getDmpProfileName());*/ - eu.eudat.models.data.funder.Funder funder = new eu.eudat.models.data.funder.Funder(); - FunderImportModels funderImport = dataManagementPlans.get(0).getFunderImportModels(); - funder.setId(funderImport.getId()); - funder.setLabel(funderImport.getLabel()); - FunderDMPEditorModel funderEditor = new FunderDMPEditorModel(); - funderEditor.setExistFunder(funder); - - eu.eudat.models.data.grant.Grant grant = new eu.eudat.models.data.grant.Grant(); - GrantImportModels grantImport = dataManagementPlans.get(0).getGrantImport(); - grant.setId(grantImport.getId()); - grant.setLabel(grantImport.getLabel()); - grant.setAbbreviation(grantImport.getAbbreviation()); - grant.setDescription(grantImport.getDescription()); - GrantDMPEditorModel grantEditor = new GrantDMPEditorModel(); - grantEditor.setExistGrant(grant); - - eu.eudat.models.data.project.Project project = new eu.eudat.models.data.project.Project(); - ProjectImportModels projectImport = dataManagementPlans.get(0).getProjectImportModels(); - project.setId(projectImport.getId()); - project.setLabel(projectImport.getLabel()); - ProjectDMPEditorModel projectEditor = new ProjectDMPEditorModel(); - projectEditor.setExistProject(project); - - List associatedProfiles = new LinkedList<>(); - if (profiles != null && profiles.length > 0) { - for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); - AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); - associatedProfiles.add(associatedProfile); + Map dmpPropertiesMap = new HashMap<>(); + if (dataManagementPlans.get(0).getExtraFieldsImportModels() != null) { + for (ExtraFieldsImportModels extraField: dataManagementPlans.get(0).getExtraFieldsImportModels()) { + dmpPropertiesMap.put(extraField.getId(), extraField.getValue()); } } + dm.setProperties(dmpPropertiesMap); + + if (this.dataManagementProfileManager.fieldInBlueprint(dmpProfileImportModel.getDmpProfileId().toString(), SystemFieldType.FUNDER, principal)) { + eu.eudat.models.data.funder.Funder funder = new eu.eudat.models.data.funder.Funder(); + FunderImportModels funderImport = dataManagementPlans.get(0).getFunderImportModels(); + funder.setId(funderImport.getId()); + funder.setLabel(funderImport.getLabel()); + FunderDMPEditorModel funderEditor = new FunderDMPEditorModel(); + funderEditor.setExistFunder(funder); + + dm.setFunder(funderEditor); + } + + if (this.dataManagementProfileManager.fieldInBlueprint(dmpProfileImportModel.getDmpProfileId().toString(), SystemFieldType.GRANT, principal)) { + eu.eudat.models.data.grant.Grant grant = new eu.eudat.models.data.grant.Grant(); + GrantImportModels grantImport = dataManagementPlans.get(0).getGrantImport(); + grant.setId(grantImport.getId()); + grant.setLabel(grantImport.getLabel()); + grant.setAbbreviation(grantImport.getAbbreviation()); + grant.setDescription(grantImport.getDescription()); + GrantDMPEditorModel grantEditor = new GrantDMPEditorModel(); + grantEditor.setExistGrant(grant); + + dm.setGrant(grantEditor); + } + + if (this.dataManagementProfileManager.fieldInBlueprint(dmpProfileImportModel.getDmpProfileId().toString(), SystemFieldType.PROJECT, principal)) { + eu.eudat.models.data.project.Project project = new eu.eudat.models.data.project.Project(); + ProjectImportModels projectImport = dataManagementPlans.get(0).getProjectImportModels(); + project.setId(projectImport.getId()); + project.setLabel(projectImport.getLabel()); + ProjectDMPEditorModel projectEditor = new ProjectDMPEditorModel(); + projectEditor.setExistProject(project); + + dm.setProject(projectEditor); + } + + List associatedProfiles = new LinkedList<>(); +// if (profiles != null && profiles.length > 0) { +// for (String profile : profiles) { +// DescriptionTemplate exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); +// AssociatedProfile associatedProfile = new AssociatedProfile().fromData(exProfile); +// associatedProfiles.add(associatedProfile); +// } +// } 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); + Map data = new HashMap<>(); + List sections = new ArrayList<>(a.getSection()); + data.put("dmpSectionIndex", sections); + associatedProfile.setData(data); associatedProfiles.add(associatedProfile); } catch (Exception ignored) { } } + List organisations = new ArrayList<>(); for (OrganisationImportModel org : dataManagementPlans.get(0).getOrganisationImportModels()) { eu.eudat.models.data.dmp.Organisation organisation = new eu.eudat.models.data.dmp.Organisation(); @@ -1773,6 +2168,7 @@ public class DataManagementPlanManager { organisation.setKey(organisation.getReference().split(":")[0]); organisations.add(organisation); } + List researchers = new LinkedList<>(); for (ResearcherImportModels res : dataManagementPlans.get(0).getResearchersImportModels()) { eu.eudat.models.data.dmp.Researcher researcher = new eu.eudat.models.data.dmp.Researcher(); @@ -1788,16 +2184,13 @@ public class DataManagementPlanManager { // Sets properties. dm.setLabel(files[0].getOriginalFilename()); // Sets label. - dm.setGrant(grantEditor); //Sets grant property. - dm.setFunder(funderEditor); - dm.setProject(projectEditor); dm.setDescription(dataManagementPlans.get(0).getDescriptionImport()); // Sets description property. dm.setProfiles(associatedProfiles); dm.setOrganisations(organisations); // Sets organisations property. dm.setResearchers(researchers); // Sets researchers property. dm.setAssociatedUsers(associatedUsers); // Sets associatedUsers property. dm.setDynamicFields(dynamicFields); // Sets dynamicFields property. - dm.setDefinition(dmpProfile); + //dm.setDefinition(dmpProfile); //ObjectMapper mapper = new ObjectMapper(); Map extraPropertiesMap = new HashMap<>(); if (dataManagementPlans.get(0).getLanguage() != null) { @@ -1836,10 +2229,11 @@ public class DataManagementPlanManager { for (DatasetImportModels das: dataManagementPlans.get(0).getDatasetImportModels()) { eu.eudat.data.entities.Dataset dataset = new eu.eudat.data.entities.Dataset(); dataset.setLabel(das.getName()); + dataset.setDmpSectionIndex(das.getDmpSectionIndex()); 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); @@ -1892,6 +2286,11 @@ public class DataManagementPlanManager { dmp.setUsers(new HashSet<>(apiContext.getOperationsContext().getDatabaseRepository().getUserDmpDao().asQueryable().where((builder, root) -> builder.equal(root.get("dmp").get("id"), dmpId)).toList())); this.updateIndex(dmp); } + for(DMPDatasetProfile dmpDatasetProfile : dmp.getAssociatedDmps()){ + dmpDatasetProfile.setDmp(dmp); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDatasetProfileDao().createOrUpdate(dmpDatasetProfile); + } + dmp.getDataset().forEach(dataset -> { dataset.setStatus(Dataset.Status.SAVED.getValue()); dataset.setCreated(new Date()); @@ -1951,19 +2350,19 @@ public class DataManagementPlanManager { } private void assignGrandUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getGrant().getCreationUser() == null && (dmp.getGrant().getReference() != null && dmp.getGrant().getReference().startsWith("dmp:"))) { + if (dmp.getGrant() != null && dmp.getGrant().getCreationUser() == null && (dmp.getGrant().getReference() != null && dmp.getGrant().getReference().startsWith("dmp:"))) { dmp.getGrant().setCreationUser(user); } } private void assignFunderUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getGrant().getFunder().getCreationUser() == null && ( dmp.getGrant().getFunder().getReference() != null && dmp.getGrant().getFunder().getReference().startsWith("dmp:"))) { + if (dmp.getGrant() != null && dmp.getGrant().getFunder() != null && dmp.getGrant().getFunder().getCreationUser() == null && ( dmp.getGrant().getFunder().getReference() != null && dmp.getGrant().getFunder().getReference().startsWith("dmp:"))) { dmp.getGrant().getFunder().setCreationUser(user); } } private void assignProjectUserIfInternal(DMP dmp, UserInfo user) { - if (dmp.getProject().getCreationUser() == null && (dmp.getProject().getReference() != null && dmp.getProject().getReference().startsWith("dmp:"))) { + if (dmp.getProject() != null && dmp.getProject().getCreationUser() == null && (dmp.getProject().getReference() != null && dmp.getProject().getReference().startsWith("dmp:"))) { dmp.getProject().setCreationUser(user); } } @@ -2043,7 +2442,7 @@ public class DataManagementPlanManager { * */ private void checkIfUserCanEditGrant(DMP dmp, UserInfo user) throws Exception{ - if (dmp.getGrant().getId() != null) { + if (dmp.getGrant() != null && dmp.getGrant().getId() != null) { Grant grant = apiContext.getOperationsContext().getDatabaseRepository().getGrantDao().find(dmp.getGrant().getId()); if (grant.getFunder() != null && dmp.getGrant().getFunder() != null && !grant.getFunder().getId().equals(dmp.getGrant().getFunder().getId())) { @@ -2130,15 +2529,17 @@ public class DataManagementPlanManager { DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfEnvelope, rdaJsonFile, supportingFilesZip, previousDOI); - Optional repo = this.repositoriesDeposit.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(depositRequest.getRepositoryId())).findFirst(); - String finalDoi = repo.map(r -> { - try { - return r.deposit(dmpDepositModel, depositRequest.getAccessToken()); - } catch (Exception e) { - logger.error(e.getMessage(), e); - return null; + String finalDoi = null; + for(RepositoryDeposit repo: this.repositoriesDeposit){ + if(repo.getConfiguration().stream().anyMatch(x-> x.getRepositoryId().equals(depositRequest.getRepositoryId()))){ + try { + finalDoi = repo.deposit(depositRequest.getRepositoryId(), dmpDepositModel, depositRequest.getAccessToken()); + } catch (Exception e) { + logger.error(e.getMessage(), e); + return null; + } } - }).orElse(null); + } Doi doiModel = null; if (finalDoi != null) { 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..979a63f06 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 @@ -2,21 +2,29 @@ package eu.eudat.logic.managers; import com.jayway.jsonpath.DocumentContext; import com.jayway.jsonpath.JsonPath; +import eu.eudat.data.dao.criteria.DataManagementPlanCriteria; import eu.eudat.data.dao.criteria.RequestItem; -import eu.eudat.data.dao.entities.DMPProfileDao; +import eu.eudat.data.dao.entities.DatasetDao; +import eu.eudat.data.dao.entities.DatasetProfileDao; 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.item.dmpprofile.DataManagementPlanProfileCriteriaRequest; import eu.eudat.data.query.items.table.dmpprofile.DataManagementPlanProfileTableRequest; +import eu.eudat.exceptions.datasetprofile.DatasetProfileWithDatasetsExeption; +import eu.eudat.exceptions.dmpblueprint.DmpBlueprintUsedException; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; -import eu.eudat.logic.utilities.documents.xml.dmpXml.ExportXmlBuilderDmpProfile; -import eu.eudat.logic.utilities.documents.xml.dmpXml.ImportXmlBuilderDmpProfile; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DmpProfileExternalAutoComplete; -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field; +import eu.eudat.logic.utilities.documents.xml.dmpXml.ExportXmlBuilderDmpBlueprint; +import eu.eudat.logic.utilities.documents.xml.dmpXml.ImportXmlBuilderDmpBlueprint; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.*; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.SystemFieldType; 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 +86,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 +107,45 @@ public class DataManagementProfileManager { return dataManagementPlanProfileListingModel; } + public DataManagementPlanBlueprintListingModel getSingleBlueprint(String id, Principal principal) { + DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); + DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel = new DataManagementPlanBlueprintListingModel(); + dataManagementPlanBlueprintListingModel.fromDataModel(dmpProfile); + return dataManagementPlanBlueprintListingModel; + } + + public boolean fieldInBlueprint(String id, SystemFieldType type, Principal principal) { + DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); + return this.fieldInBlueprint(dmpProfile, type, principal); + } + + public boolean fieldInBlueprint(DMPProfile dmpProfile, SystemFieldType type, Principal principal) { + DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel(); + dmpBlueprint.fromDataModel(dmpProfile); + for(Section section: dmpBlueprint.getDefinition().getSections()){ + for(FieldModel field: section.getFields()){ + if(field.getCategory().equals(FieldCategory.SYSTEM)){ + SystemField systemField = field.toSystemField(); + if(systemField.getType().equals(type)){ + return true; + } + } + } + } + return false; + } + + public List sectionIndexesForDescriptionTemplate(DMPProfile dmpProfile, UUID descriptionTemplateId) { + DataManagementPlanBlueprintListingModel dmpBlueprint = new DataManagementPlanBlueprintListingModel(); + dmpBlueprint.fromDataModel(dmpProfile); + List sectionIndexes = new ArrayList<>(); + for(int i = 0; i < dmpBlueprint.getDefinition().getSections().size(); i++) { + Section section = dmpBlueprint.getDefinition().getSections().get(i); + if(section.getHasTemplates() && section.getDescriptionTemplates().stream().anyMatch(x -> x.getDescriptionTemplateId().equals(descriptionTemplateId))) sectionIndexes.add(i); + } + return sectionIndexes; + } + 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,8 +157,25 @@ public class DataManagementProfileManager { apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); } - public ResponseEntity getDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws IllegalAccessException, IOException, InstantiationException { - FileEnvelope envelope = getXmlDocument(dmpProfile, label); + public void createOrUpdateBlueprint(DataManagementPlanBlueprintListingModel dataManagementPlanBlueprintListingModel, Principal principal) throws Exception { + DMPProfile dmpProfile = dataManagementPlanBlueprintListingModel.toDataModel(); + apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().createOrUpdate(dmpProfile); + } + + public void inactivate(String id) { + DMPProfile dmpProfile = databaseRepository.getDmpProfileDao().find(UUID.fromString(id)); + DataManagementPlanCriteria dataManagementPlanCriteria = new DataManagementPlanCriteria(); + dataManagementPlanCriteria.setProfile(dmpProfile); + if (dmpProfile.getStatus() == DMPProfile.Status.SAVED.getValue() || databaseRepository.getDmpDao().getWithCriteria(dataManagementPlanCriteria).count() == 0) { + dmpProfile.setStatus(DMPProfile.Status.DELETED.getValue()); + databaseRepository.getDmpProfileDao().createOrUpdate(dmpProfile); + } else { + throw new DmpBlueprintUsedException("This blueprint can not deleted, because DMPs are associated with it"); + } + } + + public ResponseEntity getDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException { + FileEnvelope envelope = getXmlDocument(dmpProfile); InputStream resource = new FileInputStream(envelope.getFile()); logger.info("Mime Type of " + envelope.getFilename() + " is " + new MimetypesFileTypeMap().getContentType(envelope.getFile())); @@ -116,18 +194,18 @@ public class DataManagementProfileManager { HttpStatus.OK); } - public FileEnvelope getXmlDocument(DataManagementPlanProfileListingModel dmpProfile, String label) throws InstantiationException, IllegalAccessException, IOException { - ExportXmlBuilderDmpProfile xmlBuilder = new ExportXmlBuilderDmpProfile(); + public FileEnvelope getXmlDocument(DataManagementPlanBlueprintListingModel dmpProfile) throws IOException { + ExportXmlBuilderDmpBlueprint xmlBuilder = new ExportXmlBuilderDmpBlueprint(); File file = xmlBuilder.build(dmpProfile, environment); FileEnvelope fileEnvelope = new FileEnvelope(); fileEnvelope.setFile(file); - fileEnvelope.setFilename(label); + fileEnvelope.setFilename(dmpProfile.getLabel()); return fileEnvelope; } - public eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel.DmpProfile createDmpProfileFromXml(MultipartFile multiPartFile) { - ImportXmlBuilderDmpProfile xmlBuilder = new ImportXmlBuilderDmpProfile(); + public eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel.DmpBlueprint createDmpProfileFromXml(MultipartFile multiPartFile) { + ImportXmlBuilderDmpBlueprint xmlBuilder = new ImportXmlBuilderDmpBlueprint(); try { return xmlBuilder.build(convert(multiPartFile)); } catch (IOException e) { 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 793f6382d..5da228f05 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 @@ -289,6 +289,45 @@ public class DatasetManager { .stream().filter(userInfo -> userInfo.getUser().getId() == principal.getId()) .collect(Collectors.toList()).size() == 0 && !datasetEntity.getDmp().isPublic()) throw new UnauthorisedException(); + dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); + dataset.fromDataModel(datasetEntity); + + // Creates the Criteria to get all version of DescriptionTemplate in question. + DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); + UUID profileId = datasetEntity.getProfile().getGroupId(); + List uuidList = new LinkedList<>(); + uuidList.add(profileId); + profileCriteria.setGroupIds(uuidList); + profileCriteria.setAllVersions(true); + + List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) + .orderBy(((builder, root) -> builder.desc(root.get("version")))) + .toList(); + List profileVersionsIncluded = new LinkedList<>(); + + // Iterate through the versions and remove those that are not included in the DMP of the dataset in question. + for (DescriptionTemplate version : profileVersions) { + for (AssociatedProfile p : dataset.getDmp().getProfiles()) { + if (version.getId().toString().equals(p.getDescriptionTemplateId().toString())) { + profileVersionsIncluded.add(version); + } + } + } + + // Sort the list with the included Versions. + 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()); + if (profiles.isEmpty()) + throw new NoSuchElementException("No profiles found for the specific Dataset"); + + DescriptionTemplate profile = profiles.get(0); + + // Check if the dataset is on the latest Version. + boolean latestVersion = profile.getVersion().toString().equals(datasetEntity.getProfile().getVersion().toString()); + dataset.setIsProfileLatestVersion(latestVersion); + eu.eudat.elastic.entities.Dataset datasetElastic; try { datasetElastic = datasetRepository.exists() ? @@ -297,45 +336,6 @@ public class DatasetManager { logger.warn(ex.getMessage()); datasetElastic = null; } - dataset.setDatasetProfileDefinition(getPagedProfile(dataset, datasetEntity)); - dataset.fromDataModel(datasetEntity); - - // Creates the Criteria to get all version of DatasetProfile in question. - DatasetProfileCriteria profileCriteria = new DatasetProfileCriteria(); - UUID profileId = datasetEntity.getProfile().getGroupId(); - List uuidList = new LinkedList<>(); - uuidList.add(profileId); - profileCriteria.setGroupIds(uuidList); - profileCriteria.setAllVersions(true); - - List profileVersions = databaseRepository.getDatasetProfileDao().getWithCriteria(profileCriteria) - .orderBy(((builder, root) -> builder.desc(root.get("version")))) - .toList(); - 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 (AssociatedProfile p : dataset.getDmp().getProfiles()) { - if (version.getId().toString().equals(p.getId().toString())) { - profileVersionsIncluded.add(version); - } - } - } - - // Sort the list with the included Versions. - Stream sorted = profileVersionsIncluded.stream().sorted(Comparator.comparing(DatasetProfile::getVersion).reversed()); - - // Make the Stream into List and get the first item. - List profiles = sorted.collect(Collectors.toList()); - if (profiles.isEmpty()) - throw new NoSuchElementException("No profiles found for the specific Dataset"); - - DatasetProfile profile = profiles.get(0); - - // Check if the dataset is on the latest Version. - boolean latestVersion = profile.getVersion().toString().equals(datasetEntity.getProfile().getVersion().toString()); - dataset.setIsProfileLatestVersion(latestVersion); - if (datasetElastic != null && datasetElastic.getTags() != null && !datasetElastic.getTags().isEmpty()) { dataset.setTags(datasetElastic.getTags()); } @@ -397,7 +397,7 @@ public class DatasetManager { } private XWPFDocument getWordDocument(ConfigLoader configLoader, eu.eudat.data.entities.Dataset datasetEntity, VisibilityRuleService visibilityRuleService, Principal principal) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); DatasetWizardModel dataset = new DatasetWizardModel(); XWPFDocument document = configLoader.getDatasetDocument(); @@ -509,7 +509,7 @@ public class DatasetManager { } private XWPFDocument getLightWordDocument(ConfigLoader configLoader, DatasetWizardModel dataset, VisibilityRuleService visibilityRuleService) throws IOException { - WordBuilder wordBuilder = new WordBuilder(this.environment); + WordBuilder wordBuilder = new WordBuilder(this.environment, configLoader); XWPFDocument document = configLoader.getDocument(); // Space below Dataset title. @@ -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); @@ -1034,18 +1034,10 @@ public class DatasetManager { public DatasetWizardModel datasetUpdateProfile(String id) { DatasetWizardModel dataset = new DatasetWizardModel(); eu.eudat.data.entities.Dataset datasetEntity = databaseRepository.getDatasetDao().find(UUID.fromString(id), HintedModelFactory.getHint(DatasetWizardModel.class)); - eu.eudat.elastic.entities.Dataset datasetElastic; - try { - datasetElastic = datasetRepository.exists() ? - datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); - } catch (Exception ex) { - logger.warn(ex.getMessage()); - datasetElastic = null; - } 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<>(); @@ -1053,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)); @@ -1062,6 +1054,14 @@ public class DatasetManager { // Now at latest version. dataset.setIsProfileLatestVersion(true); + eu.eudat.elastic.entities.Dataset datasetElastic; + try { + datasetElastic = datasetRepository.exists() ? + datasetRepository.findDocument(id) : new eu.eudat.elastic.entities.Dataset(); + } catch (Exception ex) { + logger.warn(ex.getMessage()); + datasetElastic = null; + } if (datasetElastic != null && datasetElastic.getTags() != null && !datasetElastic.getTags().isEmpty()) { dataset.setTags(datasetElastic.getTags()); } @@ -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<>(); @@ -1143,19 +1143,21 @@ public class DatasetManager { if (!tagNodes.isEmpty()) { tagNodes.forEach(node -> { JsonNode value = node.get("value"); - if (!value.toString().equals("\"\"") && !value.toString().equals("null") && value.toString().startsWith("[")) { - String stringValue = value.toString().replaceAll("=", ":"); - JSONArray values = new JSONArray(stringValue); - values.iterator().forEachRemaining(element -> { - Map data = ((JSONObject) element).toMap(); - this.addTag(tags, wizardModel.getTags(), data.get("id").toString(), data.get("name").toString()); - }); - } else { - List values = Arrays.asList(value.textValue().split(", ")); - List tagValues = values.stream().map(stringValue -> new Tag(stringValue, stringValue)).collect(Collectors.toList()); - tagValues.iterator().forEachRemaining(tag -> { - this.addTag(tags, wizardModel.getTags(), tag.getId(), tag.getName()); - }); + if (!value.toString().equals("\"\"") && !value.toString().equals("null")) { + if (value.toString().startsWith("[")) { + String stringValue = value.toString().replaceAll("=", ":"); + JSONArray values = new JSONArray(stringValue); + values.iterator().forEachRemaining(element -> { + Map data = ((JSONObject) element).toMap(); + this.addTag(tags, wizardModel.getTags(), data.get("id").toString(), data.get("name").toString()); + }); + } else { + List values = Arrays.asList(value.textValue().split(", ")); + List tagValues = values.stream().map(stringValue -> new Tag(stringValue, stringValue)).collect(Collectors.toList()); + tagValues.iterator().forEachRemaining(tag -> { + this.addTag(tags, wizardModel.getTags(), tag.getId(), tag.getName()); + }); + } } }); } @@ -1181,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..c6aae9b6d 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 @@ -1,26 +1,28 @@ 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; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException; import eu.eudat.logic.builders.model.models.DataTableDataBuilder; -import eu.eudat.logic.proxy.config.Semantic; +import eu.eudat.logic.proxy.config.*; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; +import eu.eudat.logic.proxy.config.entities.GeneralUrls; +import eu.eudat.logic.proxy.fetching.RemoteFetcher; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ExportXmlBuilderDatasetProfile; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ImportXmlBuilderDatasetProfile; +import eu.eudat.models.data.admin.composite.DatasetProfile; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; +import eu.eudat.models.data.datasetprofile.DatasetProfileWithPrefillingPropertyModel; import eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import eu.eudat.models.data.helpers.common.DataTableData; @@ -34,10 +36,11 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.http.*; -import org.springframework.http.client.SimpleClientHttpRequestFactory; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; import org.springframework.stereotype.Component; -import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; @@ -54,6 +57,8 @@ import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.*; import java.io.*; +import java.net.URI; +import java.net.URISyntaxException; import java.nio.file.Files; import java.util.*; import java.util.stream.Collectors; @@ -64,29 +69,30 @@ public class DatasetProfileManager { private static final Logger logger = LoggerFactory.getLogger(DatasetProfileManager.class); private static final List cache = new ArrayList<>(); - private ApiContext apiContext; - private DatabaseRepository databaseRepository; - private Environment environment; - private ConfigLoader configLoader; - + private final ApiContext apiContext; + private final DatabaseRepository databaseRepository; + private final Environment environment; + private final ConfigLoader configLoader; private final MetricsManager metricsManager; - + private final RemoteFetcher remoteFetcher; @Autowired - public DatasetProfileManager(ApiContext apiContext, Environment environment, ConfigLoader configLoader, MetricsManager metricsManager) { + public DatasetProfileManager(ApiContext apiContext, Environment environment, ConfigLoader configLoader, MetricsManager metricsManager, RemoteFetcher remoteFetcher) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; this.configLoader = configLoader; this.metricsManager = metricsManager; + this.remoteFetcher = remoteFetcher; } @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,40 +100,55 @@ 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; } + public List getAllWithPrefilling(DatasetProfileTableRequestItem tableRequestItem) { + List datasetProfiles = new ArrayList<>(); + if (!tableRequestItem.getCriteria().getIds().isEmpty()) { + tableRequestItem.getCriteria().getIds().forEach(id -> { + DatasetProfile datasetProfile = this.getDatasetProfile(id.toString()); + DatasetProfileWithPrefillingPropertyModel profileModel = new DatasetProfileWithPrefillingPropertyModel(); + profileModel.setId(id); + profileModel.setLabel(datasetProfile.getLabel()); + profileModel.setEnablePrefilling(datasetProfile.isEnablePrefilling()); + datasetProfiles.add(profileModel); + }); + } + return datasetProfiles; + } + public eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field queryForField(String xml, String fieldId) throws XPathExpressionException { eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.Field field = new Field(); Document document = XmlBuilder.fromXml(xml); @@ -140,10 +161,10 @@ public class DatasetProfileManager { return field; } - public static List getAutocomplete(AutoCompleteData data, String like) { - List result = new LinkedList<>(); + public List getAutocomplete(AutoCompleteData data, String like) { + /*List result = new LinkedList<>(); SimpleClientHttpRequestFactory simpleFactory = new SimpleClientHttpRequestFactory(); - + RestTemplate restTemplate = new RestTemplate(simpleFactory); HttpHeaders headers = new HttpHeaders(); DocumentContext jsonContext = null; @@ -162,7 +183,7 @@ public class DatasetProfileManager { if (url.contains("zenodo")) { url = url.replace("?", "/?"); } - + url = url.replace("{like}", like.equals("") ? "*" : like); url = url.replace("%20", " "); url = url.replace("%22", "\""); @@ -178,7 +199,7 @@ public class DatasetProfileManager { headers.setContentType(MediaType.APPLICATION_JSON); entity = new HttpEntity<>("parameters", headers); - + response = restTemplate.exchange(url, HttpMethod.GET, entity, Object.class); jsonContext = JsonPath.parse(response.getBody()); jsonItems = jsonContext.read(singleData.getOptionsRoot() + "['" + singleData.getAutoCompleteOptions().getLabel() + "','" + singleData.getAutoCompleteOptions().getValue() + "','" + singleData.getAutoCompleteOptions().getSource() + "','" + "uri" + "']"); @@ -204,8 +225,72 @@ public class DatasetProfileManager { } return result.stream().sorted(Comparator.comparing(ExternalAutocompleteFieldModel::getLabel)).collect(Collectors.toList()); - - //return result; +*/ + List result = new LinkedList<>(); + ExternalUrlCriteria urlCriteria = new ExternalUrlCriteria(); + GeneralUrls genericUrls = new GeneralUrls(); + int ordinal = 1; + List> rawResults = new ArrayList<>(); + genericUrls.setFetchMode(FetchStrategy.FIRST); + urlCriteria.setLike(like); + for (AutoCompleteData.AutoCompleteSingleData singleData : data.getAutoCompleteSingleDataList()) { + UrlConfiguration urlConfiguration = new UrlConfiguration(); + try { + URI uri; + if (singleData.getUrl().contains("?")) { + uri = new URI(singleData.getUrl().substring(0, singleData.getUrl().lastIndexOf("?"))); + } else { + uri = new URI(singleData.getUrl()); + } + String source = singleData.getAutoCompleteOptions().getSource(); + source = source != null && !source.isEmpty() ? source : uri.getHost(); + String uriString = singleData.getAutoCompleteOptions().getUri(); + uriString = uriString != null && !uriString.isEmpty() ? uriString : "uri"; + String parsedUrl = singleData.getUrl(); + parsedUrl = parsedUrl.replace("%20", " "); + parsedUrl = parsedUrl.replace("%22", "\""); + while (parsedUrl.contains("&")) { + parsedUrl = parsedUrl.replace("&", "&"); + } + urlConfiguration.setUrl(parsedUrl); + urlConfiguration.setOrdinal(ordinal); + urlConfiguration.setType("External"); + urlConfiguration.setContentType(MediaType.APPLICATION_JSON_VALUE); + urlConfiguration.setFirstpage("1"); + urlConfiguration.setRequestType(singleData.getMethod() != null ? singleData.getMethod() : "GET"); + DataUrlConfiguration dataUrlConfiguration = new DataUrlConfiguration(); + dataUrlConfiguration.setPath(singleData.getOptionsRoot()); + DataFieldsUrlConfiguration fieldsUrlConfiguration = new DataFieldsUrlConfiguration(); + fieldsUrlConfiguration.setId(singleData.getAutoCompleteOptions().getValue()); + fieldsUrlConfiguration.setName(singleData.getAutoCompleteOptions().getLabel()); + fieldsUrlConfiguration.setSource(singleData.getAutoCompleteOptions().getSource().isEmpty()? null : singleData.getAutoCompleteOptions().getSource()); + fieldsUrlConfiguration.setUri(uriString); + dataUrlConfiguration.setFieldsUrlConfiguration(fieldsUrlConfiguration); + urlConfiguration.setKey(source); + urlConfiguration.setLabel(source); + urlConfiguration.setData(dataUrlConfiguration); + if (singleData.getHasAuth()) { + AuthenticationConfiguration authenticationConfiguration = new AuthenticationConfiguration(); + authenticationConfiguration.setAuthUrl(singleData.getAuth().getUrl()); + authenticationConfiguration.setAuthMethod(singleData.getAuth().getMethod()); + authenticationConfiguration.setAuthTokenPath(singleData.getAuth().getPath()); + authenticationConfiguration.setAuthRequestBody(singleData.getAuth().getBody()); + authenticationConfiguration.setType(singleData.getAuth().getType()); + urlConfiguration.setAuth(authenticationConfiguration); + } + genericUrls.getUrls().add(urlConfiguration); + List> singleResults = this.remoteFetcher.getExternalGeneric(urlCriteria, genericUrls); + if (!singleResults.isEmpty() && !singleResults.get(0).containsKey("source") && !singleData.getAutoCompleteOptions().getSource().isEmpty()) { + singleResults.forEach(singleResult -> singleResult.put("source", singleData.getAutoCompleteOptions().getSource())); + } + rawResults.addAll(singleResults); + genericUrls.getUrls().clear(); + } catch (URISyntaxException e) { + logger.error(e.getMessage(), e); + } + } + rawResults.forEach(item -> result.add(new ExternalAutocompleteFieldModel(parseItem(item.get("pid")), parseItem(item.get("name")), parseItem(item.get("source")), parseItem(item.get("uri"))))); + return result; } private static String parseItem(Object item) { @@ -276,36 +361,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 +425,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 +466,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 +487,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 +507,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 +522,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/DepositManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java index df71d4f65..fa8e20d42 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java @@ -31,18 +31,24 @@ public class DepositManager { public List getAvailableRepos() { List reposConfigModel = new ArrayList<>(); for (RepositoryDeposit r: this.repositories) { - RepositoryConfig repoModel = new RepositoryConfig(); - RepositoryDepositConfiguration repoConf = r.getConfiguration(); + List repoConf = r.getConfiguration(); if(repoConf != null) { - reposConfigModel.add(repoModel.toModel(repoConf)); + for(RepositoryDepositConfiguration cf: repoConf){ + RepositoryConfig repoModel = new RepositoryConfig(); + reposConfigModel.add(repoModel.toModel(cf)); + } } } return reposConfigModel; } public String authenticate(String id, String code) { - Optional repo = repositories.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(id)).findFirst(); - return repo.map(repositoryDeposit -> repositoryDeposit.authenticate(code)).orElse(null); + for(RepositoryDeposit r: this.repositories){ + if(r.getConfiguration().stream().anyMatch(x -> x.getRepositoryId().equals(id))){ + return r.authenticate(id, code); + } + } + return null; } public Doi deposit(DepositRequest depositRequest, Principal principal) throws Exception { @@ -50,9 +56,12 @@ public class DepositManager { } public String getRepositoryLogo(String repositoryId){ - Optional repo = repositories.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(repositoryId)).findFirst(); - return repo.map(repositoryDeposit -> - (repositoryDeposit.getConfiguration().isHasLogo()) ? repositoryDeposit.getLogo() : null - ).orElse(null); + for(RepositoryDeposit r: this.repositories){ + Optional cf = r.getConfiguration().stream().filter(x -> x.getRepositoryId().equals(repositoryId)).findFirst(); + if(cf.isPresent()){ + return cf.get().isHasLogo() ? r.getLogo(repositoryId) : null; + } + } + return null; } } 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/EmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java index f6ad1d6fc..59200beb3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/EmailConfirmationManager.java @@ -48,6 +48,9 @@ public class EmailConfirmationManager { // Checks if mail is used by another user. If it is, merges the new the old. Long existingUsers = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).count(); if (existingUsers > 0) { + Credential credential = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + credential.setEmail(loginConfirmationEmail.getEmail()); + databaseRepository.getCredentialDao().createOrUpdate(credential); UserInfo oldUser = databaseRepository.getUserInfoDao().asQueryable().where((builder, root) -> builder.equal(root.get("email"), loginConfirmationEmail.getEmail())).getSingle(); mergeNewUserToOld(user, oldUser); expireUserToken(user); @@ -57,6 +60,12 @@ public class EmailConfirmationManager { user.setEmail(loginConfirmationEmail.getEmail()); databaseRepository.getUserInfoDao().createOrUpdate(user); + Credential credential = databaseRepository.getCredentialDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("userInfo"), user)).getSingle(); + if(credential.getEmail() == null){ + credential.setEmail(user.getEmail()); + databaseRepository.getCredentialDao().createOrUpdate(credential); + } databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java index e020593ed..a668a811d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/GrantManager.java @@ -140,6 +140,7 @@ public class GrantManager { grants.add(grant); } + grants = grants.stream().filter(grant -> grant.getLabel() != null).collect(Collectors.toList()); grants.sort(Comparator.comparing(Grant::getLabel)); grants = grants.stream().filter(listHelper.distinctByKey(Grant::getLabel)).collect(Collectors.toList()); return grants; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java index 8a30c6acb..4a6b0ac56 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MergeEmailConfirmationManager.java @@ -5,6 +5,10 @@ import eu.eudat.data.entities.EmailConfirmation; import eu.eudat.data.entities.UserDMP; import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserToken; +import eu.eudat.elastic.criteria.DmpCriteria; +import eu.eudat.elastic.entities.Collaborator; +import eu.eudat.elastic.entities.Dmp; +import eu.eudat.elastic.repository.DmpRepository; import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; import eu.eudat.logic.services.ApiContext; @@ -25,21 +29,25 @@ import com.fasterxml.jackson.databind.ObjectMapper; import javax.transaction.Transactional; import java.io.IOException; import java.util.*; +import java.util.stream.Collectors; +import java.util.stream.Stream; @Component public class MergeEmailConfirmationManager { private static Logger logger = LoggerFactory.getLogger(MergeEmailConfirmationManager.class); private ApiContext apiContext; private DatabaseRepository databaseRepository; + private DmpRepository dmpRepository; @Autowired public MergeEmailConfirmationManager(ApiContext apiContext) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); + this.dmpRepository = apiContext.getOperationsContext().getElasticRepository().getDmpRepository(); } @Transactional - public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { + public String confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { EmailConfirmation loginConfirmationEmail = apiContext.getOperationsContext() .getDatabaseRepository().getLoginConfirmationEmailDao().asQueryable() .where((builder, root) -> builder.equal(root.get("token"), UUID.fromString(token))).getSingle(); @@ -49,7 +57,7 @@ public class MergeEmailConfirmationManager { UserInfo userToBeMerged = databaseRepository.getUserInfoDao().asQueryable() .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); - + String userToBeMergedEmail = userToBeMerged.getEmail(); try { Map map = new ObjectMapper().readValue(loginConfirmationEmail.getData(), HashMap.class); UUID otherUserId = UUID.fromString((String) map.get("userId")); @@ -64,6 +72,8 @@ public class MergeEmailConfirmationManager { } catch (Exception e) { logger.error(e.getMessage(), e); } + + return userToBeMergedEmail; } public void sendConfirmationEmail(String email, Principal principal, UUID userId, Integer provider) throws HasConfirmedEmailException { @@ -91,6 +101,38 @@ public class MergeEmailConfirmationManager { userDmp.setUser(newUser); databaseRepository.getUserDmpDao().createOrUpdate(userDmp); }); + try { + DmpCriteria dmpCriteria = new DmpCriteria(); + dmpCriteria.setCollaborators(Collections.singletonList(oldUser.getId())); + List elasticDmpsIds = dmpRepository.query(dmpCriteria); + for(Dmp dmpId: elasticDmpsIds){ + Dmp dmp = dmpRepository.findDocument(dmpId.getId().toString()); + if(dmp.getDatasets() != null) { + dmp.getDatasets().forEach(dataset -> { + if(dataset.getCollaborators() != null) { + for (Collaborator collaborator : dataset.getCollaborators()) { + if (collaborator.getId().equals(oldUser.getId().toString())) { + collaborator.setId(newUser.getId().toString()); + collaborator.setName(newUser.getName()); + } + } + } + }); + } + if(dmp.getCollaborators() != null) { + for (Collaborator collaborator : dmp.getCollaborators()) { + if (collaborator.getId().equals(oldUser.getId().toString())) { + collaborator.setId(newUser.getId().toString()); + collaborator.setName(newUser.getName()); + } + } + } + dmpRepository.createOrUpdate(dmp); + } + } + catch (IOException e){ + logger.warn("Warning: Could not fetch dmps from elastic.", e); + } oldUser.setUserStatus((short)1); oldUser.setEmail(null); List credentials = databaseRepository.getCredentialDao().asQueryable().where((builder, root) -> builder.equal(root.get("userInfo"), oldUser)).toList(); 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 b39aebd6d..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) { @@ -180,6 +180,8 @@ public class MetricsManager { try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { long files = paths.count(); calculateValue(MetricNames.LANGUAGES, (int) files, null); + } catch (Exception e) { + logger.error("Could not calculate languages."); } calculateValue(MetricNames.INSTALLATIONS, 1, null); @@ -404,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/NotificationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java index f9c6403c7..a579d1870 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/NotificationManager.java @@ -60,20 +60,20 @@ public class NotificationManager { case DMP_MODIFIED: case DATASET_MODIFIED: subjectTemplate = this.environment.getProperty("notification.modified.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/modifiedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.modified.template")); break; case DMP_PUBLISH: subjectTemplate = this.environment.getProperty("notification.publish.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/publishNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.publish.template")); break; case DMP_FINALISED: subjectTemplate = this.environment.getProperty("notification.finalised.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/finalisedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.finalised.template")); break; case DMP_MODIFIED_FINALISED: case DATASET_MODIFIED_FINALISED: subjectTemplate = this.environment.getProperty("notification.modifiedFinalised.subject"); - contentTemplate = mailService.getMailTemplateContent("classpath:templates/notifications/modifiedFinalisedNotification.html"); + contentTemplate = mailService.getMailTemplateContent(this.environment.getProperty("notification.modified_finalised.template")); break; } 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 81d5fe3e0..73d39b708 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 @@ -1,7 +1,8 @@ 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; @@ -11,10 +12,7 @@ import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.prefilling.Prefilling; import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.http.HttpEntity; -import org.springframework.http.HttpHeaders; -import org.springframework.http.HttpMethod; -import org.springframework.http.MediaType; +import org.springframework.http.*; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; @@ -29,30 +27,51 @@ public class PrefillingManager { private final ObjectMapper objectMapper; private final DatasetManager datasetManager; private final LicenseManager licenseManager; + private final PrefillingMapper prefillingMapper; @Autowired - public PrefillingManager(ApiContext apiContext, ConfigLoader configLoader, DatasetManager datasetManager, LicenseManager licenseManager) { + public PrefillingManager(ApiContext apiContext, ConfigLoader configLoader, DatasetManager datasetManager, LicenseManager licenseManager, PrefillingMapper prefillingMapper) { this.apiContext = apiContext; this.configLoader = configLoader; - this.objectMapper = new ObjectMapper(); + this.prefillingMapper = prefillingMapper; + this.objectMapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); this.datasetManager = datasetManager; this.licenseManager = licenseManager; } - public List getPrefillings(String like, String configId) { - PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); + public List getPrefillings(String like) { ExternalUrlCriteria externalUrlCriteria = new ExternalUrlCriteria(); externalUrlCriteria.setLike(like); - List> map = apiContext.getOperationsContext().getRemoteFetcher().getExternalGeneric(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); - return map.stream().map(submap -> objectMapper.convertValue(submap, Prefilling.class)).collect(Collectors.toList()); + List prefillings = new ArrayList<>(); + List> map; + Map prefillingConfigs = configLoader.getExternalUrls().getPrefillings(); + for (PrefillingConfig prefillingConfig: prefillingConfigs.values()) { + map = apiContext.getOperationsContext().getRemoteFetcher().getExternalGeneric(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); + prefillings.addAll(map.stream().map(submap -> objectMapper.convertValue(submap, Prefilling.class)).collect(Collectors.toList())); + if (prefillingConfig.getPrefillingSearch().getUrlConfig().isDataInListing()) { + List> mapData = apiContext.getOperationsContext().getRemoteFetcher().getExternalGenericWithData(externalUrlCriteria, prefillingConfig.getPrefillingSearch()); + for (int i = 0; i < mapData.size(); i++) { + prefillings.get(i).setData(mapData.get(i)); + } + prefillings = prefillings.stream().filter(prefilling -> prefilling.getData() != null).collect(Collectors.toList()); + } + } + return prefillings; } public DatasetWizardModel getPrefilledDataset(String prefillId, String configId, UUID profileId) throws Exception { 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 { + PrefillingConfig prefillingConfig = configLoader.getExternalUrls().getPrefillings().get(configId); + PrefillingGet prefillingGet = prefillingConfig.getPrefillingGet(); + DescriptionTemplate descriptionTemplate = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(profileId); + return prefillingMapper.mapPrefilledEntityToDatasetWizard(data, prefillingGet, prefillingConfig.getType(), descriptionTemplate, datasetManager, licenseManager); } private Map getSingle(String url, String id) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java index 5785f1676..cf55ceaf9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java @@ -72,20 +72,7 @@ public class UnlinkEmailConfirmationManager { Credential credential = databaseRepository.getCredentialDao().asQueryable() .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); if(credential != null) { - UserInfo userTobeUnlinked = databaseRepository.getUserInfoDao().asQueryable() - .where((builder, root) -> builder.and(builder.equal(root.get("userStatus"), 1), builder.equal(root.get("name"), credential.getPublicValue()))).getSingle(); - userTobeUnlinked.setEmail(emailTobeUnlinked); - userTobeUnlinked.setUserStatus((short) 0); - databaseRepository.getUserInfoDao().createOrUpdate(userTobeUnlinked); - - credential.setUserInfo(userTobeUnlinked); - databaseRepository.getCredentialDao().createOrUpdate(credential); - - UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class) - .token(UUID.randomUUID()).user(userTobeUnlinked) - .expiresAt(Timestamp.valueOf(LocalDateTime.now().plusDays(10))).issuedAt(new Date()) - .build(); - apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); + databaseRepository.getCredentialDao().delete(credential); } } 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/DatasetMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetMapper.java index 96eae1dca..d799a4b10 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DatasetMapper.java @@ -50,7 +50,9 @@ public class DatasetMapper { elastic.setStatus(dataset.getStatus()); elastic.setDmp(dataset.getDmp().getId()); elastic.setGroup(dataset.getDmp().getGroupId()); - elastic.setGrant(dataset.getDmp().getGrant().getId()); + if (dataset.getDmp().getGrant() != null) { + elastic.setGrant(dataset.getDmp().getGrant().getId()); + } elastic.setCreated(dataset.getCreated()); elastic.setModified(dataset.getModified()); elastic.setFinalizedAt(dataset.getFinalizedAt()); @@ -74,7 +76,9 @@ public class DatasetMapper { elastic.setOrganizations(dataset.getDmp().getOrganisations().stream().map(OrganizationMapper::toElastic).collect(Collectors.toList())); } elastic.setPublic(dataset.getDmp().isPublic()); - elastic.setGrantStatus(dataset.getDmp().getGrant().getStatus()); + if (dataset.getDmp().getGrant() != null) { + elastic.setGrantStatus(dataset.getDmp().getGrant().getStatus()); + } elastic.setFormData(datasetManager.getWordDocumentText(dataset)); return elastic; 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/elastic/DmpMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DmpMapper.java index cd0961ae5..a1b10170a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DmpMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/elastic/DmpMapper.java @@ -37,7 +37,9 @@ public class DmpMapper { elastic.setCollaborators(dmp.getUsers().stream().map(user -> CollaboratorMapper.toElastic(user.getUser(), user.getRole())).collect(Collectors.toList())); } elastic.setDescription(dmp.getDescription()); - elastic.setGrant(dmp.getGrant().getId()); + if (dmp.getGrant() != null) { + elastic.setGrant(dmp.getGrant().getId()); + } elastic.setLabel(dmp.getLabel()); elastic.setPublic(dmp.isPublic()); elastic.setStatus(dmp.getStatus()); 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 9efc1e713..2cac6179c 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; @@ -25,6 +25,10 @@ import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.externaldataset.ExternalAutocompleteFieldModel; import eu.eudat.models.data.license.LicenseModel; import org.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; @@ -33,11 +37,19 @@ import java.time.format.DateTimeFormatter; import java.util.*; import java.util.stream.Collectors; +@Component public class PrefillingMapper { + private static final Logger logger = LoggerFactory.getLogger(PrefillingMapper.class); private static final ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + private final DatasetProfileManager datasetProfileManager; - public static DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, - DatasetProfile profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { + @Autowired + public PrefillingMapper(DatasetProfileManager datasetProfileManager) { + this.datasetProfileManager = datasetProfileManager; + } + + public DatasetWizardModel mapPrefilledEntityToDatasetWizard(Map prefilledEntity, PrefillingGet prefillingGet, String type, + DescriptionTemplate profile, DatasetManager datasetManager, LicenseManager licenseManager) throws Exception { DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); datasetWizardModel.setProfile(new DatasetProfileOverviewModel().fromDataModel(profile)); Dataset dataset = new Dataset(); @@ -54,7 +66,17 @@ public class PrefillingMapper { sourceValue = ((Map)sourceValue).get(sourceKey); } } - setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties, type, licenseManager); + try { + setValue(prefillingMapping, mapper.writeValueAsString(sourceValue), datasetWizardModel, parentNode, properties, type, licenseManager); + } + catch (Exception e) { + if (prefillingMapping.getSemanticTarget() != null && !prefillingMapping.getSemanticTarget().isEmpty()) { + logger.warn("Couldn't map " + prefillingMapping.getSemanticTarget()); + } + else if (prefillingMapping.getTarget() != null && !prefillingMapping.getTarget().isEmpty()) { + logger.warn("Couldn't map " + prefillingMapping.getTarget()); + } + } } for (PrefillingFixedMapping fixedMapping: prefillingGet.getFixedMappings()) { setValue(fixedMapping, fixedMapping.getValue(), datasetWizardModel, parentNode, properties, type, licenseManager); @@ -64,7 +86,7 @@ public class PrefillingMapper { return datasetWizardModel; } - private static void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map properties, String type, LicenseManager licenseManager) throws InvocationTargetException, IllegalAccessException, JsonProcessingException { + private void setValue(PrefillingMapping prefillingMapping, String value, DatasetWizardModel datasetWizardModel, JsonNode parentNode, Map properties, String type, LicenseManager licenseManager) throws InvocationTargetException, IllegalAccessException, JsonProcessingException { String trimRegex = prefillingMapping.getTrimRegex() != null ? prefillingMapping.getTrimRegex() : ""; if (!value.startsWith("\"") && !value.startsWith("[") && !value.equals("null")) { value = "\"" + value + "\""; @@ -104,7 +126,11 @@ public class PrefillingMapper { //GK: Tags Special logic if (parsedValue != null && !parsedValue.equals("null") && prefillingMapping.getTarget().equals("tags")) { parsedValue = mapper.valueToTree(parseTags(parsedValue)).toString(); - } else { + } + else if(!parsedValues.isEmpty() && prefillingMapping.getTarget().equals("tags")) { + parsedValue = mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString(); + } + else { parsedValue = mapper.valueToTree(parsedValue).toString(); } setterMethod.invoke(datasetWizardModel, mapper.readValue(parsedValue, params[0])); @@ -112,11 +138,11 @@ public class PrefillingMapper { throw e; } } else { - List nodes = JsonSearcher.findNodes(parentNode, "schematics", "rda." + prefillingMapping.getMaDmpTarget()); + List nodes = JsonSearcher.findNodes(parentNode, "schematics", prefillingMapping.getSemanticTarget()); // zenodo prefilling customizations if(type.equals("zenodo")){ - if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){ + if(prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.data_access")){ if(parsedValue != null && parsedValue.equals("open")){ List issuedNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.issued"); if(!issuedNodes.isEmpty()){ @@ -131,7 +157,7 @@ public class PrefillingMapper { } } - if (prefillingMapping.getMaDmpTarget().equals("dataset.distribution.available_until") && parsedValue != null && !parsedValue.equals("null")) { + if (prefillingMapping.getSemanticTarget().equals("rda.dataset.distribution.available_until") && parsedValue != null && !parsedValue.equals("null")) { DateTimeFormatter formatter = DateTimeFormatter.ofPattern("uuuu-MM-dd"); LocalDate date = LocalDate.parse(parsedValue, formatter); date = date.plusYears(20); @@ -152,7 +178,12 @@ public class PrefillingMapper { } break; case TAGS: - properties.put(id, mapper.valueToTree(parseTags(parsedValue)).toString()); + if(parsedValues.isEmpty()) { + properties.put(id, mapper.valueToTree(parseTags(parsedValue)).toString()); + } + else { + properties.put(id, mapper.valueToTree(parseTags(String.join(", ", parsedValues))).toString()); + } break; case DATASET_IDENTIFIER: JSONObject datasetID = new JSONObject(); @@ -194,7 +225,7 @@ public class PrefillingMapper { } } - private static Object parseComboBoxValues(JsonNode node, List parsedValues) throws JsonProcessingException { + private Object parseComboBoxValues(JsonNode node, List parsedValues) throws JsonProcessingException { List normalizedValues = new ArrayList<>(); boolean isMultiSelect; String type = node.isArray() ? node.get(0).get("data").get("type").asText() : node.get("data").get("type").asText(); @@ -203,7 +234,13 @@ public class PrefillingMapper { AutoCompleteData autoCompleteData = mapper.treeToValue(dataNode, AutoCompleteData.class); isMultiSelect = autoCompleteData.getMultiAutoComplete(); for (String format : parsedValues) { - List result = DatasetProfileManager.getAutocomplete(autoCompleteData, format); + List result = new ArrayList<>(); + try { + result = datasetProfileManager.getAutocomplete(autoCompleteData, format); + } + catch (Exception e) { + logger.error(e.getMessage(), e); + } result = result.stream().filter(StreamDistinctBy.distinctByKey(ExternalAutocompleteFieldModel::getId)).collect(Collectors.toList()); if(!result.isEmpty()){ List tempValues = new LinkedList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java new file mode 100644 index 000000000..b26ef708a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthType.java @@ -0,0 +1,23 @@ +package eu.eudat.logic.proxy.config; + +public enum AuthType { + ; + private final String name; + + AuthType(String name) { + this.name = name; + } + + public String getName() { + return name; + } + + public static AuthType fromName(String name) { + for (AuthType authType : AuthType.values()) { + if (authType.getName().equals(name)) { + return authType; + } + } + throw new IllegalArgumentException("AuthType [" + name + "] is not supported"); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java new file mode 100644 index 000000000..149b957e2 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/AuthenticationConfiguration.java @@ -0,0 +1,57 @@ +package eu.eudat.logic.proxy.config; + +import javax.xml.bind.annotation.XmlElement; + +public class AuthenticationConfiguration { + + private String authUrl; + private String authMethod = "GET"; + private String authTokenPath; + private String authRequestBody; + private String type; + + public String getAuthUrl() { + return authUrl; + } + + @XmlElement(name = "authUrl") + public void setAuthUrl(String authUrl) { + this.authUrl = authUrl; + } + + public String getAuthMethod() { + return authMethod; + } + + @XmlElement(name = "authUrlMethod") + public void setAuthMethod(String authMethod) { + this.authMethod = authMethod; + } + + public String getAuthTokenPath() { + return authTokenPath; + } + + @XmlElement(name = "authTokenJpath") + public void setAuthTokenPath(String authTokenPath) { + this.authTokenPath = authTokenPath; + } + + public String getAuthRequestBody() { + return authRequestBody; + } + + @XmlElement(name = "authUrlBody") + public void setAuthRequestBody(String authRequestBody) { + this.authRequestBody = authRequestBody; + } + + public String getType() { + return type; + } + + @XmlElement(name = "authType") + public void setType(String type) { + this.type = type; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java index 232d619d1..f9e018555 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/UrlConfiguration.java @@ -11,6 +11,7 @@ public class UrlConfiguration { private String label; private Integer ordinal; private String url; + private boolean dataInListing; private DataUrlConfiguration data; private String type; private String paginationPath; @@ -20,6 +21,7 @@ public class UrlConfiguration { private String requestType = "GET"; private String requestBody = ""; private String filterType = "remote"; + private AuthenticationConfiguration auth; private List queries; @@ -47,6 +49,14 @@ public class UrlConfiguration { this.url = url; } + public boolean isDataInListing() { + return dataInListing; + } + @XmlElement(name = "dataInListing") + public void setDataInListing(boolean dataInListing) { + this.dataInListing = dataInListing; + } + public Integer getOrdinal() { return ordinal; } @@ -134,4 +144,13 @@ public class UrlConfiguration { public void setQueries(List queries) { this.queries = queries; } + + public AuthenticationConfiguration getAuth() { + return auth; + } + + @XmlElement(name="authentication") + public void setAuth(AuthenticationConfiguration auth) { + this.auth = auth; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java index f253f5c12..ff27f43fe 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/ConfigLoader.java @@ -3,6 +3,7 @@ package eu.eudat.logic.proxy.config.configloaders; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import eu.eudat.models.data.pid.PidLinks; import org.apache.poi.xwpf.usermodel.XWPFDocument; import java.util.List; @@ -14,5 +15,6 @@ public interface ConfigLoader { XWPFDocument getDocument(); XWPFDocument getDatasetDocument(); ConfigurableProviders getConfigurableProviders(); + PidLinks getPidLinks(); Map getKeyToSourceMap(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java index 4faa489d9..b9f7ddb0c 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/configloaders/DefaultConfigLoader.java @@ -6,6 +6,7 @@ import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; +import eu.eudat.models.data.pid.PidLinks; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -41,6 +42,7 @@ public class DefaultConfigLoader implements ConfigLoader { private XWPFDocument document; private XWPFDocument datasetDocument; private ConfigurableProviders configurableProviders; + private PidLinks pidLinks; private Map keyToSourceMap; @Autowired @@ -134,6 +136,25 @@ public class DefaultConfigLoader implements ConfigLoader { } } + private void setPidLinks() { + String filePath = environment.getProperty("configuration.pid_links"); + logger.info("Loaded also config file: " + filePath); + InputStream is = null; + try { + is = getStreamFromPath(filePath); + ObjectMapper mapper = new ObjectMapper().configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false); + this.pidLinks = mapper.readValue(is, PidLinks.class); + } catch (IOException | NullPointerException e) { + logger.error(e.getMessage(), e); + } finally { + try { + if (is != null) is.close(); + } catch (IOException e) { + logger.warn("Warning: Could not close a stream after reading from file: " + filePath, e); + } + } + } + private void setKeyToSourceMap() { String filePath = this.environment.getProperty("configuration.externalUrls"); logger.info("Loaded also config file: " + filePath); @@ -192,6 +213,14 @@ public class DefaultConfigLoader implements ConfigLoader { return configurableProviders; } + public PidLinks getPidLinks() { + if (pidLinks == null) { + pidLinks = new PidLinks(); + this.setPidLinks(); + } + return pidLinks; + } + public Map getKeyToSourceMap() { if (keyToSourceMap == null) { keyToSourceMap = new HashMap<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java index 5fee3d153..4346796af 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/DefaultPrefillingMapping.java @@ -7,7 +7,7 @@ import javax.xml.bind.annotation.XmlRootElement; public class DefaultPrefillingMapping implements PrefillingMapping{ private String source; private String target; - private String maDmpTarget; + private String semanticTarget; private String subSource; private String trimRegex; @@ -29,13 +29,13 @@ public class DefaultPrefillingMapping implements PrefillingMapping{ this.target = target; } - public String getMaDmpTarget() { - return maDmpTarget; + public String getSemanticTarget() { + return semanticTarget; } - @XmlAttribute(name = "maDmpTarget") - public void setMaDmpTarget(String maDmpTarget) { - this.maDmpTarget = maDmpTarget; + @XmlAttribute(name = "semanticTarget") + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; } public String getSubSource() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java new file mode 100644 index 000000000..d6581d250 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/GeneralUrls.java @@ -0,0 +1,31 @@ +package eu.eudat.logic.proxy.config.entities; + +import eu.eudat.logic.proxy.config.FetchStrategy; +import eu.eudat.logic.proxy.config.UrlConfiguration; + +import java.util.ArrayList; +import java.util.List; + +public class GeneralUrls extends GenericUrls{ + + List urls; + FetchStrategy fetchMode; + + public GeneralUrls() { + this.urls = new ArrayList<>(); + } + + @Override + public List getUrls() { + return urls; + } + + @Override + public FetchStrategy getFetchMode() { + return fetchMode; + } + + public void setFetchMode(FetchStrategy fetchMode) { + this.fetchMode = fetchMode; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java index 4514308f1..aa59f8386 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingFixedMapping.java @@ -6,7 +6,7 @@ import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "fixedMapping") public class PrefillingFixedMapping implements PrefillingMapping{ private String target; - private String maDmpTarget; + private String semanticTarget; private String value; public String getTarget() { @@ -18,13 +18,13 @@ public class PrefillingFixedMapping implements PrefillingMapping{ this.target = target; } - public String getMaDmpTarget() { - return maDmpTarget; + public String getSemanticTarget() { + return semanticTarget; } - @XmlAttribute(name = "maDmpTarget") - public void setMaDmpTarget(String maDmpTarget) { - this.maDmpTarget = maDmpTarget; + @XmlAttribute(name = "semanticTarget") + public void setSemanticTarget(String semanticTarget) { + this.semanticTarget = semanticTarget; } @Override diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java index 34f1ca95f..ae81f6176 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/entities/PrefillingMapping.java @@ -7,9 +7,9 @@ public interface PrefillingMapping { void setTarget(String target); - String getMaDmpTarget(); + String getSemanticTarget(); - void setMaDmpTarget(String maDmpTarget); + void setSemanticTarget(String semanticTarget); String getSubSource(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 6b9a8b9b5..92de62052 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -15,9 +15,14 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; +import org.springframework.core.ParameterizedTypeReference; import org.springframework.http.*; +import org.springframework.http.client.reactive.ReactorClientHttpConnector; +import org.springframework.http.codec.json.Jackson2JsonDecoder; import org.springframework.stereotype.Service; import org.springframework.web.client.RestTemplate; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.netty.http.client.HttpClient; import javax.xml.bind.JAXBContext; import javax.xml.bind.Unmarshaller; @@ -33,10 +38,16 @@ public class RemoteFetcher { private static final Logger logger = LoggerFactory.getLogger(RemoteFetcher.class); private ConfigLoader configLoader; + private final WebClient client; @Autowired public RemoteFetcher(ConfigLoader configLoader) { this.configLoader = configLoader; + this.client = WebClient.builder().codecs(clientCodecConfigurer -> { + clientCodecConfigurer.defaultCodecs().jackson2JsonDecoder(new Jackson2JsonDecoder(new ObjectMapper(), MediaType.APPLICATION_JSON)); + clientCodecConfigurer.defaultCodecs().maxInMemorySize(2 * ((int) Math.pow(1024, 3))); //GK: Why here??? + } + ).clientConnector(new ReactorClientHttpConnector(HttpClient.create().followRedirect(true))).build(); } @Cacheable(value = "repositories", keyGenerator = "externalUrlsKeyGenerator") @@ -179,6 +190,10 @@ public class RemoteFetcher { return getAll(urlConfigurations, fetchStrategy, externalUrlCriteria); } + public List> getExternalGenericWithData(ExternalUrlCriteria externalUrlCriteria, GenericUrls genericUrls) { + List urlConfigurations = genericUrls.getUrls(); + return getAllWithData(urlConfigurations, externalUrlCriteria); + } private List> getAll(List urlConfigs, FetchStrategy fetchStrategy, ExternalUrlCriteria externalUrlCriteria) { @@ -194,7 +209,11 @@ public class RemoteFetcher { ifFunderQueryExist(urlConfiguration, externalUrlCriteria); if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { try { - results.addAll(getAllResultsFromUrl(urlConfiguration.getUrl(), fetchStrategy, urlConfiguration.getData(), urlConfiguration.getPaginationPath(), externalUrlCriteria, urlConfiguration.getLabel(), urlConfiguration.getKey(), urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getFilterType(), urlConfiguration.getQueries())); + String auth = null; + if (urlConfiguration.getAuth() != null) { + auth = this.getAuthentication(urlConfiguration.getAuth()); + } + results.addAll(getAllResultsFromUrl(urlConfiguration.getUrl(), fetchStrategy, urlConfiguration.getData(), urlConfiguration.getPaginationPath(), externalUrlCriteria, urlConfiguration.getLabel(), urlConfiguration.getKey(), urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getFilterType(), urlConfiguration.getQueries(), auth)); } catch (Exception e) { logger.error(e.getLocalizedMessage(), e); } @@ -213,6 +232,42 @@ public class RemoteFetcher { return results; } + private String getAuthentication(AuthenticationConfiguration authenticationConfiguration) { + HttpMethod method = HttpMethod.valueOf(authenticationConfiguration.getAuthMethod()); + Map reponse = this.client.method(method).uri(authenticationConfiguration.getAuthUrl()) + .contentType(MediaType.APPLICATION_JSON) + .bodyValue(this.parseBodyString(authenticationConfiguration.getAuthRequestBody())) + .exchangeToMono(mono -> mono.bodyToMono(new ParameterizedTypeReference>() { + })).block(); + + + + return authenticationConfiguration.getType() + " " + reponse.get(authenticationConfiguration.getAuthTokenPath()); + } + + private List> getAllWithData(List urlConfigs, ExternalUrlCriteria externalUrlCriteria) { + + List> results = new LinkedList<>(); + + if (urlConfigs == null || urlConfigs.isEmpty()) { + return results; + } + + urlConfigs.sort(Comparator.comparing(UrlConfiguration::getOrdinal)); + urlConfigs.forEach(urlConfiguration -> { + ifFunderQueryExist(urlConfiguration, externalUrlCriteria); + if (urlConfiguration.getType() == null || urlConfiguration.getType().equals("External")) { + try { + results.addAll(getAllResultsFromUrlWithData(urlConfiguration.getUrl(), urlConfiguration.getData(), externalUrlCriteria, urlConfiguration.getContentType(), urlConfiguration.getFirstpage(), urlConfiguration.getRequestBody(), urlConfiguration.getRequestType(), urlConfiguration.getQueries())); + } catch (Exception e) { + logger.error(e.getLocalizedMessage(), e); + } + } + }); + return results; + + } + private void ifFunderQueryExist(UrlConfiguration urlConfiguration, ExternalUrlCriteria externalUrlCriteria) { if (urlConfiguration.getFunderQuery() != null) { if (externalUrlCriteria.getFunderId() != null && !urlConfiguration.getFunderQuery().startsWith("dmp:")) { @@ -246,7 +301,7 @@ public class RemoteFetcher { protected String replaceCriteriaOnUrl(String path, ExternalUrlCriteria externalUrlCriteria, String firstPage, List queries) { String completedPath = path; if (externalUrlCriteria.getLike() != null) { - if ((path.contains("openaire") || path.contains("orcid") || path.contains("ror")) && externalUrlCriteria.getLike().equals("")) { + if ((path.contains("openaire") || path.contains("orcid") || path.contains("ror") || path.contains("fairsharing")) && externalUrlCriteria.getLike().equals("")) { completedPath = completedPath.replaceAll("\\{like}", "*"); completedPath = completedPath.replaceAll("\\{query}", "*"); } else { @@ -271,6 +326,10 @@ public class RemoteFetcher { */ completedPath = completedPath.replace("{funderId}", funderId); } + else if(completedPath.contains("{funderId}")){ + logger.warn("FunderId is null."); + completedPath = completedPath.replace("{funderId}", " "); + } if (externalUrlCriteria.getPage() != null) { completedPath = completedPath.replace("{page}", externalUrlCriteria.getPage()); } else { @@ -298,49 +357,86 @@ public class RemoteFetcher { return completedPath; } - private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalUrlCriteria externalUrlCriteria, String tag, String key, String contentType, String firstPage, String requestBody, String requestType, String filterType, List queries) throws Exception { + private List> getAllResultsFromUrl(String path, FetchStrategy fetchStrategy, final DataUrlConfiguration jsonDataPath, final String jsonPaginationPath, ExternalUrlCriteria externalUrlCriteria, String tag, String key, String contentType, String firstPage, String requestBody, String requestType, String filterType, List queries, String auth) throws Exception { Set pages = new HashSet<>(); String replacedPath = replaceCriteriaOnUrl(path, externalUrlCriteria, firstPage, queries); String replacedBody = replaceCriteriaOnUrl(requestBody, externalUrlCriteria, firstPage, queries); - Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType); - if(filterType != null && filterType.equals("local") && (externalUrlCriteria.getLike() != null && !externalUrlCriteria.getLike().isEmpty())){ - results.setResults(results.getResults().stream() - .filter(r -> r.get("name").toLowerCase().contains(externalUrlCriteria.getLike().toLowerCase())) - .collect(Collectors.toList())); + Results results = getResultsFromUrl(replacedPath, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType, auth); + if(results != null) { + if (filterType != null && filterType.equals("local") && (externalUrlCriteria.getLike() != null && !externalUrlCriteria.getLike().isEmpty())) { + results.setResults(results.getResults().stream() + .filter(r -> r.get("name").toLowerCase().contains(externalUrlCriteria.getLike().toLowerCase())) + .collect(Collectors.toList())); + } + if (fetchStrategy == FetchStrategy.FIRST) + return results.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); + + if (results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set + for (int i = 2; i <= results.getPagination().get("pages"); i++) + pages.add(i); + + Long maxResults = configLoader.getExternalUrls().getMaxresults(); + if ((maxResults > 0) && (results.getPagination().get("count") > maxResults)) + throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); + + Optional optionalResults = pages.parallelStream() + .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType, auth)) + .filter(Objects::nonNull) + .reduce((result1, result2) -> { + result1.getResults().addAll(result2.getResults()); + return result1; + }); + Results remainingResults = optionalResults.orElseGet(Results::new); + remainingResults.getResults().addAll(results.getResults()); + + return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); } - if (fetchStrategy == FetchStrategy.FIRST) - return results == null ? new LinkedList<>() : results.getResults().stream().peek(x -> x.put("tag", tag)).peek(x -> x.put("key", key)).collect(Collectors.toList()); + else { + return new LinkedList<>(); + } + } - if (results != null && results.getPagination() != null && results.getPagination().get("pages") != null) //if has more pages, add them to the pages set - for (int i = 2; i <= results.getPagination().get("pages"); i++) - pages.add(i); + private List> getAllResultsFromUrlWithData(String path, final DataUrlConfiguration jsonDataPath, ExternalUrlCriteria externalUrlCriteria, String contentType, String firstPage, String requestBody, String requestType, List queries) { - Long maxResults = configLoader.getExternalUrls().getMaxresults(); - if ((maxResults > 0 && results != null) && (results.getPagination().get("count") > maxResults)) - throw new HugeResultSet("The submitted search query " + externalUrlCriteria.getLike() + " is about to return " + results.getPagination().get("count") + " results... Please submit a more detailed search query"); + String replacedPath = replaceCriteriaOnUrl(path, externalUrlCriteria, firstPage, queries); + String replacedBody = replaceCriteriaOnUrl(requestBody, externalUrlCriteria, firstPage, queries); - Optional optionalResults = pages.parallelStream() - .map(page -> getResultsFromUrl(path + "&page=" + page, jsonDataPath, jsonPaginationPath, contentType, replacedBody, requestType)) - .filter(Objects::nonNull) - .reduce((result1, result2) -> { - result1.getResults().addAll(result2.getResults()); - return result1; - }); - Results remainingResults = optionalResults.orElseGet(Results::new); - remainingResults.getResults().addAll(results.getResults()); + try { + RestTemplate restTemplate = new RestTemplate(); + HttpHeaders headers = new HttpHeaders(); + HttpEntity entity; + ResponseEntity response; + if (contentType != null && !contentType.isEmpty()) { + headers.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); + headers.setContentType(MediaType.valueOf(contentType)); + } + JsonNode jsonBody = new ObjectMapper().readTree(replacedBody); + entity = new HttpEntity<>(jsonBody, headers); - return remainingResults.getResults().stream().peek(x -> x.put("tag", tag)).collect(Collectors.toList()); + response = restTemplate.exchange(replacedPath, HttpMethod.valueOf(requestType), entity, String.class); + if (response.getStatusCode() == HttpStatus.OK) { + if (response.getHeaders().get("Content-Type").get(0).contains("json")) { + DocumentContext jsonContext = JsonPath.parse(response.getBody()); + return jsonContext.read(jsonDataPath.getPath()); + } + } + } + catch (Exception exception) { + logger.error(exception.getMessage(), exception); + } + + return new LinkedList<>(); } - protected Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType) { + protected Results getResultsFromUrl(String urlString, DataUrlConfiguration jsonDataPath, String jsonPaginationPath, String contentType, String requestBody, String requestType, String auth) { try { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - HttpEntity entity; + //RestTemplate restTemplate = new RestTemplate(new SimpleClientHttpRequestFactory()); + //HttpHeaders headers = new HttpHeaders(); + //HttpEntity entity; ResponseEntity response; /* * URL url = new URL(urlString.replaceAll(" ", "%20")); @@ -348,14 +444,27 @@ public class RemoteFetcher { * HttpURLConnection con = (HttpURLConnection) url.openConnection(); * con.setRequestMethod("GET"); */ - if (contentType != null && !contentType.isEmpty()) { + /* if (contentType != null && !contentType.isEmpty()) { headers.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); headers.setContentType(MediaType.valueOf(contentType)); } + if (auth != null) { + headers.set("Authorization", auth); + }*/ JsonNode jsonBody = new ObjectMapper().readTree(requestBody); - entity = new HttpEntity<>(jsonBody, headers); +// entity = new HttpEntity<>(jsonBody, headers); - response = restTemplate.exchange(urlString, HttpMethod.resolve(requestType), entity, String.class); + + response = this.client.method(HttpMethod.valueOf(requestType)).uri(urlString).headers(httpHeaders -> { + if (contentType != null && !contentType.isEmpty()) { + httpHeaders.setAccept(Collections.singletonList(MediaType.valueOf(contentType))); + httpHeaders.setContentType(MediaType.valueOf(contentType)); + } + if (auth != null) { + httpHeaders.set("Authorization", auth); + } + }).bodyValue(jsonBody).retrieve().toEntity(String.class).block(); + //response = restTemplate.exchange(urlString, HttpMethod.resolve(requestType), entity, String.class); if (response.getStatusCode() == HttpStatus.OK) { // success //do here all the parsing Results results = new Results(); @@ -363,7 +472,7 @@ public class RemoteFetcher { DocumentContext jsonContext = JsonPath.parse(response.getBody()); if (jsonDataPath.getFieldsUrlConfiguration().getPath() != null) { - results = RemoteFetcherUtils.getFromJsonWithRecursiveFetching(jsonContext, jsonDataPath, this, requestBody, requestType); + results = RemoteFetcherUtils.getFromJsonWithRecursiveFetching(jsonContext, jsonDataPath, this, requestBody, requestType, auth); } else if (jsonDataPath.getFieldsUrlConfiguration().getFirstName() != null) { results = RemoteFetcherUtils.getFromJsonWithFirstAndLastName(jsonContext, jsonDataPath); } else { @@ -485,8 +594,18 @@ public class RemoteFetcher { return null; } - - - + private String parseBodyString(String bodyString) { + String finalBodyString = bodyString; + if (bodyString.contains("{env:")) { + int index = bodyString.indexOf("{env: "); + while (index >= 0) { + int endIndex = bodyString.indexOf("}", index + 6); + String envName = bodyString.substring(index + 6, endIndex); + finalBodyString = finalBodyString.replace("{env: " + envName + "}", System.getenv(envName)); + index = bodyString.indexOf("{env: ", index + 6); + } + } + return finalBodyString; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java index 20c57356d..00bcadfa1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java @@ -28,7 +28,7 @@ public class RemoteFetcherUtils { new HashMap<>(1, 1)); } - public static Results getFromJsonWithRecursiveFetching(DocumentContext jsonContext, DataUrlConfiguration jsonDataPath, RemoteFetcher remoteFetcher, String requestBody, String requestType) { + public static Results getFromJsonWithRecursiveFetching(DocumentContext jsonContext, DataUrlConfiguration jsonDataPath, RemoteFetcher remoteFetcher, String requestBody, String requestType, String auth) { Results results = new Results(parseData(jsonContext, jsonDataPath), new HashMap<>(1, 1)); @@ -37,7 +37,7 @@ public class RemoteFetcherUtils { externalUrlCriteria.setPath(result.get("path")); externalUrlCriteria.setHost(result.get("host")); String replacedPath = remoteFetcher.replaceCriteriaOnUrl(jsonDataPath.getUrlConfiguration().getUrl(), externalUrlCriteria, jsonDataPath.getUrlConfiguration().getFirstpage(), jsonDataPath.getUrlConfiguration().getQueries()); - return remoteFetcher.getResultsFromUrl(replacedPath, jsonDataPath.getUrlConfiguration().getData(), jsonDataPath.getUrlConfiguration().getData().getPath(), jsonDataPath.getUrlConfiguration().getContentType(), requestBody, requestType); + return remoteFetcher.getResultsFromUrl(replacedPath, jsonDataPath.getUrlConfiguration().getData(), jsonDataPath.getUrlConfiguration().getData().getPath(), jsonDataPath.getUrlConfiguration().getContentType(), requestBody, requestType, auth); }).filter(Objects::nonNull).map(results1 -> results1.getResults().get(0)).collect(Collectors.toList()); return new Results(multiResults, new HashMap<>(1, 1)); } @@ -70,7 +70,13 @@ public class RemoteFetcherUtils { Object pidObj = stringObjectMap.get(value.split("\\.")[0]); if(pidObj != null){ if(pidObj instanceof Map){ - pid = ((Map) pidObj).get(value.split("\\.")[1]); + Object o = ((Map) pidObj).get(value.split("\\.")[1]); + if(o instanceof String){ + pid = (String)o; + } + else if(o instanceof Integer){ + pid = String.valueOf(o); + } } else if(pidObj instanceof List){ Object o = ((List>) pidObj).get(0).get(value.split("\\.")[1]); @@ -92,8 +98,22 @@ public class RemoteFetcherUtils { } } else { value = value.replace("'", ""); - if (stringObjectMap.containsKey(value)) { - parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + if (value.contains(".")) { + String[] parts = value.split("\\."); + Map tempMap = stringObjectMap; + for (int i = 0; i < parts.length; i++) { + if (tempMap.containsKey(parts[i])) { + if (i + 1 < parts.length) { + tempMap = (Map) tempMap.get(parts[i]); + } else { + parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(tempMap.get(parts[i]), (field.getName().equals("types") || field.getName().equals("uri")))); + } + } + } + } else { + if (stringObjectMap.containsKey(value)) { + parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + } } } } @@ -129,7 +149,8 @@ public class RemoteFetcherUtils { } } } else if (value instanceof Map) { - return ((Map)value).get("content"); + String key = ((Map)value).containsKey("$") ? "$" : "content"; + return ((Map)value).get(key); } return value != null ? value.toString() : null; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java index b6f1cc533..4c6eeb975 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java @@ -37,7 +37,9 @@ public class DMPToDepositMapper { deposit.setUsers(entity.getUsers().stream().map(DMPToDepositMapper::fromUserDMP).collect(Collectors.toSet())); deposit.setOrganisations(entity.getOrganisations().stream().map(DMPToDepositMapper::fromOrganisation).collect(Collectors.toSet())); deposit.setResearchers(entity.getResearchers().stream().map(DMPToDepositMapper::fromResearcher).collect(Collectors.toSet())); - deposit.setGrant(fromGrant(entity.getGrant())); + if (entity.getGrant() != null) { + deposit.setGrant(fromGrant(entity.getGrant())); + } deposit.setPdfFile(pdfFile); deposit.setRdaJsonFile(jsonFile); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java index 5f31b65a2..862996ea6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java @@ -3,6 +3,7 @@ package eu.eudat.logic.security.validators.configurableProvider; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.CertificateInfo; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.Saml2ConfigurableProvider; import eu.eudat.logic.utilities.builders.XmlBuilder; +import eu.eudat.models.data.saml2.AuthnRequestModel; import jakarta.xml.soap.*; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.CriteriaSet; @@ -34,7 +35,6 @@ import org.opensaml.core.xml.config.XMLObjectProviderRegistry; import org.opensaml.core.xml.io.*; import org.opensaml.core.xml.schema.*; import org.opensaml.saml.common.SAMLObject; -import org.opensaml.saml.common.SAMLObjectContentReference; import org.opensaml.saml.common.SAMLVersion; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.criterion.EntityRoleCriterion; @@ -64,8 +64,6 @@ import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory; import org.opensaml.xmlsec.signature.KeyInfo; import org.opensaml.xmlsec.signature.Signature; import org.opensaml.xmlsec.signature.X509Data; -import org.opensaml.xmlsec.signature.impl.SignatureBuilder; -import org.opensaml.xmlsec.signature.support.SignatureConstants; import org.opensaml.xmlsec.signature.support.SignatureValidator; import org.opensaml.xmlsec.signature.support.Signer; import org.slf4j.Logger; @@ -88,6 +86,7 @@ import javax.xml.transform.TransformerFactory; import javax.xml.transform.dom.DOMSource; import javax.xml.transform.stream.StreamResult; import java.io.*; +import java.net.URLEncoder; import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.security.*; @@ -794,47 +793,68 @@ public class Saml2SSOUtils { } - public static String getAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { + public static AuthnRequestModel getAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { AuthnRequest authnRequest = buildAuthnRequest(provider); + String relayState = "spId=" + provider.getSpEntityId() + "&configurableLoginId=" + provider.getConfigurableLoginId(); String authnRequestXml = null; - DocumentBuilder builder; - DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + String signatureBase64 = null; try { - Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); - if(provider.isAuthnRequestsSigned()){ - - Credential credential = getCredential(provider.getSigningCert()); - signature.setSigningCredential(credential); - signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); - signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); - - X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); - keyInfoGeneratorFactory.setEmitEntityCertificate(true); - KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); - signature.setKeyInfo(keyInfoGenerator.generate(getCredential(provider.getSigningCert()))); - - authnRequest.setSignature(signature); - } - - builder = factory.newDocumentBuilder(); + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); Document document = builder.newDocument(); Marshaller out = registry.getMarshallerFactory().getMarshaller(authnRequest); out.marshall(authnRequest, document); - if(provider.isAuthnRequestsSigned()) { - Signer.signObject(signature); - } - authnRequestXml = XmlBuilder.generateXml(document); + if(provider.isAuthnRequestsSigned()) { + signatureBase64 = buildSignature(authnRequestXml, relayState, provider.getSigningCert()); + } } catch (MarshallingException | ParserConfigurationException e) { logger.error(e.getMessage(), e); } - return authnRequestXml; + AuthnRequestModel authnRequestModel = new AuthnRequestModel(); + authnRequestModel.setAuthnRequestXml(authnRequestXml); + authnRequestModel.setRelayState(relayState); + authnRequestModel.setAlgorithm("http://www.w3.org/2000/09/xmldsig#rsa-sha1"); + authnRequestModel.setSignature(signatureBase64); + return authnRequestModel; + + } + + private static String buildSignature(String authnRequest, String relayState, CertificateInfo signingCertInfo) throws Exception{ + + KeyStore ks = (signingCertInfo.getKeyFormat().getType().equals("JKS")) ? KeyStore.getInstance("JKS") : KeyStore.getInstance("PKCS12"); + String archivePassword = signingCertInfo.getKeystorePassword(); + char[] pwdArray = (archivePassword != null) ? archivePassword.toCharArray() : "changeit".toCharArray(); + ks.load(new FileInputStream(signingCertInfo.getKeystorePath()), pwdArray); + PrivateKey pk = (PrivateKey) ks.getKey(signingCertInfo.getAlias(), signingCertInfo.getPassword().toCharArray()); + + String signAlgorithm = "http://www.w3.org/2000/09/xmldsig#rsa-sha1"; + String message = "SAMLRequest=" + URLEncoder.encode(authnRequest, "UTF-8") + + "&RelayState=" + URLEncoder.encode(relayState, "UTF-8") + + "&SigAlg=" + URLEncoder.encode(signAlgorithm, "UTF-8"); + + String signature = null; + try{ + signature = new String(org.apache.commons.codec.binary.Base64.encodeBase64(sign(message, pk)), StandardCharsets.UTF_8); + } + catch(InvalidKeyException | SignatureException | NoSuchAlgorithmException e){ + logger.error(e.getMessage(), e); + } + + return signature; + } + + private static byte[] sign(String message, PrivateKey key) throws InvalidKeyException, SignatureException, NoSuchAlgorithmException { + java.security.Signature instance = java.security.Signature.getInstance("SHA1withRSA"); + instance.initSign(key); + instance.update(message.getBytes()); + return instance.sign(); } private static AuthnRequest buildAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { 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/services/operations/authentication/AbstractAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java index 2983bfa1d..34ab8a8b4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/AbstractAuthenticationService.java @@ -8,12 +8,14 @@ import eu.eudat.exceptions.security.NullEmailException; import eu.eudat.logic.builders.entity.CredentialBuilder; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.builders.entity.UserTokenBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; import eu.eudat.models.data.loginprovider.LoginProviderUser; import eu.eudat.models.data.security.Principal; import eu.eudat.types.Authorities; +import eu.eudat.types.MetricNames; import org.json.JSONObject; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -30,10 +32,12 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer protected ApiContext apiContext; protected Environment environment; + protected MetricsManager metricsManager; - public AbstractAuthenticationService(ApiContext apiContext, Environment environment) { + public AbstractAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { this.apiContext = apiContext; this.environment = environment; + this.metricsManager = metricsManager; } protected Date addADay(Date date) { @@ -91,6 +95,7 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer if (credential == null && credentials.getUsername().equals(environment.getProperty("autouser.root.username"))) { try { credential = this.autoCreateUser(credentials.getUsername(), credentials.getSecret()); + metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL); } catch (Exception e) { logger.error(e.getMessage(), e); return null; @@ -162,7 +167,7 @@ public abstract class AbstractAuthenticationService implements AuthenticationSer role.setRole(Authorities.USER.getValue()); role.setUserInfo(userInfo); apiContext.getOperationsContext().getDatabaseRepository().getUserRoleDao().createOrUpdate(role); - + metricsManager.increaseValue(MetricNames.USERS, 1, MetricNames.TOTAL); } else { Map additionalInfo = userInfo.getAdditionalinfo() != null ? new JSONObject(userInfo.getAdditionalinfo()).toMap() : new HashMap<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java index 34fa80dc9..166188736 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/NonVerifiedUserEmailAuthenticationService.java @@ -5,6 +5,7 @@ import eu.eudat.data.entities.UserInfo; import eu.eudat.data.entities.UserRole; import eu.eudat.data.entities.UserToken; import eu.eudat.logic.builders.model.models.PrincipalBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.security.Principal; import eu.eudat.types.Authorities; @@ -19,8 +20,8 @@ import java.util.List; @Service("nonVerifiedUserAuthenticationService") public class NonVerifiedUserEmailAuthenticationService extends AbstractAuthenticationService { - public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment) { - super(apiContext, environment); + public NonVerifiedUserEmailAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { + super(apiContext, environment, metricsManager); } public Principal Touch(UserToken token) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java index dfaca0d7a..4912346c4 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/operations/authentication/VerifiedUserAuthenticationService.java @@ -10,6 +10,7 @@ import eu.eudat.logic.builders.entity.CredentialBuilder; import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.builders.entity.UserTokenBuilder; import eu.eudat.logic.builders.model.models.PrincipalBuilder; +import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.validators.TokenValidatorFactoryImpl; import eu.eudat.logic.services.ApiContext; import eu.eudat.models.data.login.Credentials; @@ -27,8 +28,8 @@ import java.util.*; @Service("verifiedUserAuthenticationService") public class VerifiedUserAuthenticationService extends AbstractAuthenticationService { - public VerifiedUserAuthenticationService(ApiContext apiContext, Environment environment) { - super(apiContext, environment); + public VerifiedUserAuthenticationService(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { + super(apiContext, environment, metricsManager); } public Principal Touch(UserToken token) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java index 3f73d4996..cde1f885a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/MailServiceImpl.java @@ -108,8 +108,11 @@ public class MailServiceImpl implements MailService { lastIndex = content.indexOf("img src=\"", lastIndex); if (lastIndex != -1) { - imagePaths.add(content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9))); - lastIndex ++; + String imagePath = content.substring(lastIndex + 9, content.indexOf("\"", lastIndex + 9)); + if (!imagePath.contains("data:image/png;base64")) { + imagePaths.add(imagePath); + } + lastIndex++; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java index 0a3d64dbe..340b7e413 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/WordBuilder.java @@ -7,11 +7,14 @@ import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; import eu.eudat.data.entities.Organisation; import eu.eudat.data.entities.Researcher; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.utilities.documents.types.ParagraphStyle; import eu.eudat.logic.utilities.interfaces.ApplierWithValue; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.models.data.components.commons.datafield.*; +import eu.eudat.models.data.pid.PidLink; +import eu.eudat.models.data.pid.PidLinks; import eu.eudat.models.data.user.components.datasetprofile.Field; import eu.eudat.models.data.user.components.datasetprofile.FieldSet; import eu.eudat.models.data.user.components.datasetprofile.Section; @@ -21,6 +24,7 @@ import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.util.Units; import org.apache.poi.xwpf.usermodel.*; import org.apache.xmlbeans.XmlCursor; +import org.apache.xmlbeans.XmlObject; import org.json.JSONArray; import org.json.JSONException; import org.jsoup.Jsoup; @@ -71,8 +75,9 @@ public class WordBuilder { private Integer indent; private final ObjectMapper mapper; private Integer imageCount; + private ConfigLoader configLoader; - public WordBuilder(Environment environment) { + public WordBuilder(Environment environment, ConfigLoader configLoader) { this.cTAbstractNum = CTAbstractNum.Factory.newInstance(); this.cTAbstractNum.setAbstractNumId(BigInteger.valueOf(1)); this.indent = 0; @@ -80,6 +85,7 @@ public class WordBuilder { this.mapper = new ObjectMapper(); this.buildOptions(environment); this.buildOptionsInTable(environment); + this.configLoader = configLoader; } private void buildOptionsInTable(Environment environment) { @@ -568,6 +574,37 @@ public class WordBuilder { return hasValue; } + private void createHypeLink(XWPFDocument mainDocumentPart, String format, String pidType, String pid, boolean hasMultiplicityItems, boolean isMultiAutoComplete){ + PidLink pidLink = this.configLoader.getPidLinks().getPidLinks().stream().filter(pl -> pl.getPid().equals(pidType)).findFirst().orElse(null); + if (pidLink != null) { + if (!hasMultiplicityItems) { + XWPFParagraph paragraph = mainDocumentPart.createParagraph(); + paragraph.setIndentFromLeft(400 * indent); + if (numId != null) { + paragraph.setNumID(numId); + } + } + if (isMultiAutoComplete) { + XWPFRun r = mainDocumentPart.getLastParagraph().createRun(); + r.setText("• "); + } + XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun(pidLink.getLink().replace("{pid}", pid)); + run.setText(format); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + run.setFontSize(11); + } + else { + String newFormat = (isMultiAutoComplete) ? "• " + format : format; + if (hasMultiplicityItems) { + mainDocumentPart.getLastParagraph().createRun().setText(newFormat); + } + else { + addParagraphContent(newFormat, mainDocumentPart, ParagraphStyle.TEXT, numId, indent); + } + } + } + private Boolean createFields(List fields, XWPFDocument mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, boolean hasMultiplicityItems) { if (createListing) this.addListing(mainDocumentPart, indent, false, false); boolean hasValue = false; @@ -607,70 +644,126 @@ public class WordBuilder { } else if (field.getViewStyle().getRenderStyle().equals("combobox") && field.getData() instanceof AutoCompleteData) { format = getCommaSeparatedFormatsFromJson(format, "label"); } - boolean isResearcher = field.getViewStyle().getRenderStyle().equals("researchers"); - if(format != null && !format.isEmpty()){ - Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); - boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; - boolean arrayStringFormat = format.charAt(0) == '['; - if(arrayStringFormat || isMultiAutoComplete){ - List values = (arrayStringFormat) ? Arrays.asList(format.substring(1, format.length() - 1).split(",[ ]*")) : Arrays.asList(format.split(",[ ]*")); - if(values.size() > 1) { - boolean orcidResearcher; - for (String val : values) { - orcidResearcher = false; - String orcId = null; - if(isResearcher && val.contains("orcid:")){ - orcId = val.substring(val.indexOf(':') + 1, val.indexOf(')')); - val = val.substring(0, val.indexOf(':') + 1) + " "; - orcidResearcher = true; - } - format = "• " + val; + switch (field.getViewStyle().getRenderStyle()) { + case "organizations": + case "externalDatasets": + case "publications": + if(format != null && !format.isEmpty()){ + Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); + boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; + if(!isMultiAutoComplete){ + Map value = mapper.readValue((String)field.getValue(), Map.class); if(hasMultiplicityItems){ - mainDocumentPart.getLastParagraph().createRun().setText(format); - if(orcidResearcher){ - XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun("https://orcid.org/" + orcId); - run.setText(orcId); - run.setUnderline(UnderlinePatterns.SINGLE); - run.setColor("0000FF"); - mainDocumentPart.getLastParagraph().createRun().setText(")"); - } + createHypeLink(mainDocumentPart, format, value.get("pidTypeField"), value.get("pid"), true, false); hasMultiplicityItems = false; } else{ - XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); - if(orcidResearcher){ - XWPFHyperlinkRun run = paragraph.createHyperlinkRun("https://orcid.org/" + orcId); - run.setText(orcId); - run.setUnderline(UnderlinePatterns.SINGLE); - run.setColor("0000FF"); - paragraph.createRun().setText(")"); - } - if (paragraph != null) { -// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); -// number.setVal(BigInteger.valueOf(indent)); - hasValue = true; + createHypeLink(mainDocumentPart, format, value.get("pidTypeField"), value.get("pid"), false, false); + } + } + else{ + mapper.configure(DeserializationFeature.ACCEPT_SINGLE_VALUE_AS_ARRAY, true); + List> values = new ArrayList<>(); + try { + values = Arrays.asList(mapper.readValue(field.getValue().toString(), HashMap[].class)); + } + catch (Exception e) { + Map map = new HashMap<>(); + map.put("label", field.getValue()); + values.add(map); + } + if (values.size() > 1) { + for (Map value : values) { + if(hasMultiplicityItems){ + createHypeLink(mainDocumentPart, (String) value.get("name"), (String) value.get("pidTypeField"), (String) value.get("pid"), true, true); + hasMultiplicityItems = false; + } + else{ + createHypeLink(mainDocumentPart, (String) value.get("name"), (String) value.get("pidTypeField"), (String) value.get("pid"), false, true); + } } } - format = null; + else if(values.size() == 1){ + if(hasMultiplicityItems){ + createHypeLink(mainDocumentPart, format, (String) values.get(0).get("pidTypeField"), (String) values.get(0).get("pid"), true, false); + hasMultiplicityItems = false; + } + else{ + createHypeLink(mainDocumentPart, format, (String) values.get(0).get("pidTypeField"), (String) values.get(0).get("pid"), false, false); + } + } + } + hasValue = true; + } + break; + default: + boolean isResearcher = field.getViewStyle().getRenderStyle().equals("researchers"); + if(format != null && !format.isEmpty()){ + Object hasMultiAutoComplete = mapper.convertValue(field.getData(), Map.class).get("multiAutoComplete"); + boolean isMultiAutoComplete = hasMultiAutoComplete != null && (boolean)hasMultiAutoComplete; + boolean arrayStringFormat = format.charAt(0) == '['; + if(arrayStringFormat || isMultiAutoComplete){ + List values = (arrayStringFormat) ? Arrays.asList(format.substring(1, format.length() - 1).split(",[ ]*")) : Arrays.asList(format.split(",[ ]*")); + if(values.size() > 1) { + boolean orcidResearcher; + for (String val : values) { + orcidResearcher = false; + String orcId = null; + if(isResearcher && val.contains("orcid:")){ + orcId = val.substring(val.indexOf(':') + 1, val.indexOf(')')); + val = val.substring(0, val.indexOf(':') + 1) + " "; + orcidResearcher = true; + } + format = "• " + val; + if(hasMultiplicityItems){ + mainDocumentPart.getLastParagraph().createRun().setText(format); + if(orcidResearcher){ + XWPFHyperlinkRun run = mainDocumentPart.getLastParagraph().createHyperlinkRun("https://orcid.org/" + orcId); + run.setText(orcId); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + mainDocumentPart.getLastParagraph().createRun().setText(")"); + } + hasMultiplicityItems = false; + } + else{ + XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); + if(orcidResearcher){ + XWPFHyperlinkRun run = paragraph.createHyperlinkRun("https://orcid.org/" + orcId); + run.setText(orcId); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + paragraph.createRun().setText(")"); + } + if (paragraph != null) { +// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); +// number.setVal(BigInteger.valueOf(indent)); + hasValue = true; + } + } + format = null; + } + } + else if(values.size() == 1){ + format = values.get(0); + } } } - else if(values.size() == 1){ - format = values.get(0); + if (format != null) { + if (hasMultiplicityItems) { + mainDocumentPart.getLastParagraph().createRun().setText(format); + hasMultiplicityItems = false; + hasValue = true; + } + else { + XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); + if (paragraph != null) { +// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); +// number.setVal(BigInteger.valueOf(indent)); + hasValue = true; + } + } } - } - } - if(hasMultiplicityItems && format != null){ - mainDocumentPart.getLastParagraph().createRun().setText(format); - hasMultiplicityItems = false; - hasValue = true; - } - else{ - XWPFParagraph paragraph = addParagraphContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent); - if (paragraph != null) { -// CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); -// number.setVal(BigInteger.valueOf(indent)); - hasValue = true; - } } } } catch (IOException e) { @@ -881,7 +974,7 @@ public class WordBuilder { // logger.info("Reverting to custom parsing"); identifierData = customParse(field.getValue().toString()); } - return "id: " + identifierData.get("identifier") + ", Validation Type: " + identifierData.get("type"); + return "id: " + identifierData.get("identifier") + ", Type: " + identifierData.get("type"); } return ""; } @@ -927,60 +1020,44 @@ public class WordBuilder { int descrParPos = -1; XWPFParagraph descrPar = null; for(XWPFParagraph p: document.getParagraphs()){ - List runs = p.getRuns(); - if(runs != null){ - for(XWPFRun r : runs){ - String text = r.getText(0); - if(text != null){ - if(text.contains("{ARGOS.DMP.TITLE}")) { - text = text.replace("{ARGOS.DMP.TITLE}", dmpEntity.getLabel()); - r.setText(text, 0); - } else if(text.contains("{ARGOS.DMP.VERSION}")) { - text = text.replace("{ARGOS.DMP.VERSION}", "Version " + dmpEntity.getVersion()); - r.setText(text, 0); - } else if(datasetEntity != null && text.contains("{ARGOS.DATASET.TITLE}")) { - text = text.replace("{ARGOS.DATASET.TITLE}", datasetEntity.getLabel()); - r.setText(text, 0); -// } else if(text.equals("Description") && ((!isDataset && (dmpEntity == null || dmpEntity.getDescription() != null)) || (isDataset && (datasetEntity == null || datasetEntity.getDescription() == null)))) { -// r.setText("", 0); - } else if((dmpEntity != null && text.contains("{ARGOS.DMP.DESCRIPTION}") && !isDataset) || (datasetEntity != null && text.contains("{ARGOS.DATASET.DESCRIPTION}") && isDataset)) { - descrParPos = parPos; - descrPar = p; - if(dmpEntity != null && !isDataset) { - text = text.replace("{ARGOS.DMP.DESCRIPTION}", ""); - } else if(datasetEntity != null && isDataset) { - text = text.replace("{ARGOS.DATASET.DESCRIPTION}", ""); - } - r.setText(text, 0); - } else if(text.equals("{ARGOS.DMP.RESEARCHERS}")) { - String researchersNames = ""; - Set researchers = dmpEntity.getResearchers(); - int i = 0; - for(Researcher researcher : researchers){ - i++; - researchersNames += researcher.getLabel() + (i < researchers.size() ? ", " : ""); - } - text = text.replace("{ARGOS.DMP.RESEARCHERS}", researchersNames); - r.setText(text, 0); - r.setFontSize(17); - } else if(text.equals("{ARGOS.DMP.ORGANIZATIONS}")) { - String organisationsNames = ""; - Set organisations = dmpEntity.getOrganisations(); - int i = 0; - for(Organisation organisation : organisations){ - i++; - organisationsNames += organisation.getLabel() + (i < organisations.size() ? ", " : ""); - } - text = text.replace("{ARGOS.DMP.ORGANIZATIONS}", organisationsNames); - r.setText(text, 0); - r.setFontSize(17); - } - } - } - } - parPos++; - } + if( dmpEntity != null) { + this.replaceTextSegment(p, "'{ARGOS.DMP.TITLE}'", dmpEntity.getLabel()); + this.replaceTextSegment(p, "'{ARGOS.DMP.VERSION}'", "Version " + dmpEntity.getVersion()); + } + if( datasetEntity != null) { + this.replaceTextSegment(p, "'{ARGOS.DATASET.TITLE}'", datasetEntity.getLabel()); + } + + String researchersNames = ""; + Set researchers = dmpEntity.getResearchers(); + int i = 0; + for(Researcher researcher : researchers){ + i++; + researchersNames += researcher.getLabel() + (i < researchers.size() ? ", " : ""); + } + this.replaceTextSegment(p, "'{ARGOS.DMP.RESEARCHERS}'", researchersNames, 15); + + String organisationsNames = ""; + Set organisations = dmpEntity.getOrganisations(); + i = 0; + for(Organisation organisation : organisations){ + i++; + organisationsNames += organisation.getLabel() + (i < organisations.size() ? ", " : ""); + } + this.replaceTextSegment(p, "'{ARGOS.DMP.ORGANIZATIONS}'", organisationsNames, 15); + + if(this.textSegmentExists(p,"'{ARGOS.DMP.DESCRIPTION}'")) { + descrParPos = parPos; + descrPar = p; + this.replaceTextSegment(p, "'{ARGOS.DMP.DESCRIPTION}'", ""); + } + if(this.textSegmentExists(p,"'{ARGOS.DATASET.DESCRIPTION}'")) { + descrParPos = parPos; + descrPar = p; + this.replaceTextSegment(p, "'{ARGOS.DATASET.DESCRIPTION}'", ""); + } + } if((descrParPos != -1) && (dmpEntity!=null) && (dmpEntity.getDescription() != null) && !isDataset) { XmlCursor cursor = descrPar.getCTP().newCursor(); cursor.toNextSibling(); @@ -1000,16 +1077,16 @@ public class WordBuilder { XWPFTable tbl = document.getTables().get(0); Iterator it = tbl.getRows().iterator(); it.next(); // skip first row - if(it.hasNext()){ + if(it.hasNext() && dmpEntity.getGrant() != null){ XWPFParagraph p = it.next().getCell(0).getParagraphs().get(0); XWPFRun run = p.createRun(); run.setText(dmpEntity.getGrant().getFunder().getLabel()); - run.setFontSize(17); + run.setFontSize(15); p.setAlignment(ParagraphAlignment.CENTER); } it = tbl.getRows().iterator(); it.next(); - if(it.hasNext()){ + if(it.hasNext() && dmpEntity.getGrant() != null){ XWPFParagraph p = it.next().getCell(1).getParagraphs().get(0); XWPFRun run = p.createRun(); String text = dmpEntity.getGrant().getLabel(); @@ -1019,7 +1096,7 @@ public class WordBuilder { text += parts.length > 1 ? "/ No "+parts[parts.length - 1] : ""; } run.setText(text); - run.setFontSize(17); + run.setFontSize(15); p.setAlignment(ParagraphAlignment.CENTER); } } @@ -1027,43 +1104,165 @@ public class WordBuilder { public void fillFooter(DMP dmpEntity, Dataset datasetEntity, XWPFDocument document, boolean isDataset) { document.getFooterList().forEach(xwpfFooter -> { List runs = xwpfFooter.getParagraphs().get(0).getRuns(); - if(runs != null){ - for(XWPFRun r : runs){ - String text = r.getText(0); - if(text != null){ - if(text.contains("{ARGOS.DMP.TITLE}")){ - text = text.replace("{ARGOS.DMP.TITLE}", dmpEntity.getLabel()); - r.setText(text, 0); - } - if(text.contains("{ARGOS.DATASET.TITLE}") && datasetEntity != null){ - text = text.replace("{ARGOS.DATASET.TITLE}", datasetEntity.getLabel()); - r.setText(text, 0); - } - if(text.contains("{ARGOS.DMP.LICENSE}")){ - try{ - Map license = ((Map) mapper.readValue(dmpEntity.getExtraProperties(), Map.class).get("license")); - text = text.replace("{ARGOS.DMP.LICENSE}", license.get("pid")); - } - catch (JsonProcessingException | NullPointerException e){ - text = text.replace("{ARGOS.DMP.LICENSE}", "License: -"); - } - r.setText(text, 0); - } - if(text.contains("{ARGOS.DMP.DOI}")){ - if(dmpEntity.getDois() != null && !dmpEntity.getDois().isEmpty()) - text = text.replace("{ARGOS.DMP.DOI}", dmpEntity.getDois().iterator().next().getDoi()); - else - text = text.replace("{ARGOS.DMP.DOI}", "-"); - r.setText(text, 0); - } - if(text.contains("{ARGOS.DMP.LAST_MODIFIED}")){ - DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); - text = text.replace("{ARGOS.DMP.LAST_MODIFIED}", formatter.format(dmpEntity.getModified())); - r.setText(text, 0); - } + for(XWPFParagraph p : xwpfFooter.getParagraphs()){ + if(p != null){ + if( dmpEntity != null) { + this.replaceTextSegment(p, "'{ARGOS.DMP.TITLE}'", dmpEntity.getLabel()); } + if( datasetEntity != null) { + this.replaceTextSegment(p, "'{ARGOS.DATASET.TITLE}'", datasetEntity.getLabel()); + } + Map license = null; + try { + license = ((Map) mapper.readValue(dmpEntity.getExtraProperties(), Map.class).get("license")); + if (license != null && license.get("pid") != null) { + this.replaceTextSegment(p, "'{ARGOS.DMP.LICENSE}'", license.get("pid")); + } else { + this.replaceTextSegment(p, "'{ARGOS.DMP.LICENSE}'", "License: -"); + } + } catch (JsonProcessingException e) { + this.replaceTextSegment(p, "'{ARGOS.DMP.LICENSE}'", "License: -"); + } + if(dmpEntity.getDois() != null && !dmpEntity.getDois().isEmpty()) { + this.replaceTextSegment(p, "'{ARGOS.DMP.DOI}'", dmpEntity.getDois().iterator().next().getDoi()); + } else { + this.replaceTextSegment(p, "'{ARGOS.DMP.DOI}'", "-"); + } + DateFormat formatter = new SimpleDateFormat("dd/MM/yyyy"); + this.replaceTextSegment(p, "'{ARGOS.DMP.LAST_MODIFIED}'", formatter.format(dmpEntity.getModified())); } } }); } + + private boolean textSegmentExists(XWPFParagraph paragraph, String textToFind) { + TextSegment foundTextSegment = null; + PositionInParagraph startPos = new PositionInParagraph(0, 0, 0); + while((foundTextSegment = this.searchText(paragraph, textToFind, startPos)) != null) { + return true; + } + return false; + } + + private void replaceTextSegment(XWPFParagraph paragraph, String textToFind, String replacement) { + this.replaceTextSegment(paragraph, textToFind, replacement, null); + } + + private void replaceTextSegment(XWPFParagraph paragraph, String textToFind, String replacement, Integer fontSize) { + TextSegment foundTextSegment = null; + PositionInParagraph startPos = new PositionInParagraph(0, 0, 0); + while((foundTextSegment = this.searchText(paragraph, textToFind, startPos)) != null) { // search all text segments having text to find + + System.out.println(foundTextSegment.getBeginRun()+":"+foundTextSegment.getBeginText()+":"+foundTextSegment.getBeginChar()); + System.out.println(foundTextSegment.getEndRun()+":"+foundTextSegment.getEndText()+":"+foundTextSegment.getEndChar()); + + // maybe there is text before textToFind in begin run + XWPFRun beginRun = paragraph.getRuns().get(foundTextSegment.getBeginRun()); + String textInBeginRun = beginRun.getText(foundTextSegment.getBeginText()); + String textBefore = textInBeginRun.substring(0, foundTextSegment.getBeginChar()); // we only need the text before + + // maybe there is text after textToFind in end run + XWPFRun endRun = paragraph.getRuns().get(foundTextSegment.getEndRun()); + String textInEndRun = endRun.getText(foundTextSegment.getEndText()); + String textAfter = textInEndRun.substring(foundTextSegment.getEndChar() + 1); // we only need the text after + + if (foundTextSegment.getEndRun() == foundTextSegment.getBeginRun()) { + textInBeginRun = textBefore + replacement + textAfter; // if we have only one run, we need the text before, then the replacement, then the text after in that run + } else { + textInBeginRun = textBefore + replacement; // else we need the text before followed by the replacement in begin run + endRun.setText(textAfter, foundTextSegment.getEndText()); // and the text after in end run + } + + beginRun.setText(textInBeginRun, foundTextSegment.getBeginText()); + if (fontSize != null) { + beginRun.setFontSize(fontSize); + } + // runs between begin run and end run needs to be removed + for (int runBetween = foundTextSegment.getEndRun() - 1; runBetween > foundTextSegment.getBeginRun(); runBetween--) { + paragraph.removeRun(runBetween); // remove not needed runs + } + + } + } + + /** + * this methods parse the paragraph and search for the string searched. + * If it finds the string, it will return true and the position of the String + * will be saved in the parameter startPos. + * + * @param searched + * @param startPos + */ + private TextSegment searchText(XWPFParagraph paragraph, String searched, PositionInParagraph startPos) { + int startRun = startPos.getRun(), + startText = startPos.getText(), + startChar = startPos.getChar(); + int beginRunPos = 0, candCharPos = 0; + boolean newList = false; + + //CTR[] rArray = paragraph.getRArray(); //This does not contain all runs. It lacks hyperlink runs for ex. + java.util.List runs = paragraph.getRuns(); + + int beginTextPos = 0, beginCharPos = 0; //must be outside the for loop + + //for (int runPos = startRun; runPos < rArray.length; runPos++) { + for (int runPos = startRun; runPos < runs.size(); runPos++) { + //int beginTextPos = 0, beginCharPos = 0, textPos = 0, charPos; //int beginTextPos = 0, beginCharPos = 0 must be outside the for loop + int textPos = 0, charPos; + //CTR ctRun = rArray[runPos]; + CTR ctRun = runs.get(runPos).getCTR(); + XmlCursor c = ctRun.newCursor(); + c.selectPath("./*"); + try { + while (c.toNextSelection()) { + XmlObject o = c.getObject(); + if (o instanceof CTText) { + if (textPos >= startText) { + String candidate = ((CTText) o).getStringValue(); + if (runPos == startRun) { + charPos = startChar; + } else { + charPos = 0; + } + + for (; charPos < candidate.length(); charPos++) { + if ((candidate.charAt(charPos) == searched.charAt(0)) && (candCharPos == 0)) { + beginTextPos = textPos; + beginCharPos = charPos; + beginRunPos = runPos; + newList = true; + } + if (candidate.charAt(charPos) == searched.charAt(candCharPos)) { + if (candCharPos + 1 < searched.length()) { + candCharPos++; + } else if (newList) { + TextSegment segment = new TextSegment(); + segment.setBeginRun(beginRunPos); + segment.setBeginText(beginTextPos); + segment.setBeginChar(beginCharPos); + segment.setEndRun(runPos); + segment.setEndText(textPos); + segment.setEndChar(charPos); + return segment; + } + } else { + candCharPos = 0; + } + } + } + textPos++; + } else if (o instanceof CTProofErr) { + c.removeXml(); + } else if (o instanceof CTRPr) { + //do nothing + } else { + candCharPos = 0; + } + } + } finally { + c.dispose(); + } + } + return null; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java index 60f2da9e1..d1b849775 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/ExportXmlBuilderDatasetProfile.java @@ -36,6 +36,8 @@ public class ExportXmlBuilderDatasetProfile { Element pages = (Element)xmlDoc.getFirstChild(); pages.setAttribute("description", datasetProfile.getDescription()); pages.setAttribute("language", datasetProfile.getLanguage()); + pages.setAttribute("type", datasetProfile.getType()); + pages.setAttribute("enablePrefilling", String.valueOf(datasetProfile.isEnablePrefilling())); String xml = XmlBuilder.generateXml(xmlDoc); writer.write(xml); writer.close(); 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..36d917879 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; @@ -12,6 +14,8 @@ public class DatasetProfile { private String description; private String language; + private String type; + private boolean enablePrefilling; private List page; @@ -42,12 +46,32 @@ public class DatasetProfile { this.language = language; } + @XmlAttribute(name = "type") + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + @XmlAttribute(name = "enablePrefilling") + public boolean isEnablePrefilling() { + return enablePrefilling; + } + + public void setEnablePrefilling(boolean enablePrefilling) { + this.enablePrefilling = enablePrefilling; + } + 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); + newDatasetEntityProfile.setType(type); + newDatasetEntityProfile.setEnablePrefilling(enablePrefilling); List pagesDatasetEntity = new LinkedList<>(); List sectionDatasetEntity = new LinkedList<>(); for (Page xmlPage: page) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpBlueprint.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpBlueprint.java new file mode 100644 index 000000000..478a3127a --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpBlueprint.java @@ -0,0 +1,46 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml; + +import eu.eudat.logic.utilities.builders.XmlBuilder; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint; +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Section; +import eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel; +import org.springframework.core.env.Environment; +import org.w3c.dom.Document; +import org.w3c.dom.Element; + +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileWriter; +import java.io.IOException; +import java.util.UUID; + +public class ExportXmlBuilderDmpBlueprint { + + + public File build(DataManagementPlanBlueprintListingModel dmpProfile, Environment environment) throws IOException { + + File xmlFile = new File(environment.getProperty("temp.temp") + UUID.randomUUID() + ".xml"); + BufferedWriter writer = new BufferedWriter(new FileWriter(xmlFile, true)); + Document xmlDoc = XmlBuilder.getDocument(); + Element root = xmlDoc.createElement("root"); + Element definition = xmlDoc.createElement("definition"); +// Element root = xmlDoc.createElement(dmpProfile.getLabel()); + definition.appendChild(createDefinition(dmpProfile.getDefinition(), xmlDoc)); + root.appendChild(definition); + xmlDoc.appendChild(root); + String xml = XmlBuilder.generateXml(xmlDoc); + writer.write(xml); + writer.close(); + return xmlFile; + } + + public Element createDefinition(DataManagementPlanBlueprint dmpDefinition, Document doc) { + Element sections = doc.createElement("sections"); + for (Section section : dmpDefinition.getSections()) { + sections.appendChild(section.toXml(doc)); + } + return sections; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpProfile.java deleted file mode 100644 index 212facc14..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ExportXmlBuilderDmpProfile.java +++ /dev/null @@ -1,56 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml; - -import eu.eudat.logic.utilities.builders.XmlBuilder; - -import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile; -import eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel; -import org.springframework.core.env.Environment; -import org.w3c.dom.Document; -import org.w3c.dom.Element; - -import java.io.BufferedWriter; -import java.io.File; -import java.io.FileWriter; -import java.io.IOException; -import java.util.UUID; - -public class ExportXmlBuilderDmpProfile { - - - public File build(DataManagementPlanProfileListingModel dmpProfile, Environment environment) throws IOException { - - File xmlFile = new File(environment.getProperty("temp.temp") + UUID.randomUUID() + ".xml"); - BufferedWriter writer = new BufferedWriter(new FileWriter(xmlFile, true)); - Document xmlDoc = XmlBuilder.getDocument(); - Element root = xmlDoc.createElement("root"); - Element definition = xmlDoc.createElement("definition"); -// Element root = xmlDoc.createElement(dmpProfile.getLabel()); - definition.appendChild(createDefinition(dmpProfile.getDefinition(), xmlDoc)); - root.appendChild(definition); - xmlDoc.appendChild(root); - String xml = XmlBuilder.generateXml(xmlDoc); - writer.write(xml); - writer.close(); - return xmlFile; - } - - public Element createDefinition(DataManagementPlanProfile dmpDefinition, Document element) { - Element fields = element.createElement("fieldSets"); - dmpDefinition.getFields().forEach(item -> { - Element field = element.createElement("field"); - field.setAttribute("id", "" + item.getId()); - field.setAttribute("type", "" + item.getType()); - field.setAttribute("dataType", "" + item.getDataType()); - field.setAttribute("required", "" + item.getRequired()); - field.setAttribute("label", "" + item.getLabel()); - if(item.getValue()!=null) { - Element value = element.createElement("value"); - value.setAttribute("value", ""+item.getValue()); - field.appendChild(value); - } - fields.appendChild(field); - }); - return fields; - } - -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpBlueprint.java similarity index 57% rename from dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpProfile.java rename to dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpBlueprint.java index 7962beb51..3f4628787 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/ImportXmlBuilderDmpBlueprint.java @@ -1,6 +1,6 @@ package eu.eudat.logic.utilities.documents.xml.dmpXml; -import eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel.DmpProfile; +import eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel.DmpBlueprint; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -10,16 +10,16 @@ import javax.xml.bind.Unmarshaller; import java.io.File; import java.io.IOException; -public class ImportXmlBuilderDmpProfile { - private static final Logger logger = LoggerFactory.getLogger(ImportXmlBuilderDmpProfile.class); +public class ImportXmlBuilderDmpBlueprint { + private static final Logger logger = LoggerFactory.getLogger(ImportXmlBuilderDmpBlueprint.class); - public DmpProfile build(File xmlFile) throws IOException { - DmpProfile dmpProfile = new DmpProfile(); + public DmpBlueprint build(File xmlFile) throws IOException { + DmpBlueprint dmpProfile = new DmpBlueprint(); JAXBContext jaxbContext = null; try { - jaxbContext = JAXBContext.newInstance(DmpProfile.class); + jaxbContext = JAXBContext.newInstance(DmpBlueprint.class); Unmarshaller unmarshaller = jaxbContext.createUnmarshaller(); - dmpProfile = (DmpProfile) unmarshaller.unmarshal(xmlFile); + dmpProfile = (DmpBlueprint) unmarshaller.unmarshal(xmlFile); } catch (JAXBException e) { logger.error(e.getMessage(), e); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplate.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplate.java new file mode 100644 index 000000000..d36355d40 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplate.java @@ -0,0 +1,73 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.UUID; + +@XmlRootElement(name = "descriptionTemplate") +public class DescriptionTemplate { + + private String id; + private String descriptionTemplateId; + private String label; + private Integer minMultiplicity; + private Integer maxMultiplicity; + + @XmlAttribute(name = "id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @XmlAttribute(name = "descriptionTemplateId") + public String getDescriptionTemplateId() { + return descriptionTemplateId; + } + + public void setDescriptionTemplateId(String descriptionTemplateId) { + this.descriptionTemplateId = descriptionTemplateId; + } + + @XmlAttribute(name = "label") + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @XmlAttribute(name = "minMultiplicity") + public Integer getMinMultiplicity() { + return minMultiplicity; + } + + public void setMinMultiplicity(Integer minMultiplicity) { + this.minMultiplicity = minMultiplicity; + } + + @XmlAttribute(name = "maxMultiplicity") + public Integer getMaxMultiplicity() { + return maxMultiplicity; + } + + public void setMaxMultiplicity(Integer maxMultiplicity) { + this.maxMultiplicity = maxMultiplicity; + } + + public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DescriptionTemplate toDmpBlueprintCompositeModel() { + eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DescriptionTemplate descriptionTemplate = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DescriptionTemplate(); + descriptionTemplate.setId(UUID.fromString(this.id)); + descriptionTemplate.setDescriptionTemplateId(UUID.fromString(this.descriptionTemplateId)); + descriptionTemplate.setLabel(this.label); + descriptionTemplate.setMinMultiplicity(this.minMultiplicity); + descriptionTemplate.setMaxMultiplicity(this.maxMultiplicity); + return descriptionTemplate; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplates.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplates.java new file mode 100644 index 000000000..e4f9390d3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DescriptionTemplates.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "descriptionTemplates") +public class DescriptionTemplates { + + private List descriptionTemplates; + + @XmlElement(name = "descriptionTemplate") + public List getDescriptionTemplates() { + return descriptionTemplates; + } + public void setDescriptionTemplates(List descriptionTemplates) { + this.descriptionTemplates = descriptionTemplates; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprint.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprint.java new file mode 100644 index 000000000..ecb06cb71 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprint.java @@ -0,0 +1,35 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import eu.eudat.data.entities.DMPProfile; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.Date; + +@XmlRootElement(name = "root") +public class DmpBlueprint { + + private DmpBlueprintDefinition dmpBlueprintDefinition; + + @XmlElement(name = "definition") + public DmpBlueprintDefinition getDmpBlueprintDefinition() { + return dmpBlueprintDefinition; + } + + public void setDmpBlueprintDefinition(DmpBlueprintDefinition dmpBlueprintDefinition) { + this.dmpBlueprintDefinition = dmpBlueprintDefinition; + } + + public eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel toDmpProfileCompositeModel(String label) { + eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel dmpProfileModel = new eu.eudat.models.data.listingmodels.DataManagementPlanBlueprintListingModel(); + dmpProfileModel.setLabel(label); + dmpProfileModel.setStatus(DMPProfile.Status.SAVED.getValue()); + dmpProfileModel.setCreated(new Date()); + dmpProfileModel.setModified(new Date()); + if (this.dmpBlueprintDefinition != null) { + dmpProfileModel.setDefinition(this.dmpBlueprintDefinition.toDmpBlueprintCompositeModel()); + } + return dmpProfileModel; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprintDefinition.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprintDefinition.java new file mode 100644 index 000000000..d3e8218a2 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/DmpBlueprintDefinition.java @@ -0,0 +1,34 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.LinkedList; +import java.util.List; + +@XmlRootElement(name = "definition") +public class DmpBlueprintDefinition { + + private Sections sections; + + @XmlElement(name = "sections") + public Sections getSections() { + return sections; + } + public void setSections(Sections sections) { + this.sections = sections; + } + + + public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint toDmpBlueprintCompositeModel() { + eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint dmpBlueprint = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanBlueprint(); + List dmpBlueprintSections = new LinkedList<>(); + if (this.sections != null && this.sections.getSections() != null) { + for (Section section : this.sections.getSections()) { + dmpBlueprintSections.add(section.toDmpBlueprintCompositeModel()); + } + } + dmpBlueprint.setSections(dmpBlueprintSections); + return dmpBlueprint; + } + +} \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraField.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraField.java new file mode 100644 index 000000000..004b3c74d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraField.java @@ -0,0 +1,96 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.UUID; + +@XmlRootElement(name = "extraField") +public class ExtraField { + + private String id; + private int type; + private String label; + private String placeholder; + private String description; + private int ordinal; + private boolean required; + + @XmlAttribute(name = "id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @XmlAttribute(name = "type") + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + @XmlAttribute(name = "label") + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @XmlAttribute(name = "placeholder") + public String getPlaceholder() { + return placeholder; + } + + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + @XmlAttribute(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @XmlAttribute(name = "ordinal") + public int getOrdinal() { + return ordinal; + } + + public void setOrdinal(int ordinal) { + this.ordinal = ordinal; + } + + @XmlAttribute(name = "required") + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } + + public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel toDmpBlueprintCompositeModel() { + eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel systemField = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel(); + systemField.setId(UUID.fromString(this.id)); + systemField.setCategory(FieldCategory.EXTRA); + systemField.setType(this.type); + systemField.setLabel(this.label); + systemField.setPlaceholder(this.placeholder); + systemField.setDescription(this.description); + systemField.setOrdinal(this.ordinal); + systemField.setRequired(this.required); + return systemField; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraFields.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraFields.java new file mode 100644 index 000000000..2a3d12d6f --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/ExtraFields.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "extraFields") +public class ExtraFields { + + private List extraFields; + + @XmlElement(name = "extraField") + public List getExtraFields() { + return extraFields; + } + public void setExtraFields(List extraFields) { + this.extraFields = extraFields; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Section.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Section.java new file mode 100644 index 000000000..551302325 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Section.java @@ -0,0 +1,123 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.LinkedList; +import java.util.List; +import java.util.UUID; + +@XmlRootElement(name = "section") +public class Section { + + private String id; + private String label; + private String description; + private int ordinal; + private SystemFields systemFields; + private ExtraFields extraFields; + private boolean hasTemplates; + private DescriptionTemplates descriptionTemplates; + + @XmlAttribute(name = "id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @XmlAttribute(name = "label") + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @XmlAttribute(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @XmlAttribute(name = "ordinal") + public int getOrdinal() { + return ordinal; + } + + public void setOrdinal(int ordinal) { + this.ordinal = ordinal; + } + + @XmlElement(name = "systemFields") + public SystemFields getSystemFields() { + return systemFields; + } + + public void setSystemFields(SystemFields systemFields) { + this.systemFields = systemFields; + } + + @XmlElement(name = "extraFields") + public ExtraFields getExtraFields() { + return extraFields; + } + + public void setExtraFields(ExtraFields extraFields) { + this.extraFields = extraFields; + } + + @XmlAttribute(name = "hasTemplates") + public boolean isHasTemplates() { + return hasTemplates; + } + + public void setHasTemplates(boolean hasTemplates) { + this.hasTemplates = hasTemplates; + } + + @XmlElement(name = "descriptionTemplates") + public DescriptionTemplates getDescriptionTemplates() { + return descriptionTemplates; + } + + public void setDescriptionTemplates(DescriptionTemplates descriptionTemplates) { + this.descriptionTemplates = descriptionTemplates; + } + + public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Section toDmpBlueprintCompositeModel() { + eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Section section = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Section(); + section.setId(UUID.fromString(this.id)); + section.setLabel(this.label); + section.setDescription(this.description); + section.setOrdinal(this.ordinal); + section.setHasTemplates(this.hasTemplates); + List dmpBlueprintFieldModels = new LinkedList<>(); + if (this.systemFields != null && this.systemFields.getSystemFields() != null) { + for (SystemField systemField : this.systemFields.getSystemFields()) { + dmpBlueprintFieldModels.add(systemField.toDmpBlueprintCompositeModel()); + } + } + if (this.extraFields != null&& this.extraFields.getExtraFields() != null) { + for (ExtraField extraField : this.extraFields.getExtraFields()) { + dmpBlueprintFieldModels.add(extraField.toDmpBlueprintCompositeModel()); + } + } + section.setFields(dmpBlueprintFieldModels); + List dmpBlueprintDescriptionTemplates = new LinkedList<>(); + if (this.descriptionTemplates != null && this.descriptionTemplates.getDescriptionTemplates() != null) { + for (DescriptionTemplate descriptionTemplate : this.descriptionTemplates.getDescriptionTemplates()) { + dmpBlueprintDescriptionTemplates.add(descriptionTemplate.toDmpBlueprintCompositeModel()); + } + } + section.setDescriptionTemplates(dmpBlueprintDescriptionTemplates); + return section; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Sections.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Sections.java new file mode 100644 index 000000000..3dd99293c --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/Sections.java @@ -0,0 +1,19 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "sections") +public class Sections { + + private List
sections; + + @XmlElement(name = "section") + public List
getSections() { + return sections; + } + public void setSections(List
sections) { + this.sections = sections; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemField.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemField.java new file mode 100644 index 000000000..eded49aa0 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemField.java @@ -0,0 +1,96 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.FieldCategory; + +import javax.xml.bind.annotation.XmlAttribute; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.UUID; + +@XmlRootElement(name = "systemField") +public class SystemField { + + private String id; + private int type; + private String label; + private String placeholder; + private String description; + private int ordinal; + private boolean required; + + @XmlAttribute(name = "id") + public String getId() { + return id; + } + + public void setId(String id) { + this.id = id; + } + + @XmlAttribute(name = "type") + public int getType() { + return type; + } + + public void setType(int type) { + this.type = type; + } + + @XmlAttribute(name = "label") + public String getLabel() { + return label; + } + + public void setLabel(String label) { + this.label = label; + } + + @XmlAttribute(name = "placeholder") + public String getPlaceholder() { + return placeholder; + } + + public void setPlaceholder(String placeholder) { + this.placeholder = placeholder; + } + + @XmlAttribute(name = "description") + public String getDescription() { + return description; + } + + public void setDescription(String description) { + this.description = description; + } + + @XmlAttribute(name = "ordinal") + public int getOrdinal() { + return ordinal; + } + + public void setOrdinal(int ordinal) { + this.ordinal = ordinal; + } + + @XmlAttribute(name = "required") + public boolean isRequired() { + return required; + } + + public void setRequired(boolean required) { + this.required = required; + } + + public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel toDmpBlueprintCompositeModel() { + eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel systemField = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.FieldModel(); + systemField.setId(UUID.fromString(this.id)); + systemField.setCategory(FieldCategory.SYSTEM); + systemField.setType(this.type); + systemField.setLabel(this.label); + systemField.setPlaceholder(this.placeholder); + systemField.setDescription(this.description); + systemField.setOrdinal(this.ordinal); + systemField.setRequired(this.required); + return systemField; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemFields.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemFields.java new file mode 100644 index 000000000..7ad5a27a3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpBlueprintModel/SystemFields.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpBlueprintModel; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "systemFields") +public class SystemFields { + + private List systemFields; + + @XmlElement(name = "systemField") + public List getSystemFields() { + return systemFields; + } + public void setSystemFields(List systemFields) { + this.systemFields = systemFields; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileFieldDataType.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileFieldDataType.java deleted file mode 100644 index e5d685162..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileFieldDataType.java +++ /dev/null @@ -1,23 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "datatype") -public class DMPProfileFieldDataType { - - private int datatype; - - @XmlAttribute(name = "datatype") - public int getDatatype() { - return datatype; - } - - public void setDatatype(int datatype) { - this.datatype = datatype; - } - - public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileFieldDataType toDmpProfileCompositeModel() { - return eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileFieldDataType.fromInteger(datatype); - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileType.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileType.java deleted file mode 100644 index a13117dce..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DMPProfileType.java +++ /dev/null @@ -1,26 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - - -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; - -@XmlRootElement(name = "type") -public class DMPProfileType { - - private int type; - - @XmlAttribute(name = "type") - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - - public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileType toDmpProfileCompositeModel() { - return eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileType.fromInteger(type); - } - - -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfile.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfile.java deleted file mode 100644 index 3e9138a46..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfile.java +++ /dev/null @@ -1,33 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - -import eu.eudat.data.entities.DMPProfile; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.Date; -import java.util.UUID; - -@XmlRootElement(name = "root") -public class DmpProfile { - - private DmpProfileDefinition dmpProfileDefinition; - - @XmlElement(name = "definition") - public DmpProfileDefinition getDmpProfileDefinition() { - return dmpProfileDefinition; - } - - public void setDmpProfileDefinition(DmpProfileDefinition dmpProfileDefinition) { - this.dmpProfileDefinition = dmpProfileDefinition; - } - - public eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel toDmpProfileCompositeModel(String label) { - eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel dmpProfileModel = new eu.eudat.models.data.listingmodels.DataManagementPlanProfileListingModel(); - dmpProfileModel.setLabel(label); - dmpProfileModel.setStatus(DMPProfile.Status.SAVED.getValue()); - dmpProfileModel.setCreated(new Date()); - dmpProfileModel.setModified(new Date()); - dmpProfileModel.setDefinition(this.dmpProfileDefinition.toDmpProfileCompositeModel()); - return dmpProfileModel; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfileDefinition.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfileDefinition.java deleted file mode 100644 index 4cc4977e4..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/DmpProfileDefinition.java +++ /dev/null @@ -1,36 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - - -import eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel.FieldSets; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.LinkedList; -import java.util.List; - -@XmlRootElement(name = "definition") -public class DmpProfileDefinition { - - private FieldSets fieldSets; - - @XmlElement(name = "fieldSets") - public FieldSets getFieldSets() { - return fieldSets; - } - - public void setFieldSets(FieldSets fieldSets) { - this.fieldSets = fieldSets; - } - - public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile toDmpProfileCompositeModel() { - eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile dmpProfileDefinitionModel = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.DataManagementPlanProfile(); - List dmpProfileDefinitionFields = new LinkedList<>(); - for (Field field:this.fieldSets.fields) { - dmpProfileDefinitionFields.add(field.toDmpProfileCompositeModel()); - } - dmpProfileDefinitionModel.setFields(dmpProfileDefinitionFields); - return dmpProfileDefinitionModel; - } - - -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/Field.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/Field.java deleted file mode 100644 index 28ca0a0f6..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/Field.java +++ /dev/null @@ -1,90 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - - - -import javax.xml.bind.annotation.XmlAttribute; -import javax.xml.bind.annotation.XmlRootElement; -import javax.xml.bind.annotation.XmlValue; -import java.util.UUID; - -@XmlRootElement(name = "field") -public class Field { - - private String id; - - private String label; - - private int dataType; - - private boolean required; - - private int type; - -// private Object value; - - @XmlAttribute(name = "id") - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } - - @XmlAttribute(name = "label") - public String getLabel() { - return label; - } - - public void setLabel(String label) { - this.label = label; - } - - @XmlAttribute(name = "dataType") - public int getDataType() { - return dataType; - } - - public void setDataType(int dataType) { - this.dataType = dataType; - } - - @XmlAttribute(name = "required") - public boolean isRequired() { - return required; - } - - public void setRequired(boolean required) { - this.required = required; - } - - @XmlAttribute(name = "type") - public int getType() { - return type; - } - - public void setType(int type) { - this.type = type; - } - -// @XmlValue -// public Object getValue() { -// return value; -// } -// -// public void setValue(Object value) { -// this.value = value; -// } - - public eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field toDmpProfileCompositeModel() { - eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field field = new eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.Field(); - field.setId(UUID.fromString(this.id)); - field.setDataType(eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileFieldDataType.fromInteger(this.dataType)); - field.setLabel(this.label); - field.setRequired(this.required); - field.setType(eu.eudat.models.data.entities.xmlmodels.dmpprofiledefinition.types.DMPProfileType.fromInteger(this.type)); - // field.setValue(this.value); - return field; - } - -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/FieldSets.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/FieldSets.java deleted file mode 100644 index b8f56fd70..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/dmpXml/dmpProfileModel/FieldSets.java +++ /dev/null @@ -1,22 +0,0 @@ -package eu.eudat.logic.utilities.documents.xml.dmpXml.dmpProfileModel; - -import javax.xml.bind.annotation.XmlElement; -import javax.xml.bind.annotation.XmlRootElement; -import java.util.LinkedList; -import java.util.List; - -@XmlRootElement(name = "fieldSets") -public class FieldSets { - - List fields; - - @XmlElement(name = "field") - public List getField() { - return fields; - } - - public void setField(List fields) { - this.fields = fields; - } - -} 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..0e468c542 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,8 @@ import java.util.List; public class DatasetProfile { private String label; private String description; + private String type; + private boolean enablePrefilling; private List pages; private List
sections; private Short status; @@ -35,6 +37,20 @@ public class DatasetProfile { this.description = description; } + public String getType() { + return type; + } + public void setType(String type) { + this.type = type; + } + + public boolean isEnablePrefilling() { + return enablePrefilling; + } + public void setEnablePrefilling(boolean enablePrefilling) { + this.enablePrefilling = enablePrefilling; + } + public List getPages() { return pages; } @@ -72,6 +88,7 @@ public class DatasetProfile { } public void buildProfile(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewStyle) { + this.enablePrefilling = viewStyle.isEnablePrefilling(); this.sections = new ModelBuilder().fromViewStyleDefinition(viewStyle.getSections(), Section.class); this.pages = new ModelBuilder().fromViewStyleDefinition(viewStyle.getPages(), Page.class); } @@ -80,6 +97,8 @@ public class DatasetProfile { DatasetProfile shortProfile = new DatasetProfile(); shortProfile.setLabel(this.label); shortProfile.setDescription(this.description); + shortProfile.setType(this.type); + shortProfile.setEnablePrefilling(this.enablePrefilling); 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/components/commons/datafield/AutoCompleteData.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java index 977110dfc..98ce37926 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/datafield/AutoCompleteData.java @@ -10,11 +10,62 @@ import java.util.List; import java.util.Map; public class AutoCompleteData extends ComboBoxData { + + public static class AuthAutoCompleteData { + private String url; + private String method; + private String body; + private String path; + private String type; + + public String getUrl() { + return url; + } + + public void setUrl(String url) { + this.url = url; + } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } + + public String getBody() { + return body; + } + + public void setBody(String body) { + this.body = body; + } + + public String getPath() { + return path; + } + + public void setPath(String path) { + this.path = path; + } + + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + } public static class AutoCompleteSingleData { private int autocompleteType; private String url; private ComboBoxData.Option autoCompleteOptions; private String optionsRoot; + private Boolean hasAuth; + private AuthAutoCompleteData auth; + private String method; public int getAutocompleteType() { return autocompleteType; @@ -38,12 +89,36 @@ public class AutoCompleteData extends ComboBoxData { this.url = url; } + public Boolean getHasAuth() { + return hasAuth; + } + + public void setHasAuth(Boolean hasAuth) { + this.hasAuth = hasAuth; + } + + public AuthAutoCompleteData getAuth() { + return auth; + } + + public void setAuth(AuthAutoCompleteData auth) { + this.auth = auth; + } + public ComboBoxData.Option getAutoCompleteOptions() { return autoCompleteOptions; } public void setAutoCompleteOptions(ComboBoxData.Option autoCompleteOptions) { this.autoCompleteOptions = autoCompleteOptions; } + + public String getMethod() { + return method; + } + + public void setMethod(String method) { + this.method = method; + } } private Boolean multiAutoComplete; @@ -70,11 +145,22 @@ public class AutoCompleteData extends ComboBoxData { parent.setAttribute("url", singleData.url); parent.setAttribute("optionsRoot", singleData.optionsRoot); parent.setAttribute("autoCompleteType", Integer.toString(singleData.autocompleteType)); + parent.setAttribute("hasAuth", Boolean.toString(singleData.hasAuth)); + parent.setAttribute("method", singleData.method); Element element = doc.createElement("option"); element.setAttribute("label", singleData.autoCompleteOptions.getLabel()); element.setAttribute("value", singleData.autoCompleteOptions.getValue()); element.setAttribute("source", singleData.autoCompleteOptions.getSource()); parent.appendChild(element); + if (singleData.hasAuth) { + Element authElement = doc.createElement("auth"); + authElement.setAttribute("url", singleData.auth.url); + authElement.setAttribute("method", singleData.auth.method); + authElement.setAttribute("body", singleData.auth.body); + authElement.setAttribute("path", singleData.auth.path); + authElement.setAttribute("type", singleData.auth.type); + parent.appendChild(authElement); + } root.appendChild(parent); } return root; @@ -108,6 +194,8 @@ public class AutoCompleteData extends ComboBoxData { } else { singleData.autocompleteType = AutocompleteType.fromValue(Integer.parseInt(item.getAttribute("autoCompleteType"))).getValue(); } + singleData.hasAuth = Boolean.parseBoolean(item.getAttribute("hasAuth")); + singleData.method = item.hasAttribute("method") ? item.getAttribute("method") : "GET"; Element optionElement = (Element) item.getElementsByTagName("option").item(0); if (optionElement != null) { singleData.autoCompleteOptions = new Option(); @@ -116,6 +204,17 @@ public class AutoCompleteData extends ComboBoxData { singleData.autoCompleteOptions.setSource(optionElement.getAttribute("source")); singleData.autoCompleteOptions.setUri(optionElement.getAttribute("uri")); } + if (singleData.hasAuth) { + Element authElement = (Element) item.getElementsByTagName("auth").item(0); + if (authElement != null) { + singleData.auth = new AuthAutoCompleteData(); + singleData.auth.setUrl(authElement.getAttribute("url")); + singleData.auth.setMethod(authElement.getAttribute("method")); + singleData.auth.setBody(authElement.getAttribute("body")); + singleData.auth.setPath(authElement.getAttribute("path")); + singleData.auth.setType(authElement.getAttribute("type")); + } + } } @Override @@ -141,6 +240,8 @@ public class AutoCompleteData extends ComboBoxData { this.autoCompleteSingleDataList.get(i).autoCompleteOptions = new Option(); this.autoCompleteSingleDataList.get(i).url = (String) singleData.get("url"); this.autoCompleteSingleDataList.get(i).optionsRoot = (String) singleData.get("optionsRoot"); + this.autoCompleteSingleDataList.get(i).hasAuth = (Boolean) singleData.get("hasAuth"); + this.autoCompleteSingleDataList.get(i).method = singleData.containsKey("method") ? (String) singleData.get("method") : "GET"; if (singleData.get("autoCompleteType") == null) { this.autoCompleteSingleDataList.get(i).autocompleteType = AutocompleteType.UNCACHED.getValue(); @@ -154,6 +255,17 @@ public class AutoCompleteData extends ComboBoxData { this.autoCompleteSingleDataList.get(i).autoCompleteOptions.setSource(options.get("source")); this.autoCompleteSingleDataList.get(i).autoCompleteOptions.setUri(options.get("uri")); } + if (this.autoCompleteSingleDataList.get(i).hasAuth) { + Map auth = (Map) singleData.get("auth"); + if (auth != null) { + this.autoCompleteSingleDataList.get(i).auth = new AuthAutoCompleteData(); + this.autoCompleteSingleDataList.get(i).auth.setUrl(auth.get("url")); + this.autoCompleteSingleDataList.get(i).auth.setType(auth.get("type")); + this.autoCompleteSingleDataList.get(i).auth.setPath(auth.get("path")); + this.autoCompleteSingleDataList.get(i).auth.setBody(auth.get("body")); + this.autoCompleteSingleDataList.get(i).auth.setMethod(auth.get("method")); + } + } i++; } } @@ -190,6 +302,8 @@ public class AutoCompleteData extends ComboBoxData { node.appendChild(autoCompleteSingles.item(i)); node.setAttribute("url", item.getAttribute("url")); node.setAttribute("optionsRoot", item.getAttribute("optionsRoot")); + node.setAttribute("hasAuth", item.getAttribute("hasAuth")); + node.setAttribute("method", item.hasAttribute("method") ? item.getAttribute("method") : "GET"); autoCompletes.add(singleToMap(node)); } } @@ -214,6 +328,16 @@ public class AutoCompleteData extends ComboBoxData { return dataMap; } + private Map authToMap(Element item){ + HashMap dataMap = new HashMap(); + dataMap.put("url", item != null ? item.getAttribute("url") : ""); + dataMap.put("method", item != null ? item.getAttribute("method") : ""); + dataMap.put("body", item != null ? item.getAttribute("body") : ""); + dataMap.put("path", item != null ? item.getAttribute("path") : ""); + dataMap.put("type", item != null ? item.getAttribute("type") : ""); + return dataMap; + } + private Map singleToMap(Element item) { Map dataMap = new HashMap<>(); if (!item.getAttribute("autoCompleteType").isEmpty()) { @@ -221,8 +345,12 @@ public class AutoCompleteData extends ComboBoxData { } dataMap.put("optionsRoot", item != null ? item.getAttribute("optionsRoot") : ""); dataMap.put("url", item != null ? item.getAttribute("url") : ""); + dataMap.put("hasAuth", item != null ? item.getAttribute("hasAuth") : "false"); Element optionElement = (Element) item.getElementsByTagName("option").item(0); dataMap.put("autoCompleteOptions", item != null ? optionToMap(optionElement) : null); + Element authElement = (Element) item.getElementsByTagName("auth").item(0); + dataMap.put("auth", item != null ? authToMap(authElement) : null); + dataMap.put("method", item != null && item.hasAttribute("method") ? item.getAttribute("method") : "GET"); return dataMap; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dashboard/recent/model/RecentDatasetModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dashboard/recent/model/RecentDatasetModel.java index 2d4e5f553..4037b3f13 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dashboard/recent/model/RecentDatasetModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dashboard/recent/model/RecentDatasetModel.java @@ -39,7 +39,9 @@ public class RecentDatasetModel extends RecentActivityModel { this.setVersion(entity.getVersion()); this.datasets = entity.getDataset().stream().map(dataset -> new DatasetUrlListing().fromDataModel(dataset)).collect(Collectors.toList()); this.setFinalizedAt(entity.getFinalizedAt()); - this.setGrant(entity.getGrant().getLabel()); + if (entity.getGrant() != null) { + this.setGrant(entity.getGrant().getLabel()); + } this.groupId = entity.getGroupId(); this.setPublic(entity.isPublic()); this.setPublishedAt(entity.getPublishedAt()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java index 78e00c7ef..4091988ae 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dataset/DatasetOverviewModel.java @@ -118,7 +118,9 @@ public class DatasetOverviewModel implements DataModel new UserInfoListingModel().fromDataModel(x)).collect(Collectors.toList()); this.dmp = new DataManagementPlanOverviewModel().fromDataModel(entity.getDmp()); - this.grant = new GrantOverviewModel().fromDataModel(entity.getDmp().getGrant()); + if (entity.getDmp().getGrant() != null) { + this.grant = new GrantOverviewModel().fromDataModel(entity.getDmp().getGrant()); + } this.description = entity.getDescription(); this.isPublic = entity.getDmp().isPublic(); this.modified = entity.getModified(); 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/AssociatedProfileImportModels.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfileImportModels.java index 25c0f6ffd..89f7c833d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfileImportModels.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/AssociatedProfileImportModels.java @@ -1,19 +1,31 @@ package eu.eudat.models.data.dmp; +import java.util.List; import java.util.UUID; import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlElementWrapper; import javax.xml.bind.annotation.XmlRootElement; @XmlRootElement(name = "profile") public class AssociatedProfileImportModels { private UUID id; private String label; + private List section; @XmlElement(name = "profileId") public UUID getId() { return id; } public void setId(UUID id) { this.id = id; } - @XmlElement(name = "profilelabel") + @XmlElement(name = "profileLabel") public String getLabel() { return label; } public void setLabel(String label) { this.label = label; } + + @XmlElementWrapper(name="profileInSections") + @XmlElement(name = "section") + public List getSection() { + return section; + } + public void setSection(List section) { + this.section = section; + } } 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..cf9905ffd 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; @@ -34,7 +35,7 @@ public class DataManagementPlan implements DataModel { private List organisations; private List researchers; private List associatedUsers; - private DataManagementPlanProfile definition; + private List extraFields; private eu.eudat.models.data.userinfo.UserInfo creator; private Date modified; private Date created; @@ -152,11 +153,11 @@ public class DataManagementPlan implements DataModel { this.description = description; } - public DataManagementPlanProfile getDefinition() { - return definition; + public List getExtraFields() { + return extraFields; } - public void setDefinition(DataManagementPlanProfile definition) { - this.definition = definition; + public void setExtraFields(List extraFields) { + this.extraFields = extraFields; } public Map getProperties() { @@ -241,17 +242,26 @@ public class DataManagementPlan implements DataModel { this.version = entity.getVersion(); this.groupId = this.groupId == null ? null : entity.getGroupId(); this.label = entity.getLabel(); - this.grant = new Grant(); this.properties = entity.getProperties() != null ? new org.json.JSONObject(entity.getProperties()).toMap() : null; - this.grant.fromDataModel(entity.getGrant()); + if(entity.getGrant() != null) { + this.grant = new Grant(); + this.grant.fromDataModel(entity.getGrant()); + } + else { + this.grant = null; + } this.creator = new eu.eudat.models.data.userinfo.UserInfo(); this.groupId = entity.getGroupId(); this.lockable = entity.getDataset() != null && entity.getDataset().stream().findAny().isPresent(); - this.definition = entity.getProfile() == null ? null : new DataManagementPlanProfile().fromXml(XmlBuilder.fromXml(entity.getProfile().getDefinition()).getDocumentElement()); - if (this.definition != null && this.definition.getFields() != null && !this.definition.getFields().isEmpty() && this.properties != null) { - this.definition.getFields().forEach(item -> { - Optional> fieldOptional = ((List>) this.properties.get("fields")).stream().filter(field -> field.get("id").equals(item.getId().toString())).findFirst(); - if (fieldOptional.isPresent()) item.setValue(fieldOptional.get().get("value")); + if (this.properties != null) { + this.extraFields = new ArrayList<>(); + this.properties.forEach((id, value) -> { + if (value != null) { + ExtraFieldModel extraField = new ExtraFieldModel(); + extraField.setId(id); + extraField.setValue(value.toString()); + this.extraFields.add(extraField); + } }); } if (entity.getUsers() != null && entity.getUsers().stream().anyMatch(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue()))) @@ -259,8 +269,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); } } @@ -288,7 +305,7 @@ public class DataManagementPlan implements DataModel { this.project = new Project().fromDataModel(entity.getProject()); } - if (entity.getGrant().getFunder() != null) { + if (entity.getGrant() != null && entity.getGrant().getFunder() != null) { this.funder = new Funder(); this.funder.fromDataModel(entity.getGrant().getFunder()); } @@ -321,11 +338,19 @@ 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); + } + if(this.extraFields != null) { + this.properties = this.extraFields.stream().collect(Collectors.toMap(ExtraFieldModel::getId, ExtraFieldModel::getValue)); } dataManagementPlanEntity.setProperties(this.properties != null ? JSONObject.toJSONString(this.properties) : null); dataManagementPlanEntity.setGroupId(this.groupId != null ? this.groupId : UUID.randomUUID()); @@ -349,16 +374,19 @@ public class DataManagementPlan implements DataModel { this.researchers = entity.getResearchers() != null ? entity.getResearchers().stream().filter(Objects::nonNull).map(item -> new Researcher().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>(); this.version = entity.getVersion(); this.label = entity.getLabel(); - this.grant = new Grant(); this.properties = entity.getProperties() != null ? new org.json.JSONObject(entity.getProperties()).toMap() : null; this.creator = new eu.eudat.models.data.userinfo.UserInfo(); this.groupId = entity.getGroupId(); this.lockable = entity.getDataset() != null && entity.getDataset().stream().findAny().isPresent(); - this.definition = entity.getProfile() == null ? null : new DataManagementPlanProfile().fromXml(XmlBuilder.fromXml(entity.getProfile().getDefinition()).getDocumentElement()); - if (this.definition != null && this.definition.getFields() != null && !this.definition.getFields().isEmpty() && this.properties != null) { - this.definition.getFields().forEach(item -> { - Optional> fieldOptional = ((List>) this.properties.get("fields")).stream().filter(field -> field.get("id").equals(item.getId().toString())).findFirst(); - fieldOptional.ifPresent(stringObjectMap -> item.setValue(stringObjectMap.get("value"))); + if (this.properties != null) { + this.extraFields = new ArrayList<>(); + this.properties.forEach((id, value) -> { + if (value != null) { + ExtraFieldModel extraField = new ExtraFieldModel(); + extraField.setId(id); + extraField.setValue(value.toString()); + this.extraFields.add(extraField); + } }); } if (entity.getUsers() != null && entity.getUsers().stream().anyMatch(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue()))) @@ -366,8 +394,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); } } @@ -378,13 +413,19 @@ public class DataManagementPlan implements DataModel { this.associatedUsers = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()) : new ArrayList<>(); this.users = entity.getUsers() != null ? entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()) : new ArrayList<>(); this.dois = entity.getDois() != null ? entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>(); - this.grant.fromDataModel(entity.getGrant()); + if(entity.getGrant() != null) { + this.grant = new Grant(); + this.grant.fromDataModel(entity.getGrant()); + } + else { + this.grant = null; + } if (entity.getProject() != null) { this.project = new Project(); this.project = new Project().fromDataModel(entity.getProject()); } - if (entity.getGrant().getFunder() != null) { + if (entity.getGrant() != null && entity.getGrant().getFunder() != null) { this.funder = new Funder(); this.funder.fromDataModel(entity.getGrant().getFunder()); } 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..066aad9f8 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; @@ -22,7 +23,7 @@ public class DataManagementPlanEditorModel implements DataModel profile; + private UUID profile; private int version; private int status; private boolean lockable; @@ -33,7 +34,7 @@ public class DataManagementPlanEditorModel implements DataModel organisations; private List researchers; private List associatedUsers; - private DataManagementPlanProfile definition; + private List extraFields; private eu.eudat.models.data.userinfo.UserInfo creator; private Date modified; private Date created; @@ -52,10 +53,10 @@ public class DataManagementPlanEditorModel implements DataModel getProfile() { + public UUID getProfile() { return profile; } - public void setProfile(Tuple profile) { + public void setProfile(UUID profile) { this.profile = profile; } @@ -150,11 +151,11 @@ public class DataManagementPlanEditorModel implements DataModel getExtraFields() { + return extraFields; } - public void setDefinition(DataManagementPlanProfile definition) { - this.definition = definition; + public void setExtraFields(List extraFields) { + this.extraFields = extraFields; } public Map getProperties() { @@ -225,24 +226,28 @@ public class DataManagementPlanEditorModel implements DataModel(entity.getProfile().getId(), entity.getProfile().getLabel()) : null; + this.profile = entity.getProfile() != null ? entity.getProfile().getId() : null; this.organisations = entity.getOrganisations().stream().map(item -> new Organisation().fromDataModel(item)).collect(Collectors.toList()); this.researchers = entity.getResearchers().stream().map(item -> new Researcher().fromDataModel(item)).collect(Collectors.toList()); this.version = entity.getVersion(); this.groupId = this.groupId == null ? null : entity.getGroupId(); this.label = entity.getLabel(); - this.grant = new GrantDMPEditorModel(); this.properties = entity.getProperties() != null ? new org.json.JSONObject(entity.getProperties()).toMap() : null; - this.grant.getExistGrant().fromDataModel(entity.getGrant()); - this.grant.getExistGrant().setSource(""); + if (entity.getGrant() != null) { + this.grant = new GrantDMPEditorModel(); + this.grant.getExistGrant().fromDataModel(entity.getGrant()); + this.grant.getExistGrant().setSource(""); + } this.creator = new eu.eudat.models.data.userinfo.UserInfo(); this.groupId = entity.getGroupId(); this.lockable = entity.getDataset().stream().findAny().isPresent(); - this.definition = entity.getProfile() == null ? null : new DataManagementPlanProfile().fromXml(XmlBuilder.fromXml(entity.getProfile().getDefinition()).getDocumentElement()); - if (this.definition != null && this.definition.getFields() != null && !this.definition.getFields().isEmpty() && this.properties != null) { - this.definition.getFields().forEach(item -> { - Optional> fieldOptional = ((List>) this.properties.get("fields")).stream().filter(field -> field.get("id").equals(item.getId().toString())).findFirst(); - if (fieldOptional.isPresent()) item.setValue(fieldOptional.get().get("value")); + if (this.properties != null) { + this.extraFields = new ArrayList<>(); + this.properties.forEach((id, value) -> { + ExtraFieldModel extraField = new ExtraFieldModel(); + extraField.setId(id); + extraField.setValue(value.toString()); + this.extraFields.add(extraField); }); } if (entity.getUsers().stream().anyMatch(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue()))) @@ -250,8 +255,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); } } @@ -264,8 +275,10 @@ public class DataManagementPlanEditorModel implements DataModel new UserListingModel().fromDataModel(item.getUser())).collect(Collectors.toList()); this.users = entity.getUsers().stream().map(item -> new UserInfoListingModel().fromDataModel(item)).collect(Collectors.toList()); - this.funder = new FunderDMPEditorModel(); - this.funder.getExistFunder().fromDataModel(entity.getGrant().getFunder()); + if (entity.getGrant() != null) { + this.funder = new FunderDMPEditorModel(); + this.funder.getExistFunder().fromDataModel(entity.getGrant().getFunder()); + } this.extraProperties = entity.getExtraProperties() != null ? new org.json.JSONObject(entity.getExtraProperties()).toMap() : null; return this; @@ -276,7 +289,7 @@ 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); + } + if(this.extraFields != null) { + this.properties = new HashMap<>(); + this.extraFields.forEach((extraField) -> this.properties.put(extraField.getId(), extraField.getValue())); } 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..19f336111 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; @@ -195,7 +196,7 @@ 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(null); + 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/dmp/DatasetImportModels.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DatasetImportModels.java index d496e7dbf..7255cbff9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DatasetImportModels.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DatasetImportModels.java @@ -17,6 +17,7 @@ public class DatasetImportModels { private String name; private UUID profile; + private int dmpSectionIndex; private HashMap fieldImportModels; @XmlAttribute(name ="name") @@ -27,6 +28,7 @@ public class DatasetImportModels { this.name = name; } + @XmlElement(name = "profile-id") public UUID getProfile() { return profile; } @@ -34,6 +36,14 @@ public class DatasetImportModels { this.profile = profile; } + @XmlElement(name = "dmpSectionIndex") + public int getDmpSectionIndex() { + return dmpSectionIndex; + } + public void setDmpSectionIndex(int dmpSectionIndex) { + this.dmpSectionIndex = dmpSectionIndex; + } + @XmlJavaTypeAdapter(PageAdapter.class) @XmlElement(name = "pages") public HashMap getFieldImportModels() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DmpImportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DmpImportModel.java index 231565c73..1ba69e564 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DmpImportModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/DmpImportModel.java @@ -17,6 +17,7 @@ public class DmpImportModel { private List organisationImportModels; private List researchersImportModels; private List associatedUsersImportModels; + private List extraFieldsImportModels; private List dynamicFieldsImportModels; private List datasetImportModels; private String language; @@ -104,6 +105,15 @@ public class DmpImportModel { this.associatedUsersImportModels = associatedUsersImportModels; } + @XmlElementWrapper(name="extraFields") + @XmlElement(name = "extraField") + public List getExtraFieldsImportModels() { + return extraFieldsImportModels; + } + public void setExtraFieldsImportModels(List extraFieldsImportModels) { + this.extraFieldsImportModels = extraFieldsImportModels; + } + @XmlElementWrapper(name="dynamicFieldWithValues") @XmlElement(name = "dynamicFieldWithValue") public List getDynamicFieldsImportModels() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldModel.java new file mode 100644 index 000000000..333876a10 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldModel.java @@ -0,0 +1,20 @@ +package eu.eudat.models.data.dmp; + +public class ExtraFieldModel { + private String id; + private String value; + + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldsImportModels.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldsImportModels.java new file mode 100644 index 000000000..7f6a48899 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/dmp/ExtraFieldsImportModels.java @@ -0,0 +1,36 @@ +package eu.eudat.models.data.dmp; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; + +@XmlRootElement(name = "extraField") +public class ExtraFieldsImportModels { + + private String id; + private String label; + private String value; + + @XmlElement(name = "id") + public String getId() { + return id; + } + public void setId(String id) { + this.id = id; + } + + @XmlElement(name = "label") + public String getLabel() { + return label; + } + public void setLabel(String label) { + this.label = label; + } + + @XmlElement(name = "value") + public String getValue() { + return value; + } + public void setValue(String value) { + this.value = value; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/ViewStyleModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/ViewStyleModel.java index fd8ed6a71..99c62b402 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/ViewStyleModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/ViewStyleModel.java @@ -11,9 +11,18 @@ import java.util.LinkedList; import java.util.List; public class ViewStyleModel implements XmlSerializable { + private boolean enablePrefilling; private List
sections; private List pages; + public boolean isEnablePrefilling() { + return enablePrefilling; + } + + public void setEnablePrefilling(boolean enablePrefilling) { + this.enablePrefilling = enablePrefilling; + } + public List
getSections() { return sections; } @@ -33,6 +42,8 @@ public class ViewStyleModel implements XmlSerializable { @Override public Element toXml(Document doc) { Element root = doc.createElement("root"); + Element prefilling = doc.createElement("enablePrefilling"); + prefilling.setTextContent(String.valueOf(this.enablePrefilling)); Element sections = doc.createElement("sections"); Element pages = doc.createElement("pages"); for (Section section : this.sections) { @@ -44,6 +55,7 @@ public class ViewStyleModel implements XmlSerializable { pages.appendChild(page.toXml(doc)); } + root.appendChild(prefilling); root.appendChild(pages); root.appendChild(sections); return root; @@ -52,6 +64,12 @@ public class ViewStyleModel implements XmlSerializable { @Override public ViewStyleModel fromXml(Element element) { + this.enablePrefilling = true; + Element prefilling = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "enablePrefilling"); + if (prefilling != null) { + this.enablePrefilling = Boolean.parseBoolean(prefilling.getChildNodes().item(0).getNodeValue()); + } + this.sections = new LinkedList(); Element sections = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "sections"); if (sections != null) { 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..1ad0fde24 --- /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); + if (this.minMultiplicity != null) rootElement.setAttribute("minMultiplicity", String.valueOf(this.minMultiplicity)); + if (this.maxMultiplicity != null) 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 = item.hasAttribute("minMultiplicity") && !item.getAttribute("minMultiplicity").equals("null") ? Integer.parseInt(item.getAttribute("minMultiplicity")) : null; + this.maxMultiplicity = item.hasAttribute("maxMultiplicity") && !item.getAttribute("minMultiplicity").equals("null") ? Integer.parseInt(item.getAttribute("maxMultiplicity")) : null; + 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..306c999e8 --- /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 Section Type"); + } + } +} \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java new file mode 100644 index 000000000..6e3abcc30 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/helpers/common/AutoCompleteOptionsLookupItem.java @@ -0,0 +1,19 @@ +package eu.eudat.models.data.helpers.common; + +import eu.eudat.data.dao.criteria.Criteria; +import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; + +import java.util.List; + +public class AutoCompleteOptionsLookupItem extends Criteria { + + private List autoCompleteSingleDataList; + + public List getAutoCompleteSingleDataList() { + return autoCompleteSingleDataList; + } + public void setAutoCompleteSingleDataList(List autoCompleteSingleDataList) { + this.autoCompleteSingleDataList = autoCompleteSingleDataList; + } + +} 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/DataManagementPlanListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java index 4dd4e32d6..ade3d3918 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DataManagementPlanListingModel.java @@ -147,7 +147,7 @@ public class DataManagementPlanListingModel implements DataModel new DatasetUrlListing().fromDataModel(x)).collect(Collectors.toList()); @@ -174,9 +174,11 @@ public class DataManagementPlanListingModel implements DataModel { @@ -190,7 +190,7 @@ 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/listingmodels/DatasetListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java index b2c41e8a9..ba4a30b2a 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/listingmodels/DatasetListingModel.java @@ -144,7 +144,7 @@ public class DatasetListingModel implements DataModel pidLinks = new ArrayList<>(); + + public List getPidLinks() { + return pidLinks; + } + public void setPidLinks(List pidLinks) { + this.pidLinks = pidLinks; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java index 6c09e6b2e..873c59e34 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/prefilling/Prefilling.java @@ -1,8 +1,12 @@ package eu.eudat.models.data.prefilling; +import java.util.Map; + public class Prefilling { private String pid; private String name; + private Map data; + private String key; private String tag; public String getPid() { @@ -21,6 +25,22 @@ public class Prefilling { this.name = name; } + public Map getData() { + return data; + } + + public void setData(Map data) { + this.data = data; + } + + public String getKey() { + return key; + } + + public void setKey(String key) { + this.key = key; + } + public String getTag() { return tag; } 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/data/rda/DmpRDAExportModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/DmpRDAExportModel.java index 9d3cccf23..425f42657 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/DmpRDAExportModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/rda/DmpRDAExportModel.java @@ -162,7 +162,9 @@ public class DmpRDAExportModel { dmpRda.ethical_issues_exist = "unknown"; dmpRda.language = "en"; dmpRda.modified = formatter.format(new Date()); - dmpRda.project = new ProjectRDAExportModel().fromDataModel(entity.getGrant()); + if (entity.getGrant() != null) { + dmpRda.project = new ProjectRDAExportModel().fromDataModel(entity.getGrant()); + } dmpRda.title = entity.getLabel(); return dmpRda; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java new file mode 100644 index 000000000..90ba44eb9 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/saml2/AuthnRequestModel.java @@ -0,0 +1,47 @@ +package eu.eudat.models.data.saml2; + +public class AuthnRequestModel { + + String authnRequestXml; + String relayState; + String algorithm; + String signature; + + public AuthnRequestModel() {} + + public AuthnRequestModel(String authnRequestXml, String relayState, String algorithm, String signature) { + this.authnRequestXml = authnRequestXml; + this.relayState = relayState; + this.algorithm = algorithm; + this.signature = signature; + } + + public String getAuthnRequestXml() { + return authnRequestXml; + } + public void setAuthnRequestXml(String authnRequestXml) { + this.authnRequestXml = authnRequestXml; + } + + public String getRelayState() { + return relayState; + } + public void setRelayState(String relayState) { + this.relayState = relayState; + } + + public String getAlgorithm() { + return algorithm; + } + public void setAlgorithm(String algorithm) { + this.algorithm = algorithm; + } + + public String getSignature() { + return signature; + } + public void setSignature(String signature) { + this.signature = signature; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java index 46f11ded7..3a277ce3e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/components/datasetprofile/Field.java @@ -256,7 +256,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin @Override public void toMap(Map fieldValues) { if (this.value != null) { - if ((this.viewStyle != null && this.viewStyle.getRenderStyle().equals("datasetIdentifier") || this.value instanceof Collection)) { + if ((this.viewStyle != null && this.viewStyle.getRenderStyle().equals("datasetIdentifier") && this.value instanceof Map || this.value instanceof Collection)) { ObjectMapper mapper = new ObjectMapper(); String valueString = null; try { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/composite/DatasetProfile.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/composite/DatasetProfile.java index 3d6449313..f2714ead1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/user/composite/DatasetProfile.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/user/composite/DatasetProfile.java @@ -12,6 +12,8 @@ import java.util.Map; public class DatasetProfile implements PropertiesModelBuilder { private String description; private String language; + private String type; + private boolean enablePrefilling; private List
sections; private List rules; private List pages; @@ -33,6 +35,22 @@ public class DatasetProfile implements PropertiesModelBuilder { this.language = language; } + public String getType() { + return type; + } + + public void setType(String type) { + this.type = type; + } + + public boolean isEnablePrefilling() { + return enablePrefilling; + } + + public void setEnablePrefilling(boolean enablePrefilling) { + this.enablePrefilling = enablePrefilling; + } + public List
getSections() { return sections; } @@ -67,6 +85,7 @@ public class DatasetProfile implements PropertiesModelBuilder { } public void buildProfile(eu.eudat.models.data.entities.xmlmodels.datasetprofiledefinition.ViewStyleModel viewStyle) { + this.enablePrefilling = viewStyle.isEnablePrefilling(); this.sections = new ModelBuilder().fromViewStyleDefinition(viewStyle.getSections(), Section.class); this.pages = new ModelBuilder().fromViewStyleDefinition(viewStyle.getPages(), Page.class); this.rules = ModelBuilderCollector.collectRules(viewStyle.getSections()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java index 0c6a340f8..6f31e570e 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java @@ -6,6 +6,7 @@ import java.util.stream.Collectors; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.models.rda.Cost; import eu.eudat.models.rda.PidSystem; @@ -34,11 +35,14 @@ public class CostRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dmp.cost")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -64,12 +68,22 @@ public class CostRDAMapper { rdaMap.put(key, rda); } if(rdaProperty.contains("value")){ - rda.setValue(Double.valueOf(rdaValue)); + try { + rda.setValue(Double.valueOf(rdaValue)); + } + catch (NumberFormatException e) { + logger.warn("Dmp cost value " + rdaValue + " is not valid. Cost value will not be set."); + } } else if(rdaProperty.contains("currency_code")){ - HashMap result = - new ObjectMapper().readValue(rdaValue, HashMap.class); - rda.setCurrencyCode(Cost.CurrencyCode.fromValue(result.get("value"))); + try { + HashMap result = + new ObjectMapper().readValue(rdaValue, HashMap.class); + rda.setCurrencyCode(Cost.CurrencyCode.fromValue(result.get("value"))); + } + catch (Exception e) { + logger.warn("Dmp cost currency code is not valid and will not be set."); + } } else if(rdaProperty.contains("title")){ Iterator iter = node.get("value").elements(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java index f3e690e75..50d535348 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java @@ -2,6 +2,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.rda.DatasetId; import org.slf4j.Logger; @@ -30,11 +31,14 @@ public class DatasetIdRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.dataset_id")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -76,7 +80,13 @@ public class DatasetIdRDAMapper { rda.setIdentifier(value); break; case TYPE: - rda.setType(DatasetId.Type.fromValue(value)); + try { + rda.setType(DatasetId.Type.fromValue(value)); + } + catch (IllegalArgumentException e){ + logger.warn("Type " + value + " from semantic rda.dataset.dataset_id.type was not found. Setting type to OTHER."); + rda.setType(DatasetId.Type.OTHER); + } break; } } 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 c1a2d9dbc..89384c926 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,7 +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; @@ -51,6 +52,7 @@ public class DatasetRDAMapper { rda.setTitle(dataset.getLabel()); rda.setDescription(dataset.getDescription()); rda.setAdditionalProperty("template", dataset.getProfile().getId()); + rda.setAdditionalProperty("dmpSectionIndex", dataset.getDmpSectionIndex()); try { JSONObject jObject = new JSONObject(dataset.getProperties()); Map templateIdsToValues = jObject.toMap(); @@ -74,7 +76,14 @@ public class DatasetRDAMapper { } List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.language"); if (!languageNodes.isEmpty() && !languageNodes.get(0).get("value").asText().isEmpty()) { - rda.setLanguage(Language.fromValue(languageNodes.get(0).get("value").asText())); + String lang = languageNodes.get(0).get("value").asText(); + try { + rda.setLanguage(Language.fromValue(lang)); + } + catch (IllegalArgumentException e){ + logger.warn("Language " + lang + " from semantic rda.dataset.language was not found. Setting '" + dataset.getProfile().getLanguage() +"' as language from the dataset profile."); + rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(dataset.getProfile().getLanguage())); + } } else { rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(dataset.getProfile().getLanguage())); } @@ -188,6 +197,7 @@ public class DatasetRDAMapper { return Collections.singletonList(new Contributor()); } }).flatMap(Collection::stream).collect(Collectors.toList())); + dmp.setContributor(dmp.getContributor().stream().filter(contributor -> contributor.getContributorId() != null && contributor.getName() != null).collect(Collectors.toList())); } List costNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dmp.cost"); if (!costNodes.isEmpty()) { @@ -199,11 +209,14 @@ public class DatasetRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dmp.ethical_issues")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -268,12 +281,18 @@ 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()); + if (rda.getAdditionalProperties().get("dmpSectionIndex") != null) { + entity.setDmpSectionIndex(Integer.parseInt(rda.getAdditionalProperties().get("dmpSectionIndex").toString())); + } else { + entity.setDmpSectionIndex(0); + } + 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); @@ -347,7 +366,9 @@ public class DatasetRDAMapper { List tags = this.apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().query(criteria).stream().map(eu.eudat.elastic.entities.Dataset::getTags).flatMap(Collection::stream).filter(StreamDistinctBy.distinctByKey(Tag::getId)).collect(Collectors.toList()); if(!rda.getKeyword().isEmpty()){ List templateTags = tags.stream().filter(tag -> rda.getKeyword().contains(tag.getName())).collect(Collectors.toList()); - properties.put(keywordIds.get(0), mapper.writeValueAsString(templateTags)); + if(!templateTags.isEmpty()) { + properties.put(keywordIds.get(0), mapper.writeValueAsString(templateTags)); + } // for (int i = 0; i < keywordIds.size(); i++) { // //if (takeAll) { // List tags = new ArrayList<>(); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java index 547927c94..046d73d91 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java @@ -4,6 +4,7 @@ import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonMappingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.logic.utilities.json.JavaToJson; import eu.eudat.logic.utilities.json.JsonSearcher; @@ -74,8 +75,13 @@ public class DistributionRDAMapper { } break; case DATA_ACCESS: - rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.DATA_ACCESS.getName(), node.get("id").asText()); + try { + rda.setDataAccess(Distribution.DataAccess.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.DATA_ACCESS.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution data access " + rdaValue + " from semantic distribution.data_access is not valid. Data access will not be set set."); + } break; case BYTE_SIZE: rda.setByteSize(Integer.parseInt(rdaValue)); @@ -376,11 +382,14 @@ public class DistributionRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } return rdaProperty; 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 66ceff6c3..061e98b9f 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 @@ -1,15 +1,20 @@ package eu.eudat.models.rda.mapper; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; +import eu.eudat.logic.managers.DataManagementProfileManager; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.utilities.helpers.StreamDistinctBy; -import eu.eudat.models.rda.Cost; +import eu.eudat.models.data.dmp.AssociatedProfile; import eu.eudat.models.rda.Dmp; import eu.eudat.models.rda.DmpId; import net.minidev.json.JSONObject; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import javax.persistence.NoResultException; import javax.transaction.Transactional; import java.io.IOException; import java.util.*; @@ -18,15 +23,17 @@ import java.util.stream.Collectors; @Component public class DmpRDAMapper { + private static final Logger logger = LoggerFactory.getLogger(DmpRDAMapper.class); + private DatasetRDAMapper datasetRDAMapper; private ApiContext apiContext; - + private DataManagementProfileManager dataManagementProfileManager; @Autowired - public DmpRDAMapper(DatasetRDAMapper datasetRDAMapper, ApiContext apiContext) throws IOException { + public DmpRDAMapper(DatasetRDAMapper datasetRDAMapper, ApiContext apiContext, DataManagementProfileManager dataManagementProfileManager) throws IOException { this.datasetRDAMapper = datasetRDAMapper; this.apiContext = apiContext; - + this.dataManagementProfileManager = dataManagementProfileManager; } @Transactional @@ -83,7 +90,19 @@ public class DmpRDAMapper { rda.getCost().add(CostRDAMapper.toRDA((Map)costl)); }); } - UserInfo contact = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(UUID.fromString((String) extraProperties.get("contact"))); + UserInfo contactDb = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(UUID.fromString((String) extraProperties.get("contact"))); + UserInfo contact = new UserInfo(); + contact.setId(contactDb.getId()); + contact.setName(contactDb.getName()); + contact.setEmail(contactDb.getEmail()); + if(contact.getEmail() == null){ + for(UserDMP userDMP: dmp.getUsers()){ + if(userDMP.getDmp().getId() == dmp.getId() && userDMP.getUser().getEmail() != null){ + contact.setEmail(userDMP.getUser().getEmail()); + break; + } + } + } rda.setContact(ContactRDAMapper.toRDA(contact)); } @@ -101,7 +120,14 @@ public class DmpRDAMapper { // rda.getContributor().addAll(dmp.getUsers().stream().map(ContributorRDAMapper::toRDA).collect(Collectors.toList())); rda.setDataset(dmp.getDataset().stream().filter(dataset -> dataset.getStatus() != eu.eudat.elastic.entities.Dmp.DMPStatus.DELETED.getValue()).map(dataset -> datasetRDAMapper.toRDA(dataset, rda)).collect(Collectors.toList())); rda.setProject(Collections.singletonList(ProjectRDAMapper.toRDA(dmp.getProject(), dmp.getGrant()))); - rda.setAdditionalProperty("templates", dmp.getAssociatedDmps().stream().map(datasetProfile -> datasetProfile.getId().toString()).toArray()); + + rda.setAdditionalProperty("templates", dmp.getAssociatedDmps().stream().map(item -> item.getDatasetprofile().getId().toString()).toArray()); + rda.setAdditionalProperty("blueprintId", dmp.getProfile().getId()); + rda.setAdditionalProperty("license", extraProperties.get("license")); + rda.setAdditionalProperty("visible", extraProperties.get("visible")); + rda.setAdditionalProperty("publicDate", extraProperties.get("publicDate")); + rda.setAdditionalProperty("contact", extraProperties.get("contact")); + rda.setAdditionalProperty("dmpProperties", dmp.getProperties()); return rda; } @@ -109,32 +135,57 @@ public class DmpRDAMapper { DMP entity = new DMP(); entity.setLabel(rda.getTitle()); if (rda.getDmpId().getType() == DmpId.Type.DOI) { - EntityDoi doi = apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().findFromDoi(rda.getDmpId().getIdentifier()); - Set dois = new HashSet<>(); - dois.add(doi); - entity.setDois(dois); - } - 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 (entity.getAssociatedDmps() == null) { - entity.setAssociatedDmps(new HashSet<>()); - } - if (profiles != null) { - for (String profile : profiles) { - DatasetProfile exProfile = apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().find(UUID.fromString(profile)); - entity.getAssociatedDmps().add(exProfile); + try { + EntityDoi doi = apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().findFromDoi(rda.getDmpId().getIdentifier()); + Set dois = new HashSet<>(); + dois.add(doi); + entity.setDois(dois); + } + catch (NoResultException e) { + logger.warn("No entity doi: " + rda.getDmpId().getIdentifier() + " found in database. No dois are added to dmp."); + entity.setDois(new HashSet<>()); } } + + String blueprintId = (String) rda.getAdditionalProperties().get("blueprintId"); + DMPProfile blueprint = apiContext.getOperationsContext().getDatabaseRepository().getDmpProfileDao().find(UUID.fromString(blueprintId)); + entity.setProfile(blueprint); + + if (((List) rda.getAdditionalProperties().get("templates")) != null && !((List) rda.getAdditionalProperties().get("templates")).isEmpty()) { + List descriptionTemplates = ((List) rda.getAdditionalProperties().get("templates")).stream().map(this::getProfile).filter(Objects::nonNull).collect(Collectors.toList()); + Set dmpDatasetProfiles = new HashSet<>(); + for (DescriptionTemplate profile : descriptionTemplates) { + DMPDatasetProfile dmpDatasetProfile = new DMPDatasetProfile(); + dmpDatasetProfile.setDmp(entity); + dmpDatasetProfile.setDatasetprofile(profile); + String indexes = this.dataManagementProfileManager.sectionIndexesForDescriptionTemplate(blueprint, profile.getId()).stream() + .map(String::valueOf) // convert each int to a string + .collect(Collectors.joining(",")); + dmpDatasetProfile.setData("{\"dmpSectionIndex\":[" + indexes + "]}"); + dmpDatasetProfiles.add(dmpDatasetProfile); + } + entity.setAssociatedDmps(dmpDatasetProfiles); + } + +// if (entity.getAssociatedDmps() == null) { +// entity.setAssociatedDmps(new HashSet<>()); +// } +// if (profiles != null && entity.getId() != null) { +// for (String profile : profiles) { +// entity.getAssociatedDmps().add(this.getProfile(profile, entity.getId())); +// } +// } if (rda.getContributor() != null && !rda.getContributor().isEmpty() && rda.getContributor().get(0).getContributorId() != null) { - entity.setResearchers(rda.getContributor().stream().map(ContributorRDAMapper::toEntity).filter(StreamDistinctBy.distinctByKey(Researcher::getReference)).collect(Collectors.toSet())); + entity.setResearchers(rda.getContributor().stream().filter(r -> r.getContributorId() != null).map(ContributorRDAMapper::toEntity).filter(StreamDistinctBy.distinctByKey(Researcher::getReference)).collect(Collectors.toSet())); } entity.setCreated(rda.getCreated()); entity.setModified(rda.getModified()); entity.setDescription(rda.getDescription()); - DatasetProfile defaultProfile = ((DatasetProfile)entity.getAssociatedDmps().toArray()[0]); - entity.setDataset(rda.getDataset().stream().map(rda1 -> datasetRDAMapper.toEntity(rda1, defaultProfile)).collect(Collectors.toSet())); - if (rda.getProject().size() > 0) { + if(entity.getAssociatedDmps().size() > 0) { + DescriptionTemplate defaultProfile = entity.getAssociatedDmps().stream().findFirst().get().getDatasetprofile(); + entity.setDataset(rda.getDataset().stream().map(rda1 -> datasetRDAMapper.toEntity(rda1, defaultProfile)).collect(Collectors.toSet())); + } + if (rda.getProject() != null && rda.getProject().size() > 0) { Map result = ProjectRDAMapper.toEntity(rda.getProject().get(0), apiContext); entity.setProject((Project) result.get("project")); result.entrySet().stream().filter(entry -> entry.getKey().startsWith("grant")).forEach(entry -> entity.setGrant((Grant) entry.getValue())); @@ -142,13 +193,19 @@ public class DmpRDAMapper { Map extraProperties = new HashMap<>(); extraProperties.put("language", LanguageRDAMapper.mapRDAIsoToLanguageIso(rda.getLanguage())); - + if (rda.getAdditionalProperties().get("license") != null) extraProperties.put("license", rda.getAdditionalProperties().get("license")); + if (rda.getAdditionalProperties().get("visible") != null) extraProperties.put("visible", rda.getAdditionalProperties().get("visible")); + if (rda.getAdditionalProperties().get("publicDate") != null) extraProperties.put("publicDate", rda.getAdditionalProperties().get("publicDate")); + if (rda.getAdditionalProperties().get("contact") != null) extraProperties.put("contact", rda.getAdditionalProperties().get("contact")); entity.setExtraProperties(JSONObject.toJSONString(extraProperties)); + if (rda.getAdditionalProperties().get("dmpProperties") != null) entity.setProperties(rda.getAdditionalProperties().get("dmpProperties").toString()); + + return entity; } - private DatasetProfile getProfile(String id) { + private DescriptionTemplate getProfile(String id) { return apiContext.getOperationsContext().getDatabaseRepository().getDatasetProfileDao().asQueryable().where(((builder, root) -> builder.equal(root.get("id"), UUID.fromString(id)))).getSingleOrDefault(); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java index ca69c5cfb..74e5c2e64 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java @@ -3,6 +3,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.Host; import eu.eudat.models.rda.PidSystem; @@ -22,11 +23,14 @@ public class HostRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution.host")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ @@ -55,8 +59,13 @@ public class HostRDAMapper { rda.setAdditionalProperty(ImportPropertyName.BACKUP_TYPE.getName(), node.get("id").asText()); break; case CERTIFIED_WITH: - rda.setCertifiedWith(Host.CertifiedWith.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.CERTIFIED_WITH.getName(), node.get("id").asText()); + try { + rda.setCertifiedWith(Host.CertifiedWith.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.CERTIFIED_WITH.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host certified with " + rdaValue + "from semantic distribution.host.certified_with is not valid. Certified_with will not be set set."); + } break; case DESCRIPTION: rda.setDescription(rdaValue); @@ -70,8 +79,13 @@ public class HostRDAMapper { logger.warn(e.getLocalizedMessage() + ". Try to pass value as is"); } } - rda.setGeoLocation(Host.GeoLocation.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.GEO_LOCATION.getName(), node.get("id").asText()); + try { + rda.setGeoLocation(Host.GeoLocation.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.GEO_LOCATION.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host geo location " + rdaValue + "from semantic distribution.host.geo_location is not valid. Geo location will not be set set."); + } break; case PID_SYSTEM: try{ @@ -101,8 +115,13 @@ public class HostRDAMapper { rda.setAdditionalProperty(ImportPropertyName.STORAGE_TYPE.getName(), node.get("id").asText()); break; case SUPPORT_VERSIONING: - rda.setSupportVersioning(Host.SupportVersioning.fromValue(rdaValue)); - rda.setAdditionalProperty(ImportPropertyName.SUPPORT_VERSIONING.getName(), node.get("id").asText()); + try { + rda.setSupportVersioning(Host.SupportVersioning.fromValue(rdaValue)); + rda.setAdditionalProperty(ImportPropertyName.SUPPORT_VERSIONING.getName(), node.get("id").asText()); + } + catch (IllegalArgumentException e) { + logger.warn("Distribution host support versioning " + rdaValue + "from semantic distribution.host.support_versioning is not valid. Support versioning will not be set set."); + } break; case TITLE: rda.setTitle(rdaValue); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java index 8b2cc84e3..d7e178c14 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.json.JsonSearcher; import eu.eudat.models.rda.License; import org.slf4j.Logger; @@ -20,11 +21,14 @@ public class LicenseRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.distribution.license")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java index fd9eb1d13..e8c28b7bb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java @@ -23,11 +23,14 @@ public class MetadataRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.metadata")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/ProjectRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/ProjectRDAMapper.java index add67c68e..28f67ff93 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/ProjectRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/ProjectRDAMapper.java @@ -17,13 +17,13 @@ public class ProjectRDAMapper { public static Project toRDA(eu.eudat.data.entities.Project project, Grant grant) { Project rda = new Project(); try { - rda.setTitle(project.getLabel()); - rda.setDescription(project.getDescription()); - if (project.getStartdate() != null) { - rda.setStart(project.getStartdate().toString()); + rda.setTitle(grant.getLabel()); + rda.setDescription(grant.getDescription()); + if (grant.getStartdate() != null) { + rda.setStart(grant.getStartdate().toString()); } - if (project.getEnddate() != null) { - rda.setEnd(project.getEnddate().toString()); + if (grant.getEnddate() != null) { + rda.setEnd(grant.getEnddate().toString()); } rda.setFunding(Collections.singletonList(FundingRDAMapper.toRDA(grant))); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java index 85f494917..1d560b91b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.SecurityAndPrivacy; import org.slf4j.Logger; @@ -19,11 +20,14 @@ public class SecurityAndPrivacyRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.security_and_privacy")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java index 709ee5ef3..31ad744fe 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java @@ -1,6 +1,7 @@ package eu.eudat.models.rda.mapper; import com.fasterxml.jackson.databind.JsonNode; +import com.fasterxml.jackson.databind.node.ArrayNode; import eu.eudat.logic.utilities.helpers.MyStringUtils; import eu.eudat.models.rda.TechnicalResource; import org.slf4j.Logger; @@ -19,11 +20,14 @@ public class TechnicalResourceRDAMapper { String rdaProperty = ""; JsonNode schematics = node.get("schematics"); if(schematics.isArray()){ + int index = 0; for(JsonNode schematic: schematics){ if(schematic.asText().startsWith("rda.dataset.technical_resource")){ rdaProperty = schematic.asText(); + ((ArrayNode)schematics).remove(index); break; } + index++; } } else{ 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 +230,7 @@ public class DataManagementPlanPublicModel implements DataModel + + + + + + + + + + + + + + + + + + + + - cristin - + rda-metadata-schemes + 1 External - https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} - 1 - application/vnd.api+json; charset=utf-8 + https://rdamsc.bath.ac.uk/api2/m?q={like}&start=1&pageSize=111 + application/json; charset=utf-8 - $['data'][*]['attributes'] + $['data']['items'][*] - 'pid' - 'name' + 'mscid' + 'title' 'uri' 'description' - 'source' $['meta']['pagination']['page','pages','count'] @@ -1207,6 +1225,7 @@ but not 1 External https://zenodo.org/api/records/?page={page}&size={pageSize}&q=title:"{like}" doi:"{like}" conceptdoi:"{like}" + false 1 application/json @@ -1224,38 +1243,83 @@ but not https://zenodo.org/api/records/{id} - + - - + + - - - - - - - - - - - + + + + + + + + + + + - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + openaire + + 1 + External + https://services.openaire.eu/search/v2/api/datasets/?q={like}&page={page}&size={pageSize}&format=json + true + 0 + application/json + + $['results'][*]['result']['metadata']['oaf:entity']['oaf:result'] + + 'originalId' + 'title' + 'description' + + + $['meta']['pagination']['page','pages','count'] + + + + + + + + + + + + + + + + + + + + + + diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml index 14c945367..365ea535a 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrlsStaging.xml @@ -6,22 +6,40 @@ + + + + + + + + + + + + + + + + + + + + - cristin - + rda-metadata-schemes + 1 External - https://eestore.paas2.uninett.no/api/metadataschema/?search={like}&page={page}&size={pageSize} - 1 - application/vnd.api+json; charset=utf-8 + https://rdamsc.bath.ac.uk/api2/m?q={like}&start=1&pageSize=111 + application/json; charset=utf-8 - $['data'][*]['attributes'] + $['data']['items'][*] - 'pid' - 'name' + 'mscid' + 'title' 'uri' 'description' - 'source' $['meta']['pagination']['page','pages','count'] diff --git a/dmp-backend/web/src/main/resources/pidLinks.json b/dmp-backend/web/src/main/resources/pidLinks.json new file mode 100644 index 000000000..d2a011677 --- /dev/null +++ b/dmp-backend/web/src/main/resources/pidLinks.json @@ -0,0 +1,100 @@ +{ + "pidLinks": [ + { + "pid": "doi", + "link": "https://doi.org/{pid}" + }, + { + "pid": "uniprot", + "link": "https://uniprot.org/uniprotkb/{pid}" + }, + { + "pid": "handle", + "link": "https://hdl.handle.net/{pid}" + }, + { + "pid": "arxiv", + "link": "https://arxiv.org/abs/{pid}" + }, + { + "pid": "ascl", + "link": "https://ascl.net/{pid}" + }, + { + "pid": "orcid", + "link": "https://orcid.org/{pid}" + }, + { + "pid": "pmid", + "link": "https://pubmed.ncbi.nlm.nih.gov/{pid}" + }, + { + "pid": "ads", + "link": "https://ui.adsabs.harvard.edu/#abs/{pid}" + }, + { + "pid": "pmcid", + "link": "https://ncbi.nlm.nih.gov/pmc/{pid}" + }, + { + "pid": "gnd", + "link": "https://d-nb.info/gnd/{pid}" + }, + { + "pid": "urn", + "link": "https://nbn-resolving.org/{pid}" + }, + { + "pid": "sra", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "bioproject", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "biosample", + "link": "https://ebi.ac.uk/ena/data/view/{pid}" + }, + { + "pid": "ensembl", + "link": "https://ensembl.org/id/{pid}" + }, + { + "pid": "refseq", + "link": "https://ncbi.nlm.nih.gov/entrez/viewer.fcgi?val={pid}" + }, + { + "pid": "genome", + "link": "https://ncbi.nlm.nih.gov/assembly/{pid}" + }, + { + "pid": "geo", + "link": "https://ncbi.nlm.nih.gov/geo/query/acc.cgi?acc={pid}" + }, + { + "pid": "arrayexpress_array", + "link": "https://ebi.ac.uk/arrayexpress/arrays/{pid}" + }, + { + "pid": "arrayexpress_experiment", + "link": "https://ebi.ac.uk/arrayexpress/experiments/{pid}" + }, + { + "pid": "hal", + "link": "https://hal.archives-ouvertes.fr/{pid}" + }, + { + "pid": "swh", + "link": "https://archive.softwareheritage.org/{pid}" + }, + { + "pid": "ror", + "link": "https://ror.org/{pid}" + }, + { + "pid": "viaf", + "link": "https://viaf.org/viaf/{pid}" + } + ] +} \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html index a83e48013..3d46fc62d 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailConfirmation.html @@ -260,7 +260,7 @@
- OpenDMP + OpenDMP

Thank you for joining OpenDMP!

Please confirm that your email address is correct to continue.
The link will expire in {expiration_time}.

diff --git a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html index 6d5fea269..01f0536d6 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailMergeConfirmation.html @@ -260,7 +260,7 @@
- OpenDMP + OpenDMP

User {userName} have sent you a merge Request.

Please confirm that you want to merge your {host} account with that account.
The link will expire in {expiration_time}.

diff --git a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html index 7f6ce7c8d..ee547f813 100644 --- a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html +++ b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html @@ -260,7 +260,7 @@
- OpenDMP + OpenDMP

You have made a request to unlink your email account in ARGOS.

Please confirm that you want to unlink your {email} account.
The link will expire in {expiration_time}.

diff --git a/dmp-db-scema/main/data-dump.sql b/dmp-db-scema/main/data-dump.sql index 1ddeee509..f2c09c5d9 100644 --- a/dmp-db-scema/main/data-dump.sql +++ b/dmp-db-scema/main/data-dump.sql @@ -17,7 +17,9 @@ INSERT INTO public."DoiFunder"(name, doi) VALUES ('Wellcome Trust', '10.13039/10 UPDATE public."DMP" SET "extraProperties"='{"language": "en"}'; -UPDATE public."DatasetProfile" +UPDATE public."DescriptionTemplate" SET "Language"='en'; +INSERT INTO public."DescriptionTemplateType"("ID", "Name", "Status") VALUES (uuid_generate_v4(), 'Dataset', 1); + INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.007', '2020-10-27 13:40:00.000000+03', now(), 'Add userstatus on UserInfo table'); \ No newline at end of file diff --git a/dmp-db-scema/main/dmp-dump.sql b/dmp-db-scema/main/dmp-dump.sql index 470447770..936045b17 100644 --- a/dmp-db-scema/main/dmp-dump.sql +++ b/dmp-db-scema/main/dmp-dump.sql @@ -94,7 +94,7 @@ CREATE TABLE public."DMP" ( "GroupId" uuid, "Label" character varying(250) NOT NULL, "Version" integer NOT NULL, - "Grant" uuid NOT NULL, + "Grant" uuid, "AssociatedDmps" xml, "Profile" uuid, "Status" smallint DEFAULT 0 NOT NULL, @@ -129,7 +129,8 @@ COMMENT ON COLUMN public."DMP"."AssociatedDmps" IS 'More data about the DMP as d CREATE TABLE public."DMPDatasetProfile" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, dmp uuid NOT NULL, - datasetprofile uuid NOT NULL + datasetprofile uuid NOT NULL, + "data" text NOT NULL ); @@ -235,6 +236,7 @@ CREATE TABLE public."Dataset" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, "Label" character varying(250) NOT NULL, "DMP" uuid, + "DmpSectionIndex" integer NOT NULL, "Uri" character varying(250), "Properties" text, "Profile" uuid, @@ -302,10 +304,23 @@ CREATE TABLE public."DatasetExternalDataset" ( ALTER TABLE public."DatasetExternalDataset" OWNER TO :POSTGRES_USER; -- --- Name: DatasetProfile; Type: TABLE; Schema: public; Owner: :POSTGRES_USER +-- Name: DescriptionTemplateType; Type: TABLE; Schema: public; Owner: :POSTGRES_USER -- -CREATE TABLE public."DatasetProfile" ( +CREATE TABLE public."DescriptionTemplateType" ( + "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, + "Name" character varying(250) NOT NULL, + "Status" smallint DEFAULT 0 NOT NULL +); + + +ALTER TABLE public."DescriptionTemplateType" OWNER TO :POSTGRES_USER; + +-- +-- Name: DescriptionTemplate; Type: TABLE; Schema: public; Owner: :POSTGRES_USER +-- + +CREATE TABLE public."DescriptionTemplate" ( "ID" uuid DEFAULT public.uuid_generate_v4() NOT NULL, "Label" character varying(250) NOT NULL, "Definition" xml NOT NULL, @@ -315,17 +330,18 @@ CREATE TABLE public."DatasetProfile" ( "Description" text NOT NULL, "GroupId" uuid NOT NULL, "Version" integer DEFAULT 0 NOT NULL, - "Language" character varying NOT NULL + "Language" character varying NOT NULL, + "Type" uuid NOT NULL ); -ALTER TABLE public."DatasetProfile" OWNER TO :POSTGRES_USER; +ALTER TABLE public."DescriptionTemplate" OWNER TO :POSTGRES_USER; -- --- Name: TABLE "DatasetProfile"; Type: COMMENT; Schema: public; Owner: :POSTGRES_USER +-- Name: TABLE "DescriptionTemplate"; Type: COMMENT; Schema: public; Owner: :POSTGRES_USER -- -COMMENT ON TABLE public."DatasetProfile" IS 'Profiles for dmp datasets'; +COMMENT ON TABLE public."DescriptionTemplate" IS 'Profiles for dmp descriptions'; -- @@ -1020,11 +1036,19 @@ ALTER TABLE ONLY public."DatasetProfileViewstyle" -- --- Name: DatasetProfile DatasetProfile_pkey; Type: CONSTRAINT; Schema: public; Owner: :POSTGRES_USER +-- Name: DescriptionTemplateType DescriptionTemplateType_pkey; Type: CONSTRAINT; Schema: public; Owner: :POSTGRES_USER -- -ALTER TABLE ONLY public."DatasetProfile" - ADD CONSTRAINT "DatasetProfile_pkey" PRIMARY KEY ("ID"); +ALTER TABLE ONLY public."DescriptionTemplateType" + ADD CONSTRAINT "DescriptionTemplateType_pkey" PRIMARY KEY ("ID"); + + +-- +-- Name: DescriptionTemplate DescriptionTemplate_pkey; Type: CONSTRAINT; Schema: public; Owner: :POSTGRES_USER +-- + +ALTER TABLE ONLY public."DescriptionTemplate" + ADD CONSTRAINT "DescriptionTemplate_pkey" PRIMARY KEY ("ID"); -- @@ -1260,7 +1284,7 @@ ALTER TABLE ONLY public."DMP" -- ALTER TABLE ONLY public."DMPDatasetProfile" - ADD CONSTRAINT "DMPDatasetProfile_datasetprofile_fkey" FOREIGN KEY (datasetprofile) REFERENCES public."DatasetProfile"("ID"); + ADD CONSTRAINT "DMPDatasetProfile_datasetprofile_fkey" FOREIGN KEY (datasetprofile) REFERENCES public."DescriptionTemplate"("ID"); -- @@ -1340,7 +1364,7 @@ ALTER TABLE ONLY public."DatasetDataRepository" -- ALTER TABLE ONLY public."Dataset" - ADD CONSTRAINT "DatasetDatasetProfileReference" FOREIGN KEY ("Profile") REFERENCES public."DatasetProfile"("ID"); + ADD CONSTRAINT "DatasetDatasetProfileReference" FOREIGN KEY ("Profile") REFERENCES public."DescriptionTemplate"("ID"); -- @@ -1375,6 +1399,14 @@ ALTER TABLE ONLY public."DatasetService" ADD CONSTRAINT "DatasetServiceServiceReference" FOREIGN KEY ("Service") REFERENCES public."Service"("ID"); +-- +-- Name: DescriptionTemplate DescriptionTemplateTypeReference; Type: FK CONSTRAINT; Schema: public; Owner: :POSTGRES_USER +-- + +ALTER TABLE ONLY public."DescriptionTemplate" + ADD CONSTRAINT "DescriptionTemplateTypeReference" FOREIGN KEY ("Type") REFERENCES public."DescriptionTemplateType"("ID"); + + -- -- Name: Lock LockUserReference; Type: FK CONSTRAINT; Schema: public; Owner: :POSTGRES_USER -- @@ -1395,7 +1427,7 @@ ALTER TABLE ONLY public."Notification" -- ALTER TABLE ONLY public."UserDatasetProfile" - ADD CONSTRAINT "UserDatasetProfile_datasetProfile_fkey" FOREIGN KEY ("datasetProfile") REFERENCES public."DatasetProfile" ("ID"); + ADD CONSTRAINT "UserDatasetProfile_datasetProfile_fkey" FOREIGN KEY ("datasetProfile") REFERENCES public."DescriptionTemplate" ("ID"); -- -- Name: UserDatasetProfile UserDatasetProfile_user_key; Type: FK CONSTRAINT; Schema: public; Owner: :POSTGRES_USER diff --git a/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql b/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql new file mode 100644 index 000000000..2df4e63a1 --- /dev/null +++ b/dmp-db-scema/updates/00.00.013_Add_Description_Template_Type_table.sql @@ -0,0 +1,20 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.013'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + + +CREATE TABLE public."DescriptionTemplateType" +( + "ID" uuid NOT NULL, + "Name" character varying(250) NOT NULL, + "Status" smallint DEFAULT 0 NOT NULL, + CONSTRAINT "DescriptionTemplateType_pkey" PRIMARY KEY ("ID") +); + +/*ALTER TABLE public."DescriptionTemplateType" OWNER TO :POSTGRES_USER;*/ + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.013', '2023-06-21 12:00:00.000000+02', now(), 'Add Description Template Type table.'); + +END$$; diff --git a/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql b/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql new file mode 100644 index 000000000..9531c7e91 --- /dev/null +++ b/dmp-db-scema/updates/00.00.014_Rename_DatasetProfile_and_add_Type_column.sql @@ -0,0 +1,29 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.014'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +ALTER TABLE public."DatasetProfile" +RENAME TO "DescriptionTemplate"; + +ALTER TABLE public."DescriptionTemplate" +ADD COLUMN "Type" uuid; + +INSERT INTO public."DescriptionTemplateType" ("ID", "Name", "Status") +VALUES ('709a8400-10ca-11ee-be56-0242ac120002', 'Dataset', 1); + +UPDATE public."DescriptionTemplate" SET "Type" = '709a8400-10ca-11ee-be56-0242ac120002'; + +ALTER TABLE public."DescriptionTemplate" +ALTER COLUMN "Type" SET NOT NULL; + +ALTER TABLE ONLY public."DescriptionTemplate" + ADD CONSTRAINT "DescriptionTemplate_type_fkey" FOREIGN KEY ("Type") REFERENCES public."DescriptionTemplateType"("ID"); + +ALTER TABLE "UserDatasetProfile" +RENAME COLUMN "datasetProfile" TO "descriptionTemplate"; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.014', '2023-06-21 12:00:00.000000+02', now(), 'Rename DatasetProfile Table to DescriptionTemplate and add column Type referencing the DescriptionTemplateType.'); + +END$$; diff --git a/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql new file mode 100644 index 000000000..b6729b9fe --- /dev/null +++ b/dmp-db-scema/updates/00.00.015_Add_new_column_to_Dataset_and_DMPDatasetProfile.sql @@ -0,0 +1,15 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.015'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +ALTER TABLE public."Dataset" +ADD COLUMN "DmpSectionIndex" integer; + +ALTER TABLE public."DMPDatasetProfile" +ADD COLUMN "data" text; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.015', '2023-09-01 12:00:00.000000+02', now(), 'Add column DmpSectionIndex to Dataset table and data to DMPDatasetProfile.'); + +END$$; \ No newline at end of file diff --git a/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql new file mode 100644 index 000000000..7a5764bdd --- /dev/null +++ b/dmp-db-scema/updates/00.00.016_Insert_default_blueprint_and_add_dmpSectionIndex_to datasets.sql @@ -0,0 +1,20 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.016'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +INSERT INTO public."DMPProfile" VALUES ('86635178-36a6-484f-9057-a934e4eeecd5', 'Dmp Default Blueprint', '
',1, now(),now()); +UPDATE public."DMP" SET "Profile" = '86635178-36a6-484f-9057-a934e4eeecd5' 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-db-scema/updates/00.00.017_Make_grant_not_null.sql b/dmp-db-scema/updates/00.00.017_Make_grant_not_null.sql new file mode 100644 index 000000000..bf162c963 --- /dev/null +++ b/dmp-db-scema/updates/00.00.017_Make_grant_not_null.sql @@ -0,0 +1,12 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.017'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +ALTER TABLE public."DMP" + ALTER COLUMN "Grant" DROP NOT NULL; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.017', '2023-09-18 12:00:00.000000+02', now(), 'Make grant column of dmp table not null.'); + +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/app.component.html b/dmp-frontend/src/app/app.component.html index 87b6099ed..4fdd72aef 100644 --- a/dmp-frontend/src/app/app.component.html +++ b/dmp-frontend/src/app/app.component.html @@ -25,7 +25,4 @@ - + \ No newline at end of file diff --git a/dmp-frontend/src/app/app.component.scss b/dmp-frontend/src/app/app.component.scss index ddc6df33c..fd01ca382 100644 --- a/dmp-frontend/src/app/app.component.scss +++ b/dmp-frontend/src/app/app.component.scss @@ -40,3 +40,70 @@ ::ng-deep .mat-chip { height: auto !important; } + +.notification-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; + } +} + +.notification-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; +} + +.notification-title { + text-align: left; + font-weight: 400; + font-size: 14px; + color: #ffffff; + opacity: 0.75; +} + +.notification-subtitle { + text-align: left; + color: #ffffff; + font-weight: 700; + font-size: 16px; + opacity: 1; + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; +} +.notification-link { + color: #ffffff; + text-decoration: underline; +} + +.notification-save-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); +} \ No newline at end of file diff --git a/dmp-frontend/src/app/app.component.ts b/dmp-frontend/src/app/app.component.ts index 8eb8b023f..0d3cc7dc0 100644 --- a/dmp-frontend/src/app/app.component.ts +++ b/dmp-frontend/src/app/app.component.ts @@ -20,6 +20,8 @@ import { MatomoInjector } from 'ngx-matomo'; import { MatomoService } from './core/services/matomo/matomo-service'; import { SideNavService } from './core/services/sidenav/side-nav.sevice'; import { MatSidenav } from '@angular/material/sidenav'; +import { runInThisContext } from 'vm'; +import * as moment from 'moment'; declare const gapi: any; @@ -39,7 +41,7 @@ export class AppComponent implements OnInit, AfterViewInit { private statusChangeSubscription: Subscription; onlySplash = true; - @ViewChild('sidenav') sidenav:MatSidenav; + @ViewChild('sidenav') sidenav: MatSidenav; constructor( private router: Router, @@ -52,7 +54,7 @@ export class AppComponent implements OnInit, AfterViewInit { private cookieService: CookieService, private ccService: NgcCookieConsentService, private language: LanguageService, - private configurationService: ConfigurationService, + public configurationService: ConfigurationService, private location: Location, private matomoService: MatomoService, private sidenavService: SideNavService @@ -63,34 +65,34 @@ export class AppComponent implements OnInit, AfterViewInit { } ngAfterViewInit(): void { setTimeout(() => { - this.sideNavSubscription = this.sidenavService.status().subscribe(isopen=>{ + this.sideNavSubscription = this.sidenavService.status().subscribe(isopen => { const hamburger = document.getElementById('hamburger'); - if(isopen){ + if (isopen) { //update value of hamburfer - if(!hamburger){//try later + if (!hamburger) {//try later setTimeout(() => { - const hamburger = document.getElementById('hamburger'); - if(hamburger){ - hamburger.classList.add('change'); + const hamburger = document.getElementById('hamburger'); + if (hamburger) { + hamburger.classList.add('change'); } }, 300); - }else{ + } else { hamburger.classList.add('change'); } this.sidenav.open() - }else{//closed - if(!hamburger){//try later + } else {//closed + if (!hamburger) {//try later setTimeout(() => { - const hamburger = document.getElementById('hamburger'); - if(hamburger){ + const hamburger = document.getElementById('hamburger'); + if (hamburger) { hamburger.classList.remove('change'); } }, 300); - }else{ + } else { hamburger.classList.remove('change'); } this.sidenav.close(); - + } }); }); @@ -120,8 +122,8 @@ export class AppComponent implements OnInit, AfterViewInit { } if (!this.cookieService.check("cookiesConsent")) { // this.cookieService.set("cookiesConsent", "false", 356); - this.cookieService.set("cookiesConsent", "false", 356,null,null,false, 'Lax'); - + this.cookieService.set("cookiesConsent", "false", 356, null, null, false, 'Lax'); + } this.hasBreadCrumb = this.router.events.pipe( @@ -155,7 +157,7 @@ export class AppComponent implements OnInit, AfterViewInit { this.statusChangeSubscription = this.ccService.statusChange$.subscribe((event: NgcStatusChangeEvent) => { if (event.status == "dismiss") { // this.cookieService.set("cookiesConsent", "true", 365); - this.cookieService.set("cookiesConsent", "true", 356,null,null,false, 'Lax'); + this.cookieService.set("cookiesConsent", "true", 356, null, null, false, 'Lax'); } }); @@ -177,7 +179,7 @@ export class AppComponent implements OnInit, AfterViewInit { } this.ccService.destroy(); this.ccService.init(this.ccService.getConfig()); - }); + }); } translateTitle(ttl: string) { @@ -196,7 +198,7 @@ export class AppComponent implements OnInit, AfterViewInit { ngOnDestroy() { this.statusChangeSubscription.unsubscribe(); - if(this.sideNavSubscription){ + if (this.sideNavSubscription) { this.sideNavSubscription.unsubscribe(); } } 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..8f2d70106 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,8 @@ import { UserInfoListingModel } from "../../user/user-info-listing"; export interface DatasetProfile { label: string; + type: string; + enablePrefilling: boolean; sections: Section[]; pages: Page[]; status: number; diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/auth-type.enum.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/auth-type.enum.ts new file mode 100644 index 000000000..9f26507c7 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/auth-type.enum.ts @@ -0,0 +1,3 @@ +export enum AuthType { + BEARER = 'Bearer' +} diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts index 526c17f37..c66d04173 100644 --- a/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/field-data/field-data.ts @@ -12,11 +12,22 @@ export interface AutoCompleteFieldData extends FieldData { multiAutoComplete: boolean; } +export interface AuthAutoCompleteData extends FieldData { + url: string; + method: string; + body: string; + path: string; + type: string; +} + export interface AutoCompleteSingleData extends FieldData { url: string; optionsRoot: string; autoCompleteOptions: FieldDataOption; autocompleteType: number; + hasAuth: boolean; + method: string; + auth: AuthAutoCompleteData; } export interface CheckBoxFieldData extends FieldData { diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/html-method.enum.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/html-method.enum.ts new file mode 100644 index 000000000..ed63f9540 --- /dev/null +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/html-method.enum.ts @@ -0,0 +1,6 @@ +export enum HtmlMethod { + GET = 'GET', + POST = 'POST', + PUT = 'PUT', + PATCH = 'PATCH' +} diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts b/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts index 9724ad28e..5cac63659 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-id.model.ts @@ -9,8 +9,15 @@ export class DatasetIdModel { try{ const parsed = JSON.parse(data); if (!isNullOrUndefined(parsed)) { - this.identifier = parsed.identifier; - this.type = parsed.type; + if(typeof parsed !== 'string'){ + this.identifier = parsed.identifier; + this.type = parsed.type; + } + else{ + const parsedObjectFromString = JSON.parse(parsed); + this.identifier = parsedObjectFromString.identifier; + this.type = parsedObjectFromString.type; + } } } catch(error){ diff --git a/dmp-frontend/src/app/core/model/dataset/dataset-profile.ts b/dmp-frontend/src/app/core/model/dataset/dataset-profile.ts index d67dce6b0..7e6708dfb 100644 --- a/dmp-frontend/src/app/core/model/dataset/dataset-profile.ts +++ b/dmp-frontend/src/app/core/model/dataset/dataset-profile.ts @@ -5,6 +5,12 @@ export interface DatasetProfileModel { description: string; } +export interface DatasetProfileWithPrefillingModel { + id: string; + label: string; + enablePrefilling: boolean; +} + // export class DatasetProfileModel implements Serializable { // public id: String; // public label: String; 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/dataset/prefilling.ts b/dmp-frontend/src/app/core/model/dataset/prefilling.ts index cc3e36a4b..978dfe1eb 100644 --- a/dmp-frontend/src/app/core/model/dataset/prefilling.ts +++ b/dmp-frontend/src/app/core/model/dataset/prefilling.ts @@ -1,5 +1,7 @@ export interface Prefilling { pid: string; name: string; + data: any; + key: string; tag: string; } 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-extra-field.ts b/dmp-frontend/src/app/core/model/dmp/dmp-extra-field.ts new file mode 100644 index 000000000..4d789e64d --- /dev/null +++ b/dmp-frontend/src/app/core/model/dmp/dmp-extra-field.ts @@ -0,0 +1,4 @@ +export interface DmpExtraField { + id: string; + value: string; +} \ 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..a186597c1 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -1,23 +1,22 @@ -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"; +import { DmpExtraField } from "./dmp-extra-field"; export interface DmpModel { id: string; label: string; groupId: String; - profile: String; + profile: DmpProfile; version: number; status: DmpStatus; lockable: boolean; @@ -27,15 +26,21 @@ export interface DmpModel { funder: FunderModel; datasets: DatasetWizardModel[]; datasetsToBeFinalized: string[]; - profiles: DmpProfile[]; + profiles: DmpDatasetProfile[]; organisations: OrganizationModel[]; researchers: ResearcherModel[]; associatedUsers: UserModel[]; users: UserInfoListingModel[]; creator: UserModel; - definition: DmpProfileDefinition; + extraFields: Array; dynamicFields: Array; modified: Date; extraProperties: Map; language: String; } + + +export interface DmpProfile { + id: string; + label: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts b/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts new file mode 100644 index 000000000..683dba6fa --- /dev/null +++ b/dmp-frontend/src/app/core/model/saml2/AuthnRequestModel.ts @@ -0,0 +1,6 @@ +export interface AuthnRequestModel { + authnRequestXml: string; + relayState: string; + algorithm: string; + signature: string; +} \ No newline at end of file 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/dataset-profile/dataset-profile-criteria.ts b/dmp-frontend/src/app/core/query/dataset-profile/dataset-profile-criteria.ts index b9bbd9b5e..b447f336b 100644 --- a/dmp-frontend/src/app/core/query/dataset-profile/dataset-profile-criteria.ts +++ b/dmp-frontend/src/app/core/query/dataset-profile/dataset-profile-criteria.ts @@ -3,6 +3,7 @@ import { BaseCriteria } from "../base-criteria"; export class DatasetProfileCriteria extends BaseCriteria { public id: String; public groupIds: string[]; + public ids: string[]; public allVersions: boolean; public finalized: boolean = true; public status: number; diff --git a/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts b/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts index d511e9432..f32a40cd6 100644 --- a/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts +++ b/dmp-frontend/src/app/core/query/dataset/daatset-external-autocomplete-criteria.ts @@ -4,5 +4,8 @@ import { BaseCriteria } from "../base-criteria"; export class DatasetExternalAutocompleteCriteria extends BaseCriteria { public profileID: String; public fieldID: String; - public autocompleteOptions: AutoCompleteSingleData; +} + +export class DatasetExternalAutocompleteOptionsCriteria extends BaseCriteria { + public autoCompleteSingleDataList: AutoCompleteSingleData[]; } \ 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..0d460ba89 --- /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 { + public status?: number; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts index 1c21402b9..8b6e134db 100644 --- a/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts +++ b/dmp-frontend/src/app/core/query/recent-activity/recent-activity-criteria.ts @@ -2,5 +2,6 @@ import { RecentActivityOrder } from '@app/core/common/enum/recent-activity-order import { BaseCriteria } from '../base-criteria'; export class RecentActivityCriteria extends BaseCriteria{ + public status?: Number; public order: RecentActivityOrder = RecentActivityOrder.MODIFIED; } diff --git a/dmp-frontend/src/app/core/services/auth/auth.service.ts b/dmp-frontend/src/app/core/services/auth/auth.service.ts index b921df883..53355056d 100644 --- a/dmp-frontend/src/app/core/services/auth/auth.service.ts +++ b/dmp-frontend/src/app/core/services/auth/auth.service.ts @@ -38,7 +38,7 @@ export class AuthService extends BaseService { this.headers = this.headers.set('Accept', 'application/json'); } - private clear(): void { + public clear(): void { localStorage.removeItem('principal'); } diff --git a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts index 469f1fce9..8de302ae1 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -101,6 +101,21 @@ export class ConfigurationService extends BaseComponent { return this._maxFileSizeInMB; } + private _newReleaseNotificationLink: number; + get newReleaseNotificationLink(): number { + return this._newReleaseNotificationLink; + } + + private _newReleaseNotificationExpires: number; + get newReleaseNotificationExpires(): number { + return this._newReleaseNotificationExpires; + } + + private _newReleaseNotificationVersionCode: number; + get newReleaseNotificationVersionCode(): number { + return this._newReleaseNotificationVersionCode; + } + public loadConfiguration(): Promise { return new Promise((r, e) => { @@ -146,6 +161,9 @@ export class ConfigurationService extends BaseComponent { this._matomoSiteId = config.matomo.siteId; } this._maxFileSizeInMB = config.maxFileSizeInMB; + this._newReleaseNotificationExpires = config.newReleaseNotification?.expires; + this._newReleaseNotificationLink = config.newReleaseNotification?.link; + this._newReleaseNotificationVersionCode = config.newReleaseNotification?.versionCode; } } diff --git a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts index bcbfd2630..48e7348cf 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset-external-autocomplete.service.ts @@ -2,7 +2,7 @@ import { HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; import { Observable, of } from 'rxjs'; import { environment } from '../../../../environments/environment'; -import { DatasetExternalAutocompleteCriteria } from '../../query/dataset/daatset-external-autocomplete-criteria'; +import { DatasetExternalAutocompleteCriteria, DatasetExternalAutocompleteOptionsCriteria } from '../../query/dataset/daatset-external-autocomplete-criteria'; import { RequestItem } from '../../query/request-item'; import { DatasetProfileService } from '../dataset-profile/dataset-profile.service'; import { ConfigurationService } from '../configuration/configuration.service'; @@ -17,7 +17,7 @@ export class DatasetExternalAutocompleteService { private httpClient: HttpClient, private datasetProfileService: DatasetProfileService, private configurationService: ConfigurationService) { - this.actionUrl = configurationService.server + 'datasets/'; + this.actionUrl = configurationService.server + '/'; } getDatasetProfileById(datasetProfileID) { @@ -28,14 +28,8 @@ export class DatasetExternalAutocompleteService { return this.httpClient.post(this.configurationService.server + 'search/autocomplete', lookUpItem); } - queryApi(requestItem: RequestItem):Observable{ //TODO - - return of([ - { - label:'Preview not supported yet', - source:'' - } - ]); + queryApi(lookUpItem: RequestItem): Observable{ + return this.httpClient.post(this.configurationService.server + 'search/autocompleteOptions', lookUpItem); } } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts index 418196418..f62f7d16a 100644 --- a/dmp-frontend/src/app/core/services/dataset/dataset.service.ts +++ b/dmp-frontend/src/app/core/services/dataset/dataset.service.ts @@ -1,10 +1,9 @@ import { Injectable } from '@angular/core'; import { Observable } from 'rxjs'; -import { environment } from '../../../../environments/environment'; import { DataTableData } from '../../model/data-table/data-table-data'; import { DataTableRequest } from '../../model/data-table/data-table-request'; import { DatasetListingModel } from '../../model/dataset/dataset-listing'; -import { DatasetProfileModel } from '../../model/dataset/dataset-profile'; +import { DatasetProfileModel, DatasetProfileWithPrefillingModel } from '../../model/dataset/dataset-profile'; import { DatasetCriteria } from '../../query/dataset/dataset-criteria'; import { ExploreDatasetCriteriaModel } from '../../query/explore-dataset/explore-dataset-criteria'; import { BaseHttpService } from '../http/base-http.service'; @@ -43,6 +42,10 @@ export class DatasetService { return this.http.post(this.configurationSevice.server + 'datasetprofiles/getAll', dataTableRequest); } + getDatasetProfilesWithPrefilling(dataTableRequest: DataTableRequest): Observable { + return this.http.post(this.configurationSevice.server + 'datasetprofiles/getAllWithPrefilling', dataTableRequest); + } + getDatasetProfilesUsedPaged(dataTableRequest: DataTableRequest) { return this.http.post>(this.actionUrl + 'datasetProfilesUsedByDatasets/paged', dataTableRequest); } 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..de242c230 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 }); @@ -52,6 +67,14 @@ export class DmpProfileService { return this.http.post(this.actionUrl + "upload", formData, { params: params }); } + clone(id: string): Observable { + return this.http.post(this.actionUrl + 'clone/' + id, { headers: this.headers }); + } + + delete(id: string): Observable { + return this.http.delete(this.actionUrl + id, { headers: this.headers }); + } + externalAutocomplete(lookUpItem: RequestItem): Observable { return this.httpClient.post(this.actionUrl + 'search/autocomplete', lookUpItem); } diff --git a/dmp-frontend/src/app/core/services/prefilling.service.ts b/dmp-frontend/src/app/core/services/prefilling.service.ts index 3d5527303..600a187f9 100644 --- a/dmp-frontend/src/app/core/services/prefilling.service.ts +++ b/dmp-frontend/src/app/core/services/prefilling.service.ts @@ -15,11 +15,15 @@ export class PrefillingService { this.actionUrl = configurationService.server + 'prefilling/'; } - public getPrefillingList(like: string, configId: string): Observable { - return this.http.get(this.actionUrl + 'list?configId=' + encodeURIComponent(configId) + '&like=' + encodeURIComponent(like), { headers: this.headers }); + public getPrefillingList(like: string): Observable { + return this.http.get(this.actionUrl + 'list?like=' + encodeURIComponent(like), { headers: this.headers }); } public getPrefillingDataset(pid: string, profileId: string, configId: string): Observable { - return this.http.get(this.actionUrl + '/generate/' + encodeURIComponent(pid) + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), { headers: this.headers }); + return this.http.get(this.actionUrl + 'generate/' + encodeURIComponent(pid) + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), { headers: this.headers }); + } + + public getPrefillingDatasetUsingData(data: any, profileId: string, configId: string): Observable { + return this.http.post(this.actionUrl + 'generateUsingData' + '?configId=' + encodeURIComponent(configId) + '&profileId=' + encodeURIComponent(profileId), data, { headers: this.headers }); } } diff --git a/dmp-frontend/src/app/core/services/saml-login.service.ts b/dmp-frontend/src/app/core/services/saml-login.service.ts index c3db23658..d052205d6 100644 --- a/dmp-frontend/src/app/core/services/saml-login.service.ts +++ b/dmp-frontend/src/app/core/services/saml-login.service.ts @@ -4,6 +4,7 @@ import { ConfigurationService } from './configuration/configuration.service'; import { BaseHttpService } from './http/base-http.service'; import { Observable } from 'rxjs'; import { BaseComponent } from '@common/base/base.component'; +import { AuthnRequestModel } from '../model/saml2/AuthnRequestModel'; @Injectable() export class SamlLoginService extends BaseComponent { @@ -27,8 +28,8 @@ export class SamlLoginService extends BaseComponent { return routeParams.has('spId') ? routeParams.get('spId') : ''; } - getAuthnRequest(configurableLoginId: string): Observable { - return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); + getAuthnRequest(configurableLoginId: string): Observable { + return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); } } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts b/dmp-frontend/src/app/core/services/utilities/enum-utils.service.ts index 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/library/auto-complete/multiple/multiple-auto-complete-configuration.ts b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete-configuration.ts index 6c88bba4a..37a9422ed 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete-configuration.ts +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete-configuration.ts @@ -37,5 +37,6 @@ export interface MultipleAutoCompleteConfiguration { autoSelectFirstOptionOnBlur?: boolean; appendClassToItem?: {class: string, applyFunc: (item:any) => boolean}[]; + canRemoveItem?: (selectedItem: any) => boolean; } diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts index f39413c8f..b69c9971b 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.ts @@ -220,6 +220,9 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp ngOnChanges(changes: SimpleChanges) { if (changes['configuration'] && changes['configuration'].isFirstChange) { this.getSelectedItems(this.value); + } + if (changes['value'] && !changes['value'].isFirstChange()) { + this.getSelectedItems(this.value); } } @@ -480,6 +483,10 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp if (event != null) { event.stopPropagation(); } + if (this.configuration.canRemoveItem != null && !this.configuration.canRemoveItem(item)) { + event.stopPropagation(); + return; + } const valueToDelete = this._valueToAssign(item); this.value = this.value.filter(x => this.stringify(x) !== this.stringify(valueToDelete)); //TODO, maybe we need to implement equality here differently. this.optionRemoved.emit(item); diff --git a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts index edaf1dd56..54f5702eb 100644 --- a/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts +++ b/dmp-frontend/src/app/library/rich-text-editor/rich-text-editor.component.ts @@ -10,7 +10,7 @@ import {FormControl} from "@angular/forms"; [config]="editorConfig" [formControlName]="controlName" placeholder="{{(placeholder? (placeholder | translate) : '') + (required ? ' *': '')}}" (paste)="pasteWithoutFormatting($event)"> - close + close `, styleUrls: ['./rich-text-editor.component.scss'] @@ -47,7 +47,8 @@ export class RichTextEditorComponent { { name: 'H3 header', class: '', tag: 'h3' }, { name: 'H4 header', class: '', tag: 'h4' }, { name: 'H5 header', class: '', tag: 'h5'}, - { name: 'H6 header', class: '', tag: 'h6'} + { name: 'H6 header', class: '', tag: 'h6'}, + { name: 'Highlight', class: 'highlight', tag: ''} ], toolbarHiddenButtons: [ [ diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-auth-field-data.model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-auth-field-data.model.ts new file mode 100644 index 000000000..f01ea3ba8 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-auth-field-data.model.ts @@ -0,0 +1,35 @@ +import { FormGroup, Validators } from "@angular/forms"; +import { FieldDataEditorModel } from "./field-data-editor-model"; +import { AuthAutoCompleteData, AutoCompleteSingleData } from "@app/core/model/dataset-profile-definition/field-data/field-data"; + +export class AuthFieldEditorModel extends FieldDataEditorModel { + url: string; + method: string; + body: string; + path: string; + type: string; + + buildForm(disabled: boolean = false, skipDisable: Array = []): FormGroup { + const formGroup = this.formBuilder.group({ + method: [{ value: this.method, disabled: (disabled && !skipDisable.includes('AuthFieldEditorModel.method')) }], + url: [{ value: this.url, disabled: (disabled && !skipDisable.includes('AuthFieldEditorModel.url')) }, [Validators.required]], + body: [{ value: this.body, disabled: (disabled && !skipDisable.includes('AuthFieldEditorModel.body')) }], + path: [{ value: this.path, disabled: (disabled && !skipDisable.includes('AuthFieldEditorModel.path')) }, [Validators.required]], + type: [{ value: this.type, disabled: (disabled && !skipDisable.includes('AuthFieldEditorModel.type')) }, [Validators.required]] + }); + + return formGroup; + } + + fromModel(item: AuthAutoCompleteData): AuthFieldEditorModel { + if (item) { + this.url = item.url; + this.method = item.method; + this.body = item.body; + this.path = item.path; + this.type = item.type; + } + return this; + } + +} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts index 3bffd86d1..f53cf544c 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data.ts @@ -3,6 +3,7 @@ import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profil import { FieldDataOptionEditorModel } from './field-data-option-editor-model'; import { FormGroup, Validators } from '@angular/forms'; import { AutoCompleteFieldData, AutoCompleteSingleData } from '@app/core/model/dataset-profile-definition/field-data/field-data'; +import { AuthFieldEditorModel } from './auto-complete-auth-field-data.model'; export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel { @@ -11,6 +12,9 @@ export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel = []): FormGroup { @@ -18,9 +22,12 @@ export class AutoCompleteSingleDataEditorModel extends FieldDataEditorModel
- +
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts index 4f5e7b641..12c3754f6 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.ts @@ -69,6 +69,8 @@ export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent i @Input() indexPath: string; @Input() viewOnly: boolean; + @Input() datasetProfileId?: string; + @Input() numbering: string; @Input() hasFocus: boolean = false; @ViewChild("inputs") inputs: TransitionGroupComponent; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.html index 6037dbc05..e346928aa 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.html @@ -11,41 +11,47 @@ [formControl]="form.get('data').get('label')"> - +
{{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-SOURCE-TITLE' | translate}}
- - +
- warning_amber {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.ERROR-MESSAGES.FIELD-OTHER-SOURCES-REQUIRED'| translate}}
- +
- +
- + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}} + + {{method.value}} + - + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -70,6 +76,37 @@ {{'GENERAL.VALIDATION.REQUIRED' | translate}} + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-HAS-AUTH' | translate}} +
+ + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-METHOD' | translate}} + + {{method.value}} + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-URL' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-TYPE' | translate}} + + {{type.value}} + + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-OPTIONS-ROOT' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.FIELDS.FIELD-AUTOCOMPLETE-AUTH-BODY' | translate}} + + {{'GENERAL.VALIDATION.REQUIRED' | translate}} + +
+
diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts index 06224ee6f..1171059cd 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/auto-complete/dataset-profile-editor-auto-complete-field.component.ts @@ -3,6 +3,8 @@ import { FormGroup, FormArray, AbstractControl } from '@angular/forms'; import { DatasetProfileComboBoxType } from '../../../../../../../core/common/enum/dataset-profile-combo-box-type'; import { AutoCompleteFieldDataEditorModel } from '../../../../admin/field-data/auto-complete-field-data-editor-model'; import { AutoCompleteSingleDataEditorModel } from '@app/ui/admin/dataset-profile/admin/field-data/auto-complete-single-data'; +import { HtmlMethod } from '@app/core/model/dataset-profile-definition/html-method.enum'; +import { AuthType } from '@app/core/model/dataset-profile-definition/auth-type.enum'; @Component({ selector: 'app-dataset-profile-editor-auto-complete-field-component', @@ -11,6 +13,9 @@ import { AutoCompleteSingleDataEditorModel } from '@app/ui/admin/dataset-profile }) export class DatasetProfileEditorAutoCompleteFieldComponent implements OnInit { + public htmlMethods = HtmlMethod; + public authTypes = AuthType; + @Input() form: FormGroup; private data: AutoCompleteFieldDataEditorModel = new AutoCompleteFieldDataEditorModel(); multiForm: FormArray; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/word-list/dataset-profile-editor-word-list-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/word-list/dataset-profile-editor-word-list-field.component.html index 12d82cae4..58ea62fb2 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/word-list/dataset-profile-editor-word-list-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field-type/word-list/dataset-profile-editor-word-list-field.component.html @@ -30,7 +30,7 @@ diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html index 38426a3d6..d57310531 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.html @@ -74,7 +74,8 @@ + [hasFocus]="fieldset.get('id').value === selectedFieldSetId" + [datasetProfileId]="datasetProfileId"> diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts index 0e71dcc8c..82c46659a 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.ts @@ -26,6 +26,8 @@ export class DatasetProfileEditorSectionFieldSetComponent implements OnInit, OnC // @Input() numbering: string; @Input() tocentry: ToCEntry; + @Input() datasetProfileId?: string; + @Output() selectedEntryId = new EventEmitter(); @Output() dataNeedsRefresh = new EventEmitter (); @Output() removeFieldSet = new EventEmitter(); 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..79555f95f 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,8 @@ export class DatasetProfileEditorModel extends BaseFormModel { public status: number; public version: number; private description: string; + private type: string; + public enablePrefilling: boolean; private language: string; private users: UserInfoListingModel[] = []; @@ -22,6 +24,8 @@ 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.enablePrefilling = item.enablePrefilling; this.status = item.status; this.version = item.version; this.description = item.description; @@ -34,6 +38,8 @@ 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]], + enablePrefilling: [{ value: this.enablePrefilling, disabled: (disabled && !skipDisable.includes('DatasetProfileEditorModel.enablePrefilling')) }, []], 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 c0288f59d..aeaf7ec31 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,15 @@
-
1.4 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
+
1.5 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-PREFILLING'| translate}}
+
+ + {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DESCRIPTION-TEMPLATE-ENABLE-PREFILLING'| translate}} + +
+
+
+
1.6 {{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS'| translate}}
{{'DATASET-PROFILE-EDITOR.STEPS.GENERAL-INFO.DATASET-TEMPLATE-USERS-HINT'| translate}}
@@ -290,6 +311,7 @@ { + 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..9014940a1 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,9 @@ 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: 'clone/:cloneid', component: DmpProfileEditorComponent, canActivate: [AdminAuthGuard], data: { title: 'GENERAL.TITLES.DMP-BLUEPRINT-CLONE' } }, + { 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..034561b37 --- /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.sort((a, b) => a.ordinal - b.ordinal).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.sort((a, b) => a.ordinal - b.ordinal).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: [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; +// } +// } 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..bcd4c6328 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 @@ -2,7 +2,11 @@
-

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

+

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

+

+ {{'DMP-PROFILE-EDITOR.TITLE.NEW-PROFILE-CLONE' | translate}} + {{formGroup.get('label').value}} +

{{formGroup.get('label').value}}

@@ -18,7 +22,7 @@
+ [disabled]="!this.isFormValid()" type="button">{{'DMP-PROFILE-EDITOR.ACTIONS.FINALIZE' | translate }}
@@ -33,17 +37,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 +382,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 5cd76ceda..65c604863 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({ @@ -35,21 +49,45 @@ import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog export class DmpProfileEditorComponent extends BaseComponent implements AfterViewInit { isNew = true; + isClone = false; 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} + ]; + systemFieldListPerSection: Array> = new Array(); + descriptionTemplatesPerSection: 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,19 +99,32 @@ 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) => { this.dmpProfileId = params['id']; + const cloneId = params['cloneid']; 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(); + this.fillDescriptionTemplatesInMultAutocomplete(); + if (this.dmpBlueprintModel.status == DmpProfileStatus.Finalized) { this.formGroup.disable(); this.viewOnly = true } @@ -83,11 +134,29 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie url: '/dmp-profiles/' + this.dmpProfileId }]); }); + } else if (cloneId != null) { + this.isClone = true; + this.dmpProfileService.clone(cloneId).pipe(map(data => data as DmpBlueprint), takeUntil(this._destroyed)) + .subscribe( + data => { + this.dmpBlueprintModel = new DmpBlueprintEditor().fromModel(data); + this.dmpBlueprintModel.id = null; + this.dmpBlueprintModel.created = null; + this.dmpBlueprintModel.status = DmpProfileStatus.Draft; + this.formGroup = this.dmpBlueprintModel.buildForm(); + this.buildSystemFields(); + this.fillDescriptionTemplatesInMultAutocomplete(); + }, + error => this.onCallbackError(error) + ); } 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,20 +165,339 @@ 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).type); + } + }) + this.systemFieldListPerSection.push(systemFieldsInSection); + } + } + + fillDescriptionTemplatesInMultAutocomplete(){ + const sections = this.sectionsArray().controls.length; + for(let i = 0; i < sections; i++){ + let descriptionTemplatesInSection = new Array(); + this.descriptionTemplatesArray(i).controls.forEach((template) => { + descriptionTemplatesInSection.push({id: template.value.descriptionTemplateId, label: template.value.label, description: ""}); + }) + this.descriptionTemplatesPerSection.push(descriptionTemplatesInSection); + } + } + + checkForProfiles(event, sectionIndex: number) { + if (event.checked === false) { + this.descriptionTemplatesPerSection[sectionIndex] = new Array(); + this.descriptionTemplatesArray(sectionIndex).clear(); + } + } + + 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()); + this.systemFieldListPerSection.push(new Array()); + this.descriptionTemplatesPerSection.push(new Array()); + } + + removeSection(sectionIndex: number): void { + this.systemFieldListPerSection.splice(sectionIndex, 1); + this.descriptionTemplatesPerSection.splice(sectionIndex, 1); + this.sectionsArray().removeAt(sectionIndex); + this.sectionsArray().controls.forEach((section, index) => { + section.get('ordinal').setValue(index + 1); + }); + } + + 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); + this.fieldsArray(sectionIndex).controls.forEach((field, index) => { + field.get('ordinal').setValue(index + 1); + }); + } + + 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(type: SystemFieldType, sectionIndex: number): void { + if (this.systemFieldDisabled(type, sectionIndex)) return; + let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); + if (index == -1) { + this.systemFieldListPerSection[sectionIndex].push(type); + this.addSystemField(sectionIndex, type); + } + else { + this.systemFieldListPerSection[sectionIndex].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 { + let type: SystemFieldType = this.fieldsArray(sectionIndex).at(fieldIndex).get('type').value; + let index = this.systemFieldListPerSection[sectionIndex].indexOf(type); + this.systemFieldListPerSection[sectionIndex] = this.systemFieldListPerSection[sectionIndex].filter(types => types != type); + 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); + this.fieldsArray(sectionIndex).controls.forEach((field, index) => { + field.get('ordinal').setValue(index + 1); + }); + } + + dropSections(event: CdkDragDrop) { + moveItemInArray(this.sectionsArray().controls, event.previousIndex, event.currentIndex); + moveItemInArray(this.sectionsArray().value, event.previousIndex, event.currentIndex); + this.sectionsArray().controls.forEach((section, index) => { + section.get('ordinal').setValue(index + 1); + }); + moveItemInArray(this.systemFieldListPerSection, event.previousIndex, event.currentIndex); + moveItemInArray(this.descriptionTemplatesPerSection, 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) { + const profile: DescriptionTemplatesInSectionEditor = new DescriptionTemplatesInSectionEditor(); + profile.id = Guid.create().toString(); + profile.descriptionTemplateId = event.id; + profile.label = event.label; + this.descriptionTemplatesArray(sectionIndex).push(profile.buildForm()); + + const items = this.descriptionTemplatesPerSection[sectionIndex]; + items.push({id: event.id, label: event.label, description: ""}); + this.descriptionTemplatesPerSection[sectionIndex] = [...items]; + } + }); + } + + 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()); + } + + checkValidity() { + this.formService.touchAllFormFields(this.formGroup); + if (!this.isFormValid()) { return false; } + let errorMessages = []; + if(!this.hasTitle()) { + errorMessages.push("Title should be set."); + } + if(!this.hasDescription()) { + errorMessages.push("Description should be set."); + } + if(!this.hasDescriptionTemplates()) { + errorMessages.push("At least one section should have description templates."); + } + if(errorMessages.length > 0) { + this.showValidationErrorsDialog(undefined, errorMessages); + return false; + } + return true; } formSubmit(): void { - this.formService.touchAllFormFields(this.formGroup); - if (!this.isFormValid()) { return; } - this.onSubmit(); + if (this.checkValidity()) + this.onSubmit(); } public isFormValid() { return this.formGroup.valid; } + hasTitle(): boolean { + const dmpBlueprint: DmpBlueprint = this.formGroup.value; + return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.TEXT)); + } + + hasDescription(): boolean { + const dmpBlueprint: DmpBlueprint = this.formGroup.value; + return dmpBlueprint.definition.sections.some(section => section.fields.some(field => (field.category === FieldCategory.SYSTEM || field.category as unknown === 'SYSTEM') && field.type === SystemFieldType.HTML_TEXT)); + } + + hasDescriptionTemplates(): boolean { + const dmpBlueprint: DmpBlueprint = this.formGroup.value; + return dmpBlueprint.definition.sections.some(section => section.hasTemplates == true); + } + + 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 +525,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); @@ -190,13 +578,29 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie .subscribe( confirmed =>{ if(confirmed){ - this.formGroup.get('status').setValue(DmpProfileStatus.Deleted); - this.dmpProfileService.createDmp(this.formGroup.value) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onCallbackSuccess(), - error => this.onCallbackError(error) - ); + if(this.formGroup.get('status').value == DmpProfileStatus.Draft) { + this.formGroup.get('status').setValue(DmpProfileStatus.Deleted); + this.dmpProfileService.createBlueprint(this.formGroup.value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => this.onCallbackError(error) + ); + } + else { + this.dmpProfileService.delete(this.dmpProfileId) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCallbackSuccess(), + error => { + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.language.instant(error.message), SnackBarNotificationLevel.Error); + } + } + ); + } } } ) @@ -204,10 +608,10 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie } finalize() { - //const data = this.form.value; - this.formGroup.get('status').setValue(DmpProfileStatus.Finalized); - - this.onSubmit(); + if (this.checkValidity()) { + this.formGroup.get('status').setValue(DmpProfileStatus.Finalized); + this.onSubmit(); + } } downloadXML(): void { @@ -245,6 +649,7 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie this.addControl(formGroup); return true; } else { + this.removeControl(formGroup); return false; } } @@ -253,4 +658,9 @@ export class DmpProfileEditorComponent extends BaseComponent implements AfterVie if (formGroup.get('dataType').value == 3) formGroup.addControl('externalAutocomplete', new DmpProfileExternalAutoCompleteFieldDataEditorModel().buildForm()); } + + removeControl(formGroup: FormGroup) { + if (formGroup.get('dataType').value != 3) + formGroup.removeControl('externalAutocomplete'); + } } diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.html b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.html index 34dd7626d..f1a256ced 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.html +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.html @@ -1,11 +1,23 @@ -
-
-
- - - search - -
+
+
+
+ {{'CRITERIA.USERS.SHOW' | translate}}:
+ + + + {{'BLUEPRINT-STATUS.NONE' | translate}} + {{'BLUEPRINT-STATUS.DRAFT' | translate}} + {{'BLUEPRINT-STATUS.FINALIZED' | translate}} + + + +
+
+ + + search + +
diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.scss index 7389ee36f..9b64c055a 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.scss @@ -1,13 +1,17 @@ +.mat-form-field{ + display: inline-block !important; +} + +:host ::ng-deep .status-form-field .mat-form-field-wrapper { + background-color: white !important; + padding-bottom: 0 !important; +} :host ::ng-deep .search-form-field .mat-form-field-wrapper { background-color: white !important; padding-bottom: 0 !important; } -:host ::ng-deep .search-container .mat-form-field-appearance-outline .mat-form-field-infix { - padding: 0.3rem 0rem 0.6rem 0rem !important; -} -.dmp-criteria{ - margin-top: 3em; - margin-bottom: 0em; +:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { + padding: 0.3rem 0rem 0.6rem 0rem !important; } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts index 9e7cc3b8c..e80bea6b3 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dmp-profile-criteria.component.ts @@ -1,14 +1,10 @@ import { Component, Input, OnInit } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { GrantListingModel } from '@app/core/model/grant/grant-listing'; -import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria'; -import { DmpProfileCriteria } from '@app/core/query/dmp/dmp-profile-criteria'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; -import { DialodConfirmationUploadDmpProfiles } from '@app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component'; import { BaseCriteriaComponent } from '@app/ui/misc/criteria/base-criteria.component'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { TranslateService } from '@ngx-translate/core'; -import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-dmp-profile-criteria-component', @@ -17,11 +13,8 @@ import { takeUntil } from 'rxjs/operators'; }) export class DmpProfileCriteriaComponent extends BaseCriteriaComponent implements OnInit { - @Input() - showGrant: boolean; - public criteria: DmpProfileCriteria = new DmpProfileCriteria(); - filteringGrantsAsync = false; - filteredGrants: GrantListingModel[]; + public criteria: DmpBlueprintCriteria = new DmpBlueprintCriteria(); + constructor( private dmpProfileService: DmpProfileService, private dialog: MatDialog, @@ -32,10 +25,10 @@ export class DmpProfileCriteriaComponent extends BaseCriteriaComponent implement ngOnInit() { super.ngOnInit(); - if (this.criteria == null) { this.criteria = new DmpCriteria(); } + if (this.criteria == null) { this.criteria = new DmpBlueprintCriteria(); } } - setCriteria(criteria: DmpProfileCriteria): void { + setCriteria(criteria: DmpBlueprintCriteria): void { this.criteria = criteria; } 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..e138c7d8a 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,15 +13,20 @@
- +
+
+ +
+
+
- + @@ -30,6 +35,13 @@ {{row.label}} + + + + {{'DMP-PROFILE-LISTING.COLUMNS.CREATED' | translate}} + {{row.created | date:'short'}} + + @@ -41,14 +53,29 @@ - - - - {{'DMP-PROFILE-LISTING.COLUMNS.CREATED' | translate}} - {{row.created | date:'shortDate'}} - - + + + + + + + + + + + + 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..cac8ff4a9 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 @@ -1,6 +1,6 @@ import { DataSource } from '@angular/cdk/table'; -import { HttpClient } from '@angular/common/http'; +import { HttpClient, HttpErrorResponse } from '@angular/common/http'; import { Component, OnInit, ViewChild } from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; import { MatPaginator, PageEvent } from '@angular/material/paginator'; @@ -21,6 +21,11 @@ import { TranslateService } from '@ngx-translate/core'; import { merge as observableMerge, Observable, of as observableOf } from 'rxjs'; import { map, startWith, switchMap, takeUntil } from 'rxjs/operators'; import { DialodConfirmationUploadDmpProfiles } from './criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component'; +import { DmpBlueprintCriteria } from '@app/core/query/dmp/dmp-blueprint-criteria'; +import { DmpBlueprintListing } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint-listing'; +import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status'; +import * as FileSaver from 'file-saver'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; @Component({ @@ -35,11 +40,12 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit @ViewChild(DmpProfileCriteriaComponent, { static: true }) criteria: DmpProfileCriteriaComponent; dataSource: DatasetDataSource | null; - displayedColumns: String[] = ['label', 'status', 'created']; + displayedColumns: String[] = ['label', 'created', 'status', 'actions']; pageEvent: PageEvent; titlePrefix: String; dmpId: String; breadCrumbs: Observable; + dmpBlueprintStatus = DmpProfileStatus; statuses = [ { value: '0', viewValue: 'DMP-PROFILE-LISTING.STATUS.DRAFT' },// active @@ -71,7 +77,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' }]); }); @@ -81,12 +87,81 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit this.dataSource = new DatasetDataSource(this.dmpProfileService, this._paginator, this.sort, this.criteria); } + clone(id: string) { + this.router.navigate(['dmp-profiles/clone/' + id]); + } + rowClick(rowId: String) { this.router.navigate(['dmp-profiles/' + rowId]); } - getDefaultCriteria(): DmpProfileCriteria { - const defaultCriteria = new DmpProfileCriteria(); + downloadXML(dmpProfileId: string): void { + this.dmpProfileService.downloadXML(dmpProfileId) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/xml' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + FileSaver.saveAs(blob, filename); + }); + } + getFilenameFromContentDispositionHeader(header: string): string { + const regex: RegExp = new RegExp(/filename[^;=\n]*=((['"]).*?\2|[^;\n]*)/g); + + const matches = header.match(regex); + let filename: string; + for (let i = 0; i < matches.length; i++) { + const match = matches[i]; + if (match.includes('filename="')) { + filename = match.substring(10, match.length - 1); + break; + } else if (match.includes('filename=')) { + filename = match.substring(9); + break; + } + } + return filename; + } + + deleteTemplate(id: string) { + if (id) { + this.dialog.open(ConfirmationDialogComponent,{data:{ + isDeleteConfirmation: true, + confirmButton: this.languageService.instant('DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CONFIRM-BUTTON'), + cancelButton: this.languageService.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.CANCEL-BUTTON"), + message: this.languageService.instant("DMP-PROFILE-EDITOR.CONFIRM-DELETE-DIALOG.MESSAGE") + }}) + .afterClosed() + .subscribe( + confirmed =>{ + if(confirmed){ + this.dmpProfileService.delete(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Success); + this.refresh(); + }, + error => { + this.onCallbackError(error); + if (error.error.statusCode == 674) { + this.uiNotificationService.snackBarNotification(this.languageService.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DMP-BLUEPRINT-DELETE'), SnackBarNotificationLevel.Error); + } else { + this.uiNotificationService.snackBarNotification(this.languageService.instant(error.message), SnackBarNotificationLevel.Error); + } + } + ); + } + } + ) + } + } + + onCallbackError(errorResponse: HttpErrorResponse) { + this.uiNotificationService.snackBarNotification(errorResponse.message, SnackBarNotificationLevel.Warning); + } + + getDefaultCriteria(): DmpBlueprintCriteria { + const defaultCriteria = new DmpBlueprintCriteria(); return defaultCriteria; } @@ -142,7 +217,7 @@ export class DmpProfileListingComponent extends BaseComponent implements OnInit } } -export class DatasetDataSource extends DataSource { +export class DatasetDataSource extends DataSource { totalCount = 0; @@ -156,7 +231,7 @@ export class DatasetDataSource extends DataSource { } - connect(): Observable { + connect(): Observable { const displayDataChanges = [ this._paginator.page //this._sort.matSortChange @@ -168,9 +243,9 @@ export class DatasetDataSource extends DataSource { const startIndex = this._paginator.pageIndex * this._paginator.pageSize; let fields: Array = new Array(); if (this._sort.active) { fields = this._sort.direction === 'asc' ? ['+' + this._sort.active] : ['-' + this._sort.active]; } - const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); + const request = new DataTableRequest(startIndex, this._paginator.pageSize, { fields: fields }); request.criteria = this._criteria.criteria; - return this._service.getPaged(request); + return this._service.getPagedBlueprint(request); }), /*.catch((error: any) => { this._snackBar.openFromComponent(SnackBarNotificationComponent, { diff --git a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts index 4997571dd..00902cdfa 100644 --- a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts @@ -90,25 +90,18 @@ export class ConfigurableLoginComponent extends BaseComponent implements OnInit this.samlLoginService.getAuthnRequest(provider.configurableLoginId).pipe(takeUntil(this._destroyed)) .subscribe( authenticationRequest => { - const uint = new Uint8Array(authenticationRequest.length); - for (let i = 0, j = authenticationRequest.length; i < j; ++i) { - uint[i] = authenticationRequest.charCodeAt(i); + const uint = new Uint8Array(authenticationRequest.authnRequestXml.length); + for (let i = 0, j = authenticationRequest.authnRequestXml.length; i < j; ++i) { + uint[i] = authenticationRequest.authnRequestXml.charCodeAt(i); } const base64String = btoa(pk.deflateRaw(uint, { to: 'string' })); - const relayState = this.buildRelayState(provider.spEntityId, provider.configurableLoginId); - const url = provider.idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String); + const url = provider.idpUrl + '?SAMLRequest=' + encodeURIComponent(base64String) + '&RelayState=' + encodeURIComponent(authenticationRequest.relayState) + '&SigAlg=' + encodeURIComponent(authenticationRequest.algorithm) + '&Signature=' + encodeURIComponent(authenticationRequest.signature); window.location.href = url; } ); } } - buildRelayState(spId: string, configurableLoginId: string): string { - let uri = 'spId=' + spId; - uri += '&configurableLoginId=' + configurableLoginId; - return encodeURIComponent(uri); - } - public configurableLoginUser(code: string, state: string) { if (state !== (this.provider).state) { this.router.navigate(['/login']) diff --git a/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts b/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts index e11f9b1d9..dbff4c3d4 100644 --- a/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/merge-email-confirmation/merge-email-confirmation.component.ts @@ -1,6 +1,7 @@ import { Component, OnInit } from "@angular/core"; import { FormControl } from '@angular/forms'; import { ActivatedRoute, Router } from "@angular/router"; +import { AuthService } from "@app/core/services/auth/auth.service"; import { EmailConfirmationService } from '@app/core/services/email-confirmation/email-confirmation.service'; import { MergeEmailConfirmationService } from '@app/core/services/merge-email-confirmation/merge-email-confirmation.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; @@ -20,6 +21,7 @@ export class MergeEmailConfirmation extends BaseComponent implements OnInit { constructor( private emailConfirmationService: MergeEmailConfirmationService, + private authService: AuthService, private route: ActivatedRoute, private router: Router, private language: TranslateService, @@ -36,7 +38,13 @@ export class MergeEmailConfirmation extends BaseComponent implements OnInit { this.emailConfirmationService.emailConfirmation(token) .pipe(takeUntil(this._destroyed)) .subscribe( - result => this.onCallbackEmailConfirmationSuccess(), + result => { + const principal = this.authService.current(); + if(!principal || !result || (principal.email == result)) + this.authService.clear(); + this.uiNotificationService.snackBarNotification(this.language.instant('USER-PROFILE.MERGING-SUCCESS'), SnackBarNotificationLevel.Success); + this.onCallbackEmailConfirmationSuccess(); + }, error => this.onCallbackError(error) ) } else { diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index 795ff063d..70c24509a 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -1,8 +1,28 @@
-
-
+
+
+
+
+ clear +
+

{{'NEW-RELEASE-NOTIFICATION.HINT' | translate}}

+
+

{{'NEW-RELEASE-NOTIFICATION.TITLE' | translate}}

+

{{'NEW-RELEASE-NOTIFICATION.BODY' | translate}}

+ + +
clear @@ -22,165 +42,163 @@
- +
- -
-
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
- - - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
> - - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- -
-
-
-
- - - -
-
{{'DASHBOARD.PERSONAL-USAGE' | translate}}
-
- {{dashboardStatisticsData?.totalDataManagementPlanCount}}
- {{'DASHBOARD.DMPS' | translate}} -
- {{dashboardStatisticsData?.totalDataSetCount}}
- {{'DASHBOARD.DATASET-DESCRIPTIONS' | translate}} -
- {{dashboardStatisticsData?.totalGrantCount}}
- {{'DASHBOARD.GRANTS' | translate}} -
- {{dashboardStatisticsData?.totalOrganisationCount}}
- {{'DASHBOARD.RELATED-ORGANISATIONS' | translate}} +
+
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
+ + + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
+ + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
> + + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
+ + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
+ +
+
+
-
- -
-
+ + +
+
{{'DASHBOARD.PERSONAL-USAGE' | translate}}
+
+ {{dashboardStatisticsData?.totalDataManagementPlanCount}}
+ {{'DASHBOARD.DMPS' | translate}} +
+ {{dashboardStatisticsData?.totalDataSetCount}}
+ {{'DASHBOARD.DESCRIPTIONS' | translate}} +
+ {{dashboardStatisticsData?.totalGrantCount}}
+ {{'DASHBOARD.GRANTS' | translate}} +
+ {{dashboardStatisticsData?.totalOrganisationCount}}
+ {{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}
+
- -
-
- +
+
+ -
-
-
-
-
- clear -
-

{{'DASHBOARD.TITLE' | translate}}

-

{{'DASHBOARD.INFO-TEXT' | translate}}

-
-
- - - -
+
+
+
+
+
+ clear +
+

{{'DASHBOARD.TITLE' | translate}}

+

{{'DASHBOARD.INFO-TEXT' | translate}}

-
-
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
- - - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- - - -
{{'DASHBOARD.EMPTY-LIST' | translate}}
- -
-
+
+ + +
-
- -
-
{{'DASHBOARD.PUBLIC-USAGE' | translate}}
-
- {{dashboardStatisticsData?.totalDataManagementPlanCount}}
- {{'DASHBOARD.PUBLIC-DMPS' | translate}} -
- {{dashboardStatisticsData?.totalDataSetCount}}
- {{'DASHBOARD.PUBLIC-DATASETS' | translate}} -
- {{dashboardStatisticsData?.totalGrantCount}}
- {{'DASHBOARD.GRANTS' | translate}} -
- {{dashboardStatisticsData?.totalOrganisationCount}}
- {{'DASHBOARD.RELATED-ORGANISATIONS' | translate}} -
+
+
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
+ + + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
+ + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+
+ + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
+ +
+
+
+
+
+ +
+
{{'DASHBOARD.PUBLIC-USAGE' | translate}}
+
+ {{dashboardStatisticsData?.totalDataManagementPlanCount}}
+ {{'DASHBOARD.PUBLIC-DMPS' | translate}} +
+ {{dashboardStatisticsData?.totalDataSetCount}}
+ {{'DASHBOARD.PUBLIC-DATASETS' | translate}} +
+ {{dashboardStatisticsData?.totalGrantCount}}
+ {{'DASHBOARD.GRANTS' | translate}} +
+ {{dashboardStatisticsData?.totalOrganisationCount}}
+ {{'DASHBOARD.RELATED-ORGANISATIONS' | translate}}
@@ -188,10 +206,11 @@
+
- +
--> \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.scss b/dmp-frontend/src/app/ui/dashboard/dashboard.component.scss index 6df4b8c2c..7d642ec2c 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.scss +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.scss @@ -396,7 +396,7 @@ input[type="text"] { .add-dataset-btn { height: 40px; - margin-left: 40px; + margin-left: 40px; } :host ::ng-deep .mat-tab-group.mat-primary .mat-ink-bar, @@ -425,6 +425,87 @@ input[type="text"] { padding: 0.3rem 0rem 0.6rem 0rem !important; } +.new-releases-hint-container { + padding-left: 40px; + /* padding-top: 40px; */ + padding-right: 55px; +} + +.new-releases-card { + box-shadow: 0px 3px 6px #00000029; + max-width: 712px; + min-width: 17.5rem; + margin-top: 0rem; + margin-bottom: 3.75rem; + + background: transparent linear-gradient(127deg, #EDAEB3 0%, #E1368A 100%) 0% 0% no-repeat padding-box; + border-radius: 6px; + opacity: 1; + padding-bottom: 2em; +} + +.new-releases-btn { + height: 40px; + margin-left: 40px; + + background: var(--primary-color) 0% 0% no-repeat padding-box; + border-radius: 30px; + opacity: 1; + color: #FFFFFF; + padding-right: 2em; + padding-left: 2em; +} + +.new-releases-chip { + // margin-bottom: 1em; + // margin-left: 2.5em; + // margin-right: 2.5em; + color: #fff; + /* text-transform: uppercase; */ + text-align: center; + font-weight: 500; + /* max-width: 160px; */ + white-space: nowrap; + overflow: hidden; + text-overflow: ellipsis; + background: #EAEAEA 0% 0% no-repeat padding-box; + border-radius: 30px; + opacity: 0.7; + /* font: normal normal bold 12px/21px Aileron; */ + letter-spacing: 0.12px; + color: #6E6E6E; +} + +.new-releases-title { + text-align: left; + font: Bold 30px/34px Roboto; + letter-spacing: 0px; + color: #212121; + padding-left: 40px; + /* padding-top: 40px; */ + padding-right: 55px; + opacity: 1; +} + +.new-releases-content { + text-align: left; + font-weight: 300; + font-size: 1rem; + letter-spacing: 0px; + color: #212121; + padding-left: 40px; + font: normal normal normal 16px/24px Roboto; + padding-top: 36px; + padding-right: 55px; + opacity: 1; +} + +.new-releases-logo { + position: absolute; + right: 0; + bottom: 0; +} + /* ::ng-deep .mat-tab-group { height: 100%; } diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts index ed6f36cdc..6018e0538 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.ts @@ -35,6 +35,9 @@ import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/serv import { GuidedTourService } from '@app/library/guided-tour/guided-tour.service'; import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.constants'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import * as moment from 'moment'; +import { CookieService } from 'ngx-cookie-service'; @Component({ @@ -73,6 +76,7 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC importFileText: string; startWizardText: string; currentType: string = "recent"; + newReleaseNotificationVisible = false; constructor( private router: Router, @@ -89,7 +93,9 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC private language: TranslateService, private uiNotificationService: UiNotificationService, private guidedTourService: GuidedTourService, - private matomoService: MatomoService + private matomoService: MatomoService, + private cookieService: CookieService, + public configurationService: ConfigurationService ) { super(); // this.dashboardStatisticsData.totalDataManagementPlanCount = 0; @@ -154,6 +160,8 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC this.filteredOptions = this.searchControl.valueChanges.pipe(mergeMap(x => { return this.searchBarService.search(x); })); + + this.newReleaseNotificationVisible = this.isNewReleaseNotificationVisible(); } public get indexFromCurrentType() { @@ -302,7 +310,7 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC if (result.startNewDmp) { this.openNewDmpDialog(); } else { - this.router.navigate(['/datasets', 'new', result.formGroup.get('dmp').value.id]); + this.router.navigate(['/plans', 'edit', result.formGroup.get('dmp').value.id]); // Save dataset direct but missing title and template // this.datasetWizardService.createDataset(result.formGroup.getRawValue()) // .pipe(takeUntil(this._destroyed)) @@ -400,4 +408,26 @@ export class DashboardComponent extends BaseComponent implements OnInit, IBreadC // viewAllPublicDatasetsClicked() { // this.router.navigate(['explore']); // } + + dismissNewReleaseNotification() { + this.cookieService.set('new-release-dismiss-' + this.configurationService.newReleaseNotificationVersionCode, 'true', 5000, null, null, false, 'Lax'); + this.newReleaseNotificationVisible = false; + } + + isNewReleaseNotificationVisible() { + if (this.configurationService.newReleaseNotificationVersionCode == null) { + return false; + } + if (this.configurationService.newReleaseNotificationExpires == null && this.configurationService.newReleaseNotificationLink == null) { + return false; + } + if (this.configurationService.newReleaseNotificationExpires != null && moment(this.configurationService.newReleaseNotificationExpires).tz('UTC') < moment.utc()) { + return false; + } + if (this.cookieService.get('new-release-dismiss-' + this.configurationService.newReleaseNotificationVersionCode) === 'true') { + return false; + } + + return true; + } } 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 752fe315a..6ffe6c375 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.html @@ -1,4 +1,7 @@ -
+
+ {{'DMP-LISTING.EMPTY-LIST' | translate}} +
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -12,118 +15,155 @@ - + search - + {{formGroup.get('like').getError('backendError').message}}
-
+
-
-
- -
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
-
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
-
-
{{activity.label}}
-
- {{ roleDisplay(activity.users) }} - . - public{{'DATASET-LISTING.STATES.PUBLIC' | translate}} - done{{ enumUtils.toDmpStatusString(activity.status) }} - create{{ enumUtils.toDmpStatusString(activity.status) }} - . - {{'DATASET-LISTING.COLUMNS.GRANT' | translate}}: {{activity.grant}} -
-
-
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} -
{{'DATASET-LISTING.TOOLTIP.DMP' | translate}}
+
+
+
+ + +
+
{{ 'DMP-LISTING.DMP' | translate }}
+
{{ 'DMP-LISTING.EDITED' | translate }}: {{ activity.modified | dateTimeCultureFormatter: "d MMMM y" }}
+
{{ 'DMP-LISTING.PUBLISHED' | translate }}: {{ activity.publishedAt | dateTimeCultureFormatter: "d MMMM y" }}
- -
{{activity.dmp}}
+
{{activity.title}}
+
+ {{ roleDisplay(activity.users) }} + . + create{{ enumUtils.toDmpStatusString(activity.status) }} + . + {{'DMP-LISTING.VERSION' | translate}} {{activity.version}} + . + {{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}} +
+
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ getDatasets(activity).length }}) +
+
+
+
{{dataset.label}},
+
{{dataset.label}}
+
+
+ +
{{'GENERAL.ACTIONS.SHOW-MORE' | translate}} + + - -
- open_in_new{{'DATASET-LISTING.ACTIONS.EXPORT' | translate}} - group_add{{'DATASET-LISTING.ACTIONS.INVITE-SHORT' | translate}} - file_copy{{'DATASET-WIZARD.ACTIONS.COPY-DATASET' | translate}} - delete{{ 'DATASET-WIZARD.ACTIONS.DELETE' | translate }} - - - + + + + + + + + + + +
- - - - - +
+
+
-
+
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}}
-
+
- diff --git a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts index be73632c5..8ff1a60e6 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -1,6 +1,6 @@ import {Component, OnInit, Input, EventEmitter, Output, ViewChild} from '@angular/core'; import { DatasetService } from '../../../core/services/dataset/dataset.service'; -import { DataTableRequest } from '../../../core/model/data-table/data-table-request'; +import {DataTableMultiTypeRequest, DataTableRequest} from '../../../core/model/data-table/data-table-request'; import { DatasetCriteria } from '../../../core/query/dataset/dataset-criteria'; import { DatasetListingModel } from '../../../core/model/dataset/dataset-listing'; import { AuthService } from '../../../core/services/auth/auth.service'; @@ -9,10 +9,10 @@ import {ActivatedRoute, Router} from '@angular/router'; import { DmpStatus } from '../../../core/common/enum/dmp-status'; import { Principal } from '@app/core/model/auth/principal'; import { TranslateService } from '@ngx-translate/core'; -import { debounceTime, takeUntil } from 'rxjs/operators'; +import {debounceTime, map, takeUntil} from 'rxjs/operators'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; -import { FormControl, FormBuilder } from '@angular/forms'; +import {FormControl, FormBuilder, FormGroup} from '@angular/forms'; import { BaseComponent } from '@common/base/base.component'; import { MatDialog } from '@angular/material/dialog'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; @@ -27,6 +27,24 @@ import { Role } from '@app/core/common/enum/role'; import { LockService } from '@app/core/services/lock/lock.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import {RecentActivityModel} from "@app/core/model/recent-activity/recent-activity.model"; +import {DmpEditorModel} from "@app/ui/dmp/editor/dmp-editor.model"; +import {DmpService} from "@app/core/services/dmp/dmp.service"; +import {DashboardService} from "@app/core/services/dashboard/dashboard.service"; +import {RecentActivityCriteria} from "@app/core/query/recent-activity/recent-activity-criteria"; +import {RecentDmpModel} from "@app/core/model/recent-activity/recent-dmp-activity.model"; +import {DatasetUrlListing} from "@app/core/model/dataset/dataset-url-listing"; +import {RecentDatasetModel} from "@app/core/model/recent-activity/recent-dataset-activity.model"; +import {DmpListingModel} from "@app/core/model/dmp/dmp-listing"; +import {DmpModel} from "@app/core/model/dmp/dmp"; +import {GrantTabModel} from "@app/ui/dmp/editor/grant-tab/grant-tab-model"; +import {ProjectFormModel} from "@app/ui/dmp/editor/grant-tab/project-form-model"; +import {FunderFormModel} from "@app/ui/dmp/editor/grant-tab/funder-form-model"; +import {ExtraPropertiesFormModel} from "@app/ui/dmp/editor/general-tab/extra-properties-form.model"; +import {CloneDialogComponent} from "@app/ui/dmp/clone/clone-dialog/clone-dialog.component"; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; @Component({ selector: 'app-drafts', @@ -35,39 +53,44 @@ import { HttpClient } from '@angular/common/http'; }) export class DraftsComponent extends BaseComponent implements OnInit { - @Input() routerLink: string; - @Output() totalCountDraftDatasets: EventEmitter = new EventEmitter(); - - @ViewChild("drafts") resultsContainer; - datasetDrafts: DatasetListingModel[]; - datasetDraftsTypeEnum = RecentActivityType; - status: number; + @Output() totalCountRecentEdited: EventEmitter = new EventEmitter(); + @ViewChild("results") resultsContainer; + allRecentActivities: RecentActivityModel[]; + recentActivityTypeEnum = RecentActivityType; + dmpModel: DmpEditorModel; + isDraft: boolean; totalCount: number; startIndex: number = 0; - pageSize: number = 5; + dmpOffset: number = 0; + datasetOffset: number = 0; offsetLess: number = 0; - hasMoreResults:boolean = true; - + pageSize: number = 5; + dmpFormGroup: FormGroup; + hasMoreActivity:boolean = true; public formGroup = new FormBuilder().group({ like: new FormControl(), order: new FormControl() }); + publicMode = false; order = RecentActivityOrder; page: number = 1; @Input() isActive: boolean = false; + constructor( private route: ActivatedRoute, private router: Router, - private datasetService: DatasetService, - private authentication: AuthService, - private language: TranslateService, - public dialog: MatDialog, - private datasetWizardService: DatasetWizardService, public enumUtils: EnumUtils, + private authentication: AuthService, + private dmpService: DmpService, + private dmpProfileService: DmpProfileService, + private dashboardService: DashboardService, + private language: TranslateService, + private dialog: MatDialog, private uiNotificationService: UiNotificationService, + private datasetWizardService: DatasetWizardService, private location: Location, private lockService: LockService, private httpClient: HttpClient, @@ -83,7 +106,8 @@ export class DraftsComponent extends BaseComponent implements OnInit { let page = (params['page'] === undefined) ? 1 : +params['page']; this.page = (page <= 0) ? 1 : page; - this.startIndex = (this.page-1)*this.pageSize; + this.datasetOffset = (this.page-1)*this.pageSize; + this.dmpOffset = (this.page-1)*this.pageSize; if(this.page > 1) { this.offsetLess = (this.page-2)*this.pageSize; } @@ -94,48 +118,57 @@ export class DraftsComponent extends BaseComponent implements OnInit { } this.formGroup.get('order').setValue(order); - let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; this.formGroup.get("like").setValue(keyword); this.updateUrl(); } - // else { - // this.page = 1; - // this.formGroup.get('order').setValue(this.order.MODIFIED); - // this.formGroup.get("like").setValue(""); - // } }); - // const fields: Array = []; - // fields.push('-modified'); - if(!this.formGroup.get('order').value) { - this.formGroup.get('order').setValue(this.order.MODIFIED); - } - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.like = this.formGroup.get('like').value; - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { - let queryParams = { type: "drafts", page: 1, order: this.formGroup.get("order").value }; - if(this.formGroup.get("like").value) { - queryParams['keyword'] = this.formGroup.get("like").value; - } - this.router.navigate(["/home"], { queryParams: queryParams }) + if (this.isAuthenticated()) { + if (!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); } - }); - this.formGroup.get('like').valueChanges - .pipe(takeUntil(this._destroyed), debounceTime(500)) - .subscribe(x => this.refresh()); - this.formGroup.get('order').valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, 5, {fields: fields}); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get('like').value; + allDataTableRequest.criteria.order = this.formGroup.get('order').value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + } + }); + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if (this.allRecentActivities.length == 0 && this.page > 1) { + let queryParams = {type: "recent", page: 1, order: this.formGroup.get("order").value}; + if (this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], {queryParams: queryParams}) + } + }); + this.formGroup.get('like').valueChanges + .pipe(takeUntil(this._destroyed), debounceTime(500)) + .subscribe(x => { + this.refresh() + }); + this.formGroup.get('order').valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.refresh() + }); + } } ngOnChanges() { @@ -152,6 +185,231 @@ export class DraftsComponent extends BaseComponent implements OnInit { this.location.go(this.router.url.split('?')[0]+parameters); } + getDatasets(activity: RecentDmpModel): DatasetUrlListing[] { + return activity.datasets; + } + + getGroupId(activity: RecentDmpModel): string { + return activity.groupId; + } + + getDmp(activity: RecentDatasetModel): String { + return activity.dmp; + } + + getDmpId(activity: RecentDatasetModel): String { + return activity.dmpId; + } + + public isAuthenticated(): boolean { + return !!this.authentication.current(); + } + + isUserOwner(activity: DmpListingModel): boolean { + const principal: Principal = this.authentication.current(); + if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); + } + + editClicked(dmp: DmpListingModel) { + this.router.navigate(['/plans/edit/' + dmp.id]); + } + + deleteDmpClicked(dmp: DmpListingModel) { + this.lockService.checkLockStatus(dmp.id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDmpDialog(dmp); + } else { + this.openDmpLockedByUserDialog(); + } + }); + } + + cloneOrNewVersionClicked(dmp: RecentActivityModel, isNewVersion: boolean) { + this.dmpService.getSingle(dmp.id).pipe(map(data => data as DmpModel)) + .pipe(takeUntil(this._destroyed)) + .subscribe(data => { + this.dmpModel = new DmpEditorModel(); + this.dmpModel.grant = new GrantTabModel(); + this.dmpModel.project = new ProjectFormModel(); + this.dmpModel.funder = new FunderFormModel(); + this.dmpModel.extraProperties = new ExtraPropertiesFormModel(); + this.dmpModel.fromModel(data); + this.dmpModel.status = DmpStatus.Draft; + this.dmpFormGroup = this.dmpModel.buildForm(); + + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + + if (!isNewVersion) { + this.dmpFormGroup.get('label').setValue(dmp.title + " New"); + } + this.openCloneDialog(isNewVersion); + }); + } + + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } + + openCloneDialog(isNewVersion: boolean) { + const dialogRef = this.dialog.open(CloneDialogComponent, { + maxWidth: '700px', + maxHeight: '80vh', + data: { + formGroup: this.dmpFormGroup, + datasets: this.dmpFormGroup.get('datasets').value, + isNewVersion: isNewVersion, + confirmButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.SAVE'), + cancelButton: this.language.instant('DMP-EDITOR.CLONE-DIALOG.CANCEL'), + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (!isNewVersion) { + this.dmpService.clone(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } else if (isNewVersion) { + this.dmpService.newVersion(this.dmpFormGroup.getRawValue(), this.dmpFormGroup.get('id').value) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onCloneOrNewVersionCallbackSuccess(complete), + error => this.onCloneOrNewVersionCallbackError(error) + ); + } + } + }); + } + + openDeleteDmpDialog(dmp: DmpListingModel) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.dmpService.delete(dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); + } + }); + } + + openDmpLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DMP-EDITOR.ACTIONS.LOCK') + } + }); + } + + openShareDialog(rowId: any, rowName: any) { + const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { + // height: '250px', + // width: '700px', + autoFocus: false, + restoreFocus: false, + data: { + dmpId: rowId, + dmpName: rowName + } + }); + } + + isDraftDmp(activity: DmpListingModel) { + return activity.status == DmpStatus.Draft; + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans']); + } + + reloadPage(): void { + const path = this.location.path(); + this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { + this.router.navigate([path]); + }); + } + + onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.reloadPage(); + } + + onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + + onCloneOrNewVersionCallbackSuccess(dmpId: String): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/plans/edit/', dmpId]); + } + + onCloneOrNewVersionCallbackError(error: any) { + this.uiNotificationService.snackBarNotification(error.error.message ? this.language.instant(error.error.message) : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-CLONE'), SnackBarNotificationLevel.Error); + } + redirect(id: string, type: RecentActivityType) { switch (type) { case RecentActivityType.Grant: { @@ -159,11 +417,15 @@ export class DraftsComponent extends BaseComponent implements OnInit { return; } case RecentActivityType.Dataset: { - this.router.navigate(["datasets/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../datasets/overview/' + id]); + } return; } case RecentActivityType.Dmp: { - this.router.navigate(["plans/edit/" + id]); + if (this.isAuthenticated()) { + this.router.navigate(['../plans/overview/' + id]); + } return; } default: @@ -171,13 +433,28 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - public isAuthenticated(): boolean { - return !!this.authentication.current(); - } - - navigateToUrl() { - if (!this.isAuthenticated()) { return; } - this.router.navigate(['/datasets'], { queryParams: { status: 0 } }); + navigateToUrl(id: string, type: RecentActivityType): string[] { + switch (type) { + case RecentActivityType.Grant: { + return ["grants/edit/" + id]; + } + case RecentActivityType.Dataset: { + if (this.isAuthenticated()) { + return ['../datasets/overview/' + id]; + } else { + return ['../explore/publicOverview', id]; + } + } + case RecentActivityType.Dmp: { + if (this.isAuthenticated()) { + return ['../plans/overview/' + id]; + } else { + return ['../explore-plans/publicOverview', id]; + } + } + default: + throw new Error("Unsupported Activity Type "); + } } roleDisplay(value: any) { @@ -201,117 +478,68 @@ export class DraftsComponent extends BaseComponent implements OnInit { } } - openDmpSearchDialogue(dataset: DatasetListingModel) { - const formControl = new FormControl(); - const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { - width: '500px', - restoreFocus: false, - data: { - formControl: formControl, - datasetId: dataset.id, - datasetProfileId: dataset.profile.id, - datasetProfileExist: false, - confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), - cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') - } - }); + // dmpProfileDisplay(value: any) { + // if (value != null) { + // return value; + // } + // else { + // return "--"; + // } + // } - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) - .subscribe(result => { - if (result && result.datasetProfileExist) { - const newDmpId = result.formControl.value.id; - this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); - // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId } ]); - // window.open(url.toString(), '_blank'); - } + downloadXml(id: string) { + this.dmpService.downloadXML(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/xml' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "xml", id); }); } - deleteClicked(id: string) { - this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) - .subscribe(lockStatus => { - if (!lockStatus) { - this.openDeleteDialog(id); - } else { - this.openLockedByUserDialog(); - } + downloadDocx(id: string) { + this.dmpService.downloadDocx(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/msword' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "docx", id); }); } - openDeleteDialog(id: string): void { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '300px', - restoreFocus: false, - data: { - message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), - confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), - cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - isDeleteConfirmation: true - } - }); - dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - if (result) { - this.datasetWizardService.delete(id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => this.onDeleteCallbackSuccess(), - error => this.onDeleteCallbackError(error) - ); - } - }); + downloadPdf(id: string) { + this.dmpService.downloadPDF(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/pdf' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "pdf", id); + }); } - openLockedByUserDialog() { - const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - maxWidth: '400px', - restoreFocus: false, - data: { - message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') - } - }); + downloadJson(id: string) { + this.dmpService.downloadJson(id) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'application/json' }); + const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); + FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "json", id); + }, async error => { + this.onExportCallbackError(error); + }); } - openShareDialog(dmpRowId: any, dmpRowName: any) { - const dialogRef = this.dialog.open(DmpInvitationDialogComponent, { - // height: '250px', - // width: '700px', - autoFocus: false, - restoreFocus: false, - data: { - dmpId: dmpRowId, - dmpName: dmpRowName - } - }); - } - - isUserOwner(activity: DatasetListingModel): boolean { - const principal: Principal = this.authentication.current(); - if (principal) return !!activity.users.find(x => (x.role === Role.Owner) && (principal.id === x.id)); - } - - onCallbackSuccess(id?: String): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); - id ? this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', id]); }) : this.router.navigate(['/datasets']); - } - - onCallbackError(error: any) { - // this.setErrorModel(error.error); - } - - reloadPage(): void { - const path = this.location.path(); - this.router.navigateByUrl('/reload', { skipLocationChange: true }).then(() => { - this.router.navigate([path]); - }); - } - - onDeleteCallbackSuccess(): void { - this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); - this.reloadPage(); - } - - onDeleteCallbackError(error) { - this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + async onExportCallbackError(error: any) { + const errorJsonText = await error.error.text(); + const errorObj = JSON.parse(errorJsonText); + this.uiNotificationService.snackBarNotification(errorObj.message, SnackBarNotificationLevel.Error); } downloadPDF(dataset: DatasetListingModel): void { @@ -369,119 +597,177 @@ export class DraftsComponent extends BaseComponent implements OnInit { return filename; } - refresh(): void { - this.page = 1; - this.updateUrl(); + viewVersions(rowId: String, rowLabel: String, activity: DmpListingModel) { + if (activity.public && !this.isUserOwner(activity)) { + let url = this.router.createUrlTree(['/explore-plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/explore-plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } else { + let url = this.router.createUrlTree(['/plans/versions/', rowId, { groupLabel: rowLabel }]); + window.open(url.toString(), '_blank'); + // this.router.navigate(['/plans/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); + } + } - // const fields: Array = []; - // fields.push('-modified'); - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - this.startIndex = 0; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); - dmpDataTableRequest.criteria = new DatasetCriteria(); - dmpDataTableRequest.criteria.status = DmpStatus.Draft; - dmpDataTableRequest.criteria.like = this.formGroup.get("like").value; - this.datasetService.getPaged(dmpDataTableRequest) - .pipe(takeUntil(this._destroyed)) - .subscribe(response => { - this.datasetDrafts = response.data; - this.totalCount = response.totalCount; - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); - if(response.data.length< this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + openDmpSearchDialogue(dataset: RecentDatasetModel) { + const formControl = new FormControl(); + const dialogRef = this.dialog.open(DatasetCopyDialogueComponent, { + width: '500px', + restoreFocus: false, + data: { + formControl: formControl, + datasetId: dataset.id, + datasetProfileId: dataset.profile.id, + datasetProfileExist: false, + confirmButton: this.language.instant('DATASET-WIZARD.DIALOGUE.COPY'), + cancelButton: this.language.instant('DATASET-WIZARD.DIALOGUE.CANCEL') + } + }); + + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result && result.datasetProfileExist) { + const newDmpId = result.formControl.value.id; + // let url = this.router.createUrlTree(['/datasets/copy/', result.datasetId, { newDmpId: newDmpId }]); + // window.open(url.toString(), '_blank'); + this.router.navigate(['/datasets/copy/' + result.datasetId], { queryParams: { newDmpId: newDmpId } }); + } + }); + } + + deleteDatasetClicked(id: string) { + this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) + .subscribe(lockStatus => { + if (!lockStatus) { + this.openDeleteDatasetDialog(id); + } else { + this.openDatasetLockedByUserDialog(); + } + }); + } + + openDeleteDatasetDialog(id: string): void { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + this.datasetWizardService.delete(id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => this.onDeleteCallbackSuccess(), + error => this.onDeleteCallbackError(error) + ); } }); } - public loadNextOrPrevious(more: boolean = true) { - // const fields: Array = ["-modified"]; - const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - let request; - this.startIndex = (this.page)*this.pageSize; - if(this.page > 1) { - this.offsetLess = (this.page-2)*this.pageSize; - } - if(more) { - // this.startIndex = this.startIndex + this.pageSize; - request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); - } else { - request = new DataTableRequest(this.offsetLess, this.pageSize, {fields: fields}); - } - request.criteria = new DatasetCriteria(); - request.criteria.status = DmpStatus.Draft; - request.criteria.like = this.formGroup.get("like").value;; + openDatasetLockedByUserDialog() { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '400px', + restoreFocus: false, + data: { + message: this.language.instant('DATASET-WIZARD.ACTIONS.LOCK') + } + }); + } - this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result || !result.data || result.data.length == 0) { - this.hasMoreResults = false; + refresh(): void { + this.datasetOffset = 0; + this.dmpOffset = 0; + this.page = 1; + this.updateUrl(); + + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + this.startIndex = 0; + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(0, 0, this.pageSize, { fields: fields }); + allDataTableRequest.criteria = new RecentActivityCriteria(); + allDataTableRequest.criteria.like = this.formGroup.get("like").value; + allDataTableRequest.criteria.order = this.formGroup.get("order").value; + allDataTableRequest.criteria.status = 0; + + this.dashboardService + .getRecentActivity(allDataTableRequest) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + this.allRecentActivities = response; + this.allRecentActivities.forEach(recentActivity => { + if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; + } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; + } + }); + + if(response.length< this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + }); + } + + public loadNextOrPrevious(more: boolean = true) { + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; + // const fields: Array = ["-modified"]; + let request; + if(more) { + request = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, this.pageSize, {fields: fields}); + } else { + request = new DataTableMultiTypeRequest(this.offsetLess, this.offsetLess, this.pageSize, {fields: fields}); + } + request.criteria = new RecentActivityCriteria(); + request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; + request.criteria.order = this.formGroup.get("order").value; + request.criteria.status = 0; + + this.dashboardService.getRecentActivity(request).pipe(takeUntil(this._destroyed)).subscribe(result => { + if (!result || result.length == 0) { + this.hasMoreActivity = false; // return []; } else { - // this.datasetDrafts = this.datasetDrafts.concat(result.data); - // this.datasetDrafts = this.datasetDrafts.length > 0 ? this.mergeTwoSortedLists(this.datasetDrafts, result.data, this.formGroup.get('order').value) : result.data; this.page = this.page + (more ? 1 : -1); this.updateUrl(); - this.datasetDrafts = result.data; - if(result.data.length < this.pageSize) { - this.hasMoreResults = false; - } else { - this.hasMoreResults = true; + // if(more) { + // result.forEach(recentActivity => { + // if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + // } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + // } + // }); + // } + if (this.page > 1) { + this.offsetLess = (this.page - 2) * this.pageSize; } - this.totalCountDraftDatasets.emit(this.datasetDrafts.length); + + if(result.length < this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + + // this.allRecentActivities = this.allRecentActivities.concat(result); + // this.allRecentActivities = this.allRecentActivities.length > 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result; + this.allRecentActivities = result; + this.totalCountRecentEdited.emit(this.allRecentActivities.length); if (more) { this.resultsContainer.nativeElement.scrollIntoView(); } } }); } - - private mergeTwoSortedLists(arr1: DatasetListingModel[], arr2: DatasetListingModel[], order: string): DatasetListingModel[] { - let merged = []; - let index1 = 0; - let index2 = 0; - let current = 0; - - while (current < (arr1.length + arr2.length)) { - - let isArr1Depleted = index1 >= arr1.length; - let isArr2Depleted = index2 >= arr2.length; - - if (order === 'modified') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].modified) > new Date(arr2[index2].modified)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'created') { - if (!isArr1Depleted && (isArr2Depleted || (new Date(arr1[index1].created) > new Date(arr2[index2].created)))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'label') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].label < arr2[index2].label))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } else if (order === 'status') { - if (!isArr1Depleted && (isArr2Depleted || (arr1[index1].status < arr2[index2].status))) { - merged[current] = arr1[index1]; - index1++; - } else { - merged[current] = arr2[index2]; - index2++; - } - } - current++; - } - return merged; - } } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html index bc084981d..75d48c7d0 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.html @@ -48,7 +48,7 @@ . {{ 'DMP-LISTING.GRANT' | translate }}: {{activity.grant}}
-
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ getDatasets(activity).length }}) +
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ getDatasets(activity).length }})
@@ -61,7 +61,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}} @@ -106,7 +106,7 @@
-
{{'DATASET-LISTING.DATASET-DESCRIPTION' | translate}}
+
{{'DATASET-LISTING.DESCRIPTION' | translate}}
{{'DATASET-LISTING.STATES.EDITED' | translate}}: {{activity.modified | dateTimeCultureFormatter: "d MMMM y"}}
{{'DATASET-LISTING.STATES.PUBLISHED' | translate}}: {{activity.publishedAt | dateTimeCultureFormatter: "d MMMM y"}}
@@ -132,7 +132,7 @@
-
{{'DMP-LISTING.CONTAINED-DATASETS' | translate}}: ({{ activity.datasets.length }}) +
{{'DMP-LISTING.CONTAINED-DESCRIPTIONS' | translate}}: ({{ activity.datasets.length }})
@@ -55,7 +55,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/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts index 1e53f6b9a..c381774f8 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts @@ -34,6 +34,9 @@ import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model' import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-model'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-recent-edited-dmp-activity', @@ -75,6 +78,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O public enumUtils: EnumUtils, private authentication: AuthService, private dmpService: DmpService, + private dmpProfileService: DmpProfileService, private datasetService: DatasetService, private language: TranslateService, private dialog: MatDialog, @@ -252,6 +256,17 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O this.dmpModel.fromModel(data); this.dmpModel.status = DmpStatus.Draft; this.dmpFormGroup = this.dmpModel.buildForm(); + + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + if (!isNewVersion) { this.dmpFormGroup.get('label').setValue(dmp.label + " New"); } @@ -259,6 +274,48 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O }); } + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } + openCloneDialog(isNewVersion: boolean) { const dialogRef = this.dialog.open(CloneDialogComponent, { maxWidth: '700px', diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.ts index 37b53eb00..db2037a76 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.ts @@ -74,7 +74,7 @@ export class DatasetCopyDialogueComponent { map(result => { this.dmpModel = result this.dmpModel.profiles.forEach((element) => { - if (element.id == this.data.datasetProfileId) { + if (element.descriptionTemplateId == this.data.datasetProfileId) { this.data.datasetProfileExist = true; } }) diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html index a7be0544d..b5b27b9c1 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.html @@ -32,7 +32,8 @@ + ((formGroup.get('description').touched && (formGroup.get('description').hasError('required') || formGroup.get('description').hasError('backendError'))) ? 'required' : '')" + [editable]="!formGroup.get('description').disabled">
{{formGroup.get('description').getError('backendError').message}} @@ -63,7 +64,9 @@ - {{profile.label}} +
+ {{profile.label}} +
{{formGroup.get('profile').getError('backendError').message}} diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts index 341cb9a9e..371faa461 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.ts @@ -1,4 +1,4 @@ -import { Component, Input, Output, EventEmitter } from '@angular/core'; +import { Component, Input } from '@angular/core'; import { FormGroup } from '@angular/forms'; import { Router } from '@angular/router'; import { BaseComponent } from '@common/base/base.component'; @@ -7,6 +7,9 @@ import { GuidedTour, Orientation } from '@app/library/guided-tour/guided-tour.co import { TranslateService } from '@ngx-translate/core'; import { DatasetProfileModel } from '@app/core/model/dataset/dataset-profile'; import { takeUntil } from 'rxjs/operators'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { MatDialog } from '@angular/material/dialog'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; @Component({ selector: 'app-dataset-editor-component', @@ -25,6 +28,8 @@ export class DatasetEditorComponent extends BaseComponent { constructor( private router: Router, + private dmpProfileService: DmpProfileService, + private dialog: MatDialog, private guidedTourService: GuidedTourService, private language: TranslateService ) { super(); } @@ -44,6 +49,44 @@ export class DatasetEditorComponent extends BaseComponent { ] }; + ngOnInit() { + this.formGroup.get('profile').valueChanges.pipe(takeUntil(this._destroyed)).subscribe(x => { + this.checkMinMax(x); + }); + } + + checkMinMax(profile: DatasetProfileModel) { + const dmpSectionIndex = this.formGroup.get('dmpSectionIndex').value; + const blueprintId = this.formGroup.get('dmp').value.profile.id; + this.dmpProfileService.getSingleBlueprint(blueprintId) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + const section = result.definition.sections[dmpSectionIndex]; + if (section.hasTemplates) { + const foundTemplate = section.descriptionTemplates.find(template => template.descriptionTemplateId === profile.id); + if (foundTemplate !== undefined) { + let count = 0; + if (this.formGroup.get('dmp').value.datasets != null) { + for (let dataset of this.formGroup.get('dmp').value.datasets) { + if (dataset.dmpSectionIndex === dmpSectionIndex && dataset.profile.id === foundTemplate.descriptionTemplateId) { + count++; + } + } + if (count === foundTemplate.maxMultiplicity) { + this.dialog.open(PopupNotificationDialogComponent, { + data: { + title: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.TITLE'), + message: this.language.instant('DATASET-EDITOR.MAX-DESCRIPTION-DIALOG.MESSAGE') + }, maxWidth: '30em' + }); + this.formGroup.get('profile').reset(); + } + } + } + } + }); + } + getDmpText(): string { return this.language.instant('DMP-LISTING.TEXT-INFO') + '\n\n' + this.language.instant('DMP-LISTING.TEXT-INFO-QUESTION') + ' ' + diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts index f4ad2cf38..e2a3f45a5 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard-editor.model.ts @@ -26,6 +26,7 @@ export class DatasetWizardEditorModel { public tags: ExternalTagEditorModel[] = []; public externalDatasets: ExternalDatasetEditorModel[] = []; public dmp: DmpModel; + public dmpSectionIndex: number; public datasetProfileDefinition: DatasetDescriptionFormEditorModel; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public isProfileLatestVersion: Boolean; @@ -43,6 +44,7 @@ export class DatasetWizardEditorModel { if (item.dataRepositories) { this.dataRepositories = item.dataRepositories.map(x => new ExternalDataRepositoryEditorModel().fromModel(x)); } if (item.externalDatasets) { this.externalDatasets = item.externalDatasets.map(x => new ExternalDatasetEditorModel().fromModel(x)); } this.dmp = item.dmp; + this.dmpSectionIndex = item.dmpSectionIndex; if (item.datasetProfileDefinition) { this.datasetProfileDefinition = new DatasetDescriptionFormEditorModel().fromModel(item.datasetProfileDefinition); } if (item.tags) { this.tags = item.tags.map(x => new ExternalTagEditorModel().fromModel(x)); } this.isProfileLatestVersion = item.isProfileLatestVersion; @@ -60,6 +62,7 @@ export class DatasetWizardEditorModel { status: [{ value: this.status, disabled: disabled }, context.getValidation('status').validators], description: [{ value: this.description, disabled: disabled }, context.getValidation('description').validators], dmp: [{ value: this.dmp, disabled: disabled }, context.getValidation('dmp').validators], + dmpSectionIndex: [{ value: this.dmpSectionIndex, disabled: disabled }, context.getValidation('dmpSectionIndex').validators], //externalDatasets: [{ value: this.externalDatasets, disabled: disabled }, context.getValidation('externalDatasets').validators], tags: [{ value: this.tags, disabled: disabled }, context.getValidation('tags').validators], //registries: [{ value: this.registries, disabled: disabled }, context.getValidation('registries').validators], @@ -143,6 +146,7 @@ export class DatasetWizardEditorModel { baseContext.validation.push({ key: 'dataRepositories', validators: [BackendErrorValidator(this.validationErrorModel, 'dataRepositories')] }); baseContext.validation.push({ key: 'externalDatasets', validators: [BackendErrorValidator(this.validationErrorModel, 'externalDatasets')] }); baseContext.validation.push({ key: 'dmp', validators: [BackendErrorValidator(this.validationErrorModel, 'dmp')] }); + baseContext.validation.push({ key: 'dmpSectionIndex', validators: [BackendErrorValidator(this.validationErrorModel, 'dmpSectionIndex')] }); baseContext.validation.push({ key: 'datasetProfileDefinition', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'tags', validators: [BackendErrorValidator(this.validationErrorModel, 'datasetProfileDefinition')] }); baseContext.validation.push({ key: 'modified', validators: []}); diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html index a33d78874..6b84a8950 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.html @@ -10,7 +10,7 @@
{{'DMP-EDITOR.TITLE.ADD-DATASET' | translate}}
-
{{'DMP-EDITOR.TITLE.EDIT-DATASET' | translate}}
+
{{'DMP-EDITOR.TITLE.EDIT-DESCRIPTION' | translate}}
{{ formGroup.get('label').value }} ({{'DMP-EDITOR.CHANGES' | translate}})
@@ -141,7 +141,7 @@
- +
@@ -183,7 +183,7 @@
-

{{(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/dataset-listing.component.ts b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.ts index f4f90fb18..0a1e89bdc 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.ts +++ b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.ts @@ -430,7 +430,7 @@ export class DatasetListingComponent extends BaseComponent implements OnInit, IB if (result.startNewDmp) { this.openNewDmpDialog(); } else { - this.router.navigate(['/datasets', 'new', result.formGroup.get('dmp').value.id]); + this.router.navigate(['/plans', 'edit', result.formGroup.get('dmp').value.id]); } } }); 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-OVERVIEW.GRANT' | translate}}
-
{{ dataset.grant.label }}
- +
+
{{'DMP-OVERVIEW.GRANT' | translate}}
+
{{ dataset.grant.label }}
+
+
{{'DMP-OVERVIEW.RESEARCHERS' | translate}}
@@ -151,7 +153,7 @@
-

{{ 'DATASET-OVERVIEW.DATASET-AUTHORS' | translate }}

+

{{ 'DATASET-OVERVIEW.DESCRIPTION-AUTHORS' | translate }}

diff --git a/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.html b/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.html index b1ed8babb..ef4ae836c 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.html +++ b/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.html @@ -53,9 +53,9 @@
-
{{'DMP-EDITOR.FIELDS.DATASETS' | translate}}
+
{{'DMP-EDITOR.FIELDS.DESCRIPTIONS' | translate}}
-
{{'DATASET-LISTING.SELECT-DATASETS-TO-CLONE' | translate}}
+
{{'DATASET-LISTING.SELECT-DESCRIPTIONS-TO-CLONE' | translate}}
@@ -65,7 +65,7 @@
-
{{'DATASET-LISTING.SELECT-DATASETS-NONE' | translate}}
+
{{'DATASET-LISTING.SELECT-DESCRIPTIONS-NONE' | translate}}
diff --git a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.html b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.html index a949bb2d6..ed8b1a92e 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.html +++ b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.html @@ -30,8 +30,8 @@
- -
{{'DATASET-LISTING.SELECT-DATASETS-TO-CLONE' | translate}}
+ +
{{'DATASET-LISTING.SELECT-DESCRIPTIONS-TO-CLONE' | translate}}
{{ dataset.value.label }} ({{'DMP-EDITOR.CHANGES' | translate}})
{{'DATASET-LISTING.TOOLTIP.PART-OF' | translate}} @@ -65,7 +65,7 @@
  • {{'DMP-EDITOR.STEPPER.MAIN-INFO' | translate}} (4)
  • {{'DMP-EDITOR.STEPPER.FUNDING-INFO' | translate}} (3)
  • {{'DMP-EDITOR.STEPPER.LICENSE-INFO' | translate}} (6)
  • -
  • {{'DMP-EDITOR.STEPPER.DATASET-INFO' | translate}}
  • +
  • {{'DMP-EDITOR.STEPPER.DESCRIPTION-INFO' | translate}}
  • {{'DMP-EDITOR.STEPPER.DATASET' | translate}}
    @@ -95,7 +95,7 @@
  • add -
    {{'DMP-LISTING.ACTIONS.ADD-DATASET-SHORT' | translate}}
    +
    {{'DMP-LISTING.ACTIONS.ADD-DESCRIPTION-SHORT' | translate}}
    diff --git a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts index 20681c99e..7b707bc02 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts +++ b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.ts @@ -29,6 +29,9 @@ import { DmpEditorModel } from '../editor/dmp-editor.model'; import { DatasetWizardEditorModel } from '@app/ui/dataset/dataset-wizard/dataset-wizard-editor.model'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; import { MatDialog } from '@angular/material/dialog'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Component({ @@ -65,6 +68,7 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { private router: Router, private language: TranslateService, private dmpService: DmpService, + private dmpProfileService: DmpProfileService, private authentication: AuthService, private uiNotificationService: UiNotificationService, private datasetService: DatasetService, @@ -90,6 +94,16 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { this.dmp.status = DmpStatus.Draft; this.formGroup = this.dmp.buildForm(); + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + this.datasets = this.formGroup.get('datasets') as FormArray; this.parentDmpLabel = this.formGroup.get('label').value; @@ -128,6 +142,48 @@ export class DmpCloneComponent extends BaseComponent implements OnInit { } + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } + public cancel(id: String): void { if (id != null) { this.router.navigate(['/plans/overview/' + id]); diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html new file mode 100644 index 000000000..6ebf63eda --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.html @@ -0,0 +1,347 @@ +
    +
    +
    + +
    +
    +
    +
    +
    +
    {{'DMP-EDITOR.TITLE.EDIT-DMP' | translate}}
    +
    {{ formGroup.get('label').value }} ({{'DMP-EDITOR.CHANGES' | translate}})
    +
    +
    + +
    + + +
    + +
    + +
    +
    +
    +
    +
    +
    +
    +
    +
    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 +
    + + + + +
    +
    + +
    +
    +
    +
    +
    +
    Title of DMP *
    + + Title + + + +
    +
    +
    Description of DMP *
    + + +
    +
    +
    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..a9283c45b --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.scss @@ -0,0 +1,437 @@ +@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; +} + +::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { + padding: 1em 0 1em 0 !important; +} + +// ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { +// padding: 0rem 0rem 0.4rem 0rem !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..c93f61cef --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor-blueprint.component.ts @@ -0,0 +1,1169 @@ +import { Component, OnInit } from '@angular/core'; +import { AbstractControl, FormArray, FormBuilder, FormControl, FormGroup, Validators } from '@angular/forms'; +import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; +import { DmpBlueprintDefinition, ExtraFieldType, FieldCategory, 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, DmpExtraFieldEditorModel } 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'; +import { DmpProfileStatus } from '@app/core/common/enum/dmp-profile-status'; +import { DatasetService } from '@app/core/services/dataset/dataset.service'; +import { runInThisContext } from 'vm'; + +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>(); + + extraFieldTypesEnum = ExtraFieldType; + + 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; + + readonly defaultBlueprintId = '86635178-36a6-484f-9057-a934e4eeecd5'; + + constructor( + private dmpProfileService: DmpProfileService, + private datasetService: DatasetService, + 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.getItem(itemId); + } + 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) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.checkForGrant(); + this.checkForFunder(); + this.checkForProject(); + this.buildExtraFields(); + 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', + canRemoveItem: (item) => this.canRemoveItem(item) + }; + } + + private getItem(itemId: String) { + 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) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.checkForGrant(); + this.checkForFunder(); + this.checkForProject(); + this.buildExtraFields(); + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + this.step = 1; + this.sectionTemplates = new Array>(); + 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' + }); + } + }); + }); + } + + extraFieldsArray(): FormArray { + return this.formGroup.get('extraFields') as FormArray; + } + + 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(this.defaultBlueprintId) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.selectedDmpBlueprintDefinition = result.definition; + this.formGroup.get('profile').setValue(result); + this.maxStep = this.selectedDmpBlueprintDefinition.sections.length; + if (this.formGroup.get('label').valid && this.formGroup.get('description').valid) { + 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 !== 1 ? 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(sectionIndex: number): boolean { + return this.formGroup.get('profiles') && this.formGroup.get('profiles').value && this.formGroup.get('profiles').value.some(x => x.data?.dmpSectionIndex?.includes(sectionIndex)); + } + + 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; + const rawvalue = this.formGroup.getRawValue(); + if (rawvalue.profile instanceof Object) rawvalue.profile = rawvalue.profile.id; + this.dmpService.createDmp(rawvalue) + .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]); + } + this.getItem(dmp.id); + 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]); + } + + } + + + } + + public removeDataset(datasetId: string, index: number) { + const dialogRef = this.dialog.open(ConfirmationDialogComponent, { + maxWidth: '300px', + restoreFocus: false, + data: { + message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.DELETE-ITEM'), + confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.DELETE'), + cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), + isDeleteConfirmation: true + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + if (result) { + if (datasetId) { + this.datasetService.delete(datasetId) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + this.onDeleteCallbackSuccess(); + }, + error => this.onDeleteCallbackError(error) + ); + } + this.formGroup.get('datasets')['controls'].splice(index, 1); + this.step = 0; + } + }); + } + + onDeleteCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.SUCCESSFUL-DELETE'), SnackBarNotificationLevel.Success); + this.dmp.id != null ? this.router.navigate(['/reload']).then(() => this.router.navigate(['/plans', 'edit', this.dmp.id])) : this.router.navigate(['/plans']); + } + + onDeleteCallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-DELETE'), SnackBarNotificationLevel.Error); + } + + //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.checkForGrant(); + this.checkForFunder(); + this.checkForProject(); + this.buildExtraFields(); + this.addProfiles(); + } + else { + this.selectedDmpBlueprintDefinition = null; + } + }) + } + + private buildExtraFields(): void { + const extraFields = new Array(); + this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach(field => { + if (field.category as unknown == 'EXTRA') { + let extraField = new DmpExtraFieldEditorModel(); + extraField.id = field.id; + if (!isNullOrUndefined(this.dmp.extraFields)) { + let found = this.dmp.extraFields.find(f => f.id === field.id); + if (found !== undefined) { + extraField.value = found.value; + } + } + extraFields.push(extraField.buildForm()); + } + })); + this.formGroup.setControl('extraFields', new FormBuilder().array(extraFields)); + } + + getExtraFieldIndex(id: string): string { + return (this.formGroup.get('extraFields') as FormArray).controls.findIndex((element) => element.value.id == id).toString(); + } + + private checkForGrant() { + let hasGrant = false; + this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder() { + let hasFunder = false; + this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject() { + let hasProject = false; + this.selectedDmpBlueprintDefinition.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } + + 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 != null) { + 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.descriptionTemplateId == 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, 20, { fields: fields }); + request.criteria = new DmpBlueprintCriteria(); + request.criteria.like = query; + request.criteria.status = DmpProfileStatus.Finalized; + 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; + } + + canRemoveItem(item): boolean { + let found = false; + this.formGroup.get('datasets')['controls'].forEach(element => { + if ((element.get('profile').value.id === item.id) && (element.get('dmpSectionIndex').value === (this.step - 1))) { + found = true; + this.uiNotificationService.snackBarNotification(this.language.instant('GENERAL.SNACK-BAR.UNSUCCESSFUL-REMOVE-TEMPLATE'), SnackBarNotificationLevel.Success); + } + }); + if (found) return false + else return true; + } + + onRemoveTemplate(event, sectionIndex: number) { + let profiles = this.formGroup.get('profiles').value as DmpDatasetProfile[]; + this.sectionTemplates[sectionIndex] = this.sectionTemplates[sectionIndex].filter(sectionProfile => sectionProfile.id !== event.id); + profiles = profiles.filter(sectionProfile => sectionProfile.descriptionTemplateId !== event.id || !sectionProfile.data.dmpSectionIndex.includes(sectionIndex)); + this.formGroup.get('profiles').setValue(profiles); + } + + addProfile(event, sectionIndex: number) { + 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); + } + + 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) { + this.addProfile(event, sectionIndex); + const items = this.sectionTemplates[sectionIndex]; + items.push({ id: event.id, label: event.label, description: "" }); + this.sectionTemplates[sectionIndex] = [...items]; + } + }); + } + onOptionSelected(event, sectionIndex: number) { + try { + this.addProfile(event, sectionIndex); + // 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..3c1888121 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,6 @@ 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 { 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 +21,8 @@ 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"; +import { DmpExtraField } from "@app/core/model/dmp/dmp-extra-field"; export class DmpEditorModel { public id: string; @@ -41,13 +39,13 @@ 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[] = []; public associatedUsers: UserModel[] = []; public users: UserInfoListingModel[] = []; - public definition: DmpProfileDefinition; + public extraFields: Array = []; public dynamicFields: Array = []; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public modified: Date; @@ -55,7 +53,7 @@ export class DmpEditorModel { fromModel(item: DmpModel): DmpEditorModel { this.id = item.id; - this.profile = item.profile; + this.profile = item.profile.id; this.label = item.label; this.groupId = item.groupId; this.version = item.version; @@ -72,7 +70,7 @@ export class DmpEditorModel { this.datasetsToBeFinalized = item.datasetsToBeFinalized; this.associatedUsers = item.associatedUsers; this.users = item.users; - if (item.definition) { this.definition = item.definition; } + if (item.extraFields) { item.extraFields.map(x => this.extraFields.push(new DmpExtraFieldEditorModel().fromModel(x))); } if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); } this.creator = item.creator; this.modified = new Date(item.modified); @@ -115,14 +113,9 @@ export class DmpEditorModel { if (this.dynamicFields) { this.dynamicFields.forEach(item => dynamicFields.push(item.buildForm())); } formGroup.addControl('dynamicFields', new FormBuilder().array(dynamicFields)); - if (this.definition) { - const fields = new Array(); - this.definition.fields.forEach(item => fields.push(new DmpDefinitionFieldEditorModel().fromModel(item).buildForm())); - const definition = new FormBuilder().group({ - fields: new FormBuilder().array(fields) - }); - formGroup.addControl('definition', definition); - } + const extraFields = new Array(); + if (this.extraFields) { this.extraFields.forEach(item => extraFields.push(item.buildForm())); } + formGroup.addControl('extraFields', new FormBuilder().array(extraFields)); return formGroup; } @@ -135,10 +128,10 @@ export class DmpEditorModel { baseContext.validation.push({ key: 'groupId', validators: [BackendErrorValidator(this.validationErrorModel, 'groupId')] }); baseContext.validation.push({ key: 'version', validators: [BackendErrorValidator(this.validationErrorModel, 'version')] }); baseContext.validation.push({ key: 'status', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'status')] }); - baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] }); - baseContext.validation.push({ key: 'grant', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'grant')] }); + baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] }); + baseContext.validation.push({ key: 'grant', validators: [BackendErrorValidator(this.validationErrorModel, 'grant')] }); baseContext.validation.push({ key: 'project', validators: [BackendErrorValidator(this.validationErrorModel, 'project')] }); - baseContext.validation.push({ key: 'funder', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'funder')] }); + baseContext.validation.push({ key: 'funder', validators: [BackendErrorValidator(this.validationErrorModel, 'funder')] }); baseContext.validation.push({ key: 'organisations', validators: [BackendErrorValidator(this.validationErrorModel, 'organisations')] }); baseContext.validation.push({ key: 'researchers', validators: [BackendErrorValidator(this.validationErrorModel, 'researchers')] }); baseContext.validation.push({ key: 'profiles', validators: [Validators.required, ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'profiles')] }); @@ -151,6 +144,26 @@ export class DmpEditorModel { } } +export class DmpExtraFieldEditorModel { + public id: string; + public value: string; + + fromModel(item: DmpExtraField): DmpExtraFieldEditorModel { + this.id = item.id; + this.value = item.value; + return this; + } + + buildForm(): FormGroup { + const builder = new FormBuilder(); + const formGroup = builder.group({ + id: [this.id], + value: [this.value] + }); + return formGroup; + } +} + export class DmpDynamicFieldEditorModel { public id: 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..cf6383007 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,22 +1,22 @@
    -
    + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.FUNDER-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    - +
    @@ -31,41 +31,42 @@ clear - + {{funderFormGroup.get('label').getError('backendError').message}} {{'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}}
    -
    -
    +
    --> +
    - +
    @@ -80,14 +81,14 @@ clear - + {{grantformGroup.get('label').getError('backendError').message}} {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + {{projectFormGroup.get('description').getError('backendError').message}} @@ -107,28 +108,28 @@
    -
    -
    + -
    + +
    {{'DMP-EDITOR.FIELDS.EXTERNAL-SOURCE-HINT' | translate}}
    {{'DMP-EDITOR.FIELDS.PROJECT-HINT' | translate}}
    info {{'DMP-EDITOR.MAIN-INFO.TYPING' | translate}}
    -
    -
    +
    --> +
    - +
    - + {{'DMP-EDITOR.FUNDING-INFO.IDENTIFIER-PROJECT-EXISTS' | translate}} check @@ -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..f3d9e9fda 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 @@ -14,6 +14,7 @@ import { FunderCriteria } from '@app/core/query/funder/funder-criteria'; import { debounceTime, filter, map, switchMap, takeUntil, tap } from 'rxjs/operators'; import { isNullOrUndefined } from '@swimlane/ngx-datatable'; +import { FieldInSection } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'funding-info', templateUrl: './funding-info.component.html', @@ -28,6 +29,10 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { @Input() isClone: boolean = false; @Input() isNewVersion: boolean; + @Input() isRequired: boolean; + @Input() type: number; + @Input() field: FieldInSection; + @Input() formGroup: FormGroup; @Input() grantformGroup: FormGroup; @Input() projectFormGroup: FormGroup; @@ -71,7 +76,7 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { return ''; } - ngOnInit() { + ngOnInit() { const grantRequestItem: RequestItem = new RequestItem(); grantRequestItem.criteria = new GrantCriteria(); @@ -79,16 +84,24 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { this.initializeReferenceValidators(); - this.isCreateNew = (this.grantformGroup.get('label').value != null && this.grantformGroup.get('label').value.length > 0); - this.isCreateNewProject = (this.projectFormGroup.get('label').value != null && this.projectFormGroup.get('label').value.length > 0); - this.isCreateNewFunder = (this.funderFormGroup.get('label').value != null && this.funderFormGroup.get('label').value.length > 0); - this.setGrantValidators(); - this.setProjectValidators(); - this.setFunderValidators(); + if (this.grantformGroup != null) { + this.isCreateNew = (this.grantformGroup.get('label').value != null && this.grantformGroup.get('label').value.length > 0); + this.setGrantValidators(); + } + if (this.projectFormGroup != null) { + this.isCreateNewProject = (this.projectFormGroup.get('label').value != null && this.projectFormGroup.get('label').value.length > 0); + this.setProjectValidators(); + } + if (this.funderFormGroup != null) { + this.isCreateNewFunder = (this.funderFormGroup.get('label').value != null && this.funderFormGroup.get('label').value.length > 0); + this.setFunderValidators(); + } this.registerFormListeners(); if (this.isNew && !this.isClone) { - this.grantformGroup.reset(); - this.grantformGroup.disable(); + if (this.grantformGroup != null && this.funderFormGroup != null) { + this.grantformGroup.reset(); + this.grantformGroup.disable(); + } } this.formGroup.valueChanges.pipe(takeUntil(this._destroyed)) @@ -99,108 +112,114 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { initializeReferenceValidators() { //Validator for funder - this.funderFormGroup.get('reference').valueChanges.pipe( - takeUntil(this._destroyed), - filter(value =>!isNullOrUndefined(value)), - tap(_=>this.isFunderPending = true), - debounceTime(500), - switchMap(value=> { - const requestItem = new RequestItem(); - requestItem.criteria = new FunderCriteria(); - requestItem.criteria.exactReference = this._FUNDER_PREFIX +value; - return this.funderService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); - }), - map(response=>{ - if(response && response.length){ - const internalFunders = (response as Array).filter(funder=> funder.key === this._KEY); + if (this.funderFormGroup != null) { + this.funderFormGroup.get('reference').valueChanges.pipe( + takeUntil(this._destroyed), + filter(value =>!isNullOrUndefined(value)), + tap(_=>this.isFunderPending = true), + debounceTime(500), + switchMap(value=> { + const requestItem = new RequestItem(); + requestItem.criteria = new FunderCriteria(); + requestItem.criteria.exactReference = this._FUNDER_PREFIX +value; + return this.funderService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); + }), + map(response=>{ + if(response && response.length){ + const internalFunders = (response as Array).filter(funder=> funder.key === this._KEY); - if(internalFunders && internalFunders.length){ - return {funderIdentifierExists:true}; + if(internalFunders && internalFunders.length){ + return {funderIdentifierExists:true}; + } + return null; } return null; + }) + ) + .subscribe(error=>{ + this.isFunderPending = false; + this.funderFormGroup.get('reference').setErrors(error); + if(!error && this.funderFormGroup.get('reference').validator){ + const validator = this.funderFormGroup.get('reference').validator({} as AbstractControl); + if(validator && validator.required && this.funderFormGroup.get('reference').touched && !this.funderFormGroup.get('reference').value){ + this.funderFormGroup.get('reference').setErrors({required : true}); + } } - return null; - }) - ) - .subscribe(error=>{ - this.isFunderPending = false; - this.funderFormGroup.get('reference').setErrors(error); - if(!error && this.funderFormGroup.get('reference').validator){ - const validator = this.funderFormGroup.get('reference').validator({} as AbstractControl); - if(validator && validator.required && this.funderFormGroup.get('reference').touched && !this.funderFormGroup.get('reference').value){ - this.funderFormGroup.get('reference').setErrors({required : true}); - } - } - }); + }); + } //Validator for grants - this.grantformGroup.get('reference').valueChanges.pipe( - takeUntil(this._destroyed), - filter(value =>!isNullOrUndefined(value)), - tap(_=> this.isGrantPending = true), - debounceTime(500), - switchMap(value=> { - const requestItem = new RequestItem(); - requestItem.criteria = new GrantCriteria(); - requestItem.criteria.exactReference = this._GRANT_PREFIX + value; - return this.grantService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); - }), - map(response=>{ - if(response && response.length){ - const internalGrants = (response as Array).filter(grant=> grant.key === this._KEY); + if (this.grantformGroup != null) { + this.grantformGroup.get('reference').valueChanges.pipe( + takeUntil(this._destroyed), + filter(value =>!isNullOrUndefined(value)), + tap(_=> this.isGrantPending = true), + debounceTime(500), + switchMap(value=> { + const requestItem = new RequestItem(); + requestItem.criteria = new GrantCriteria(); + requestItem.criteria.exactReference = this._GRANT_PREFIX + value; + return this.grantService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); + }), + map(response=>{ + if(response && response.length){ + const internalGrants = (response as Array).filter(grant=> grant.key === this._KEY); - if(internalGrants && internalGrants.length){ - return {grantIdentifierExists:true}; + if(internalGrants && internalGrants.length){ + return {grantIdentifierExists:true}; + } + return null; } return null; + }) + ) + .subscribe(error=>{ + this.isGrantPending = false; + this.grantformGroup.get('reference').setErrors(error); + if(!error && this.grantformGroup.get('reference').validator){ + const validator = this.grantformGroup.get('reference').validator({} as AbstractControl); + if(validator && validator.required && this.grantformGroup.get('reference').touched && !this.grantformGroup.get('reference').value){ + this.grantformGroup.get('reference').setErrors({required : true}); + } } - return null; - }) - ) - .subscribe(error=>{ - this.isGrantPending = false; - this.grantformGroup.get('reference').setErrors(error); - if(!error && this.grantformGroup.get('reference').validator){ - const validator = this.grantformGroup.get('reference').validator({} as AbstractControl); - if(validator && validator.required && this.grantformGroup.get('reference').touched && !this.grantformGroup.get('reference').value){ - this.grantformGroup.get('reference').setErrors({required : true}); - } - } - }); + }); + } //validator for projects - this.projectFormGroup.get('reference').valueChanges.pipe( - takeUntil(this._destroyed), - filter(value =>!isNullOrUndefined(value)), - tap(_ => this.isProjectPending = true), - debounceTime(500), - switchMap(value=> { - const requestItem = new RequestItem(); - requestItem.criteria = new ProjectCriteria(); - requestItem.criteria.exactReference = this._PROJECT_PREFIX + value; - return this.projectService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); - }), - map(response=>{ - if(response && response.length){ - const internalProjects = (response as Array).filter(project=> project.key === this._KEY); - if(internalProjects && internalProjects.length){ - return {projectIdentifierExists:true}; + if (this.projectFormGroup != null) { + this.projectFormGroup.get('reference').valueChanges.pipe( + takeUntil(this._destroyed), + filter(value =>!isNullOrUndefined(value)), + tap(_ => this.isProjectPending = true), + debounceTime(500), + switchMap(value=> { + const requestItem = new RequestItem(); + requestItem.criteria = new ProjectCriteria(); + requestItem.criteria.exactReference = this._PROJECT_PREFIX + value; + return this.projectService.getWithExternal(requestItem).pipe(takeUntil(this._destroyed)); + }), + map(response=>{ + if(response && response.length){ + const internalProjects = (response as Array).filter(project=> project.key === this._KEY); + if(internalProjects && internalProjects.length){ + return {projectIdentifierExists:true}; + } + return null; } return null; + }) + ) + .subscribe(error=>{ + this.isProjectPending = false; + this.projectFormGroup.get('reference').setErrors(error); + if(!error && this.projectFormGroup.get('reference').validator){ + const validator = this.projectFormGroup.get('reference').validator({} as AbstractControl); + if(validator && validator.required && this.projectFormGroup.get('reference').touched && !this.projectFormGroup.get('reference').value){ + this.projectFormGroup.get('reference').setErrors({required : true}); + } } - return null; - }) - ) - .subscribe(error=>{ - this.isProjectPending = false; - this.projectFormGroup.get('reference').setErrors(error); - if(!error && this.projectFormGroup.get('reference').validator){ - const validator = this.projectFormGroup.get('reference').validator({} as AbstractControl); - if(validator && validator.required && this.projectFormGroup.get('reference').touched && !this.projectFormGroup.get('reference').value){ - this.projectFormGroup.get('reference').setErrors({required : true}); - } - } - }); + }); + } } configureAutoCompletes(): void { @@ -281,7 +300,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { this.grantformGroup.get('description').enable(); this.grantformGroup.get('reference').enable(); - this.grantformGroup.get('reference').setValidators(Validators.required); + if(this.isRequired) + this.grantformGroup.get('reference').setValidators(Validators.required); this.grantformGroup.get('reference').updateValueAndValidity(); } else if (this.isClone && !this.isNewVersion) { this.grantformGroup.get('existGrant').enable(); @@ -324,7 +344,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { this.projectFormGroup.get('description').enable(); this.projectFormGroup.get('reference').enable() - this.projectFormGroup.get('reference').setValidators(Validators.required); + if(this.isRequired) + this.projectFormGroup.get('reference').setValidators(Validators.required); this.projectFormGroup.get('reference').updateValueAndValidity(); } else if (this.isClone && !this.isNewVersion) { this.projectFormGroup.get('existProject').enable(); @@ -366,7 +387,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { this.funderFormGroup.get('label').enable(); this.funderFormGroup.get('reference').enable(); - this.funderFormGroup.get('reference').setValidators(Validators.required); + if(this.isRequired) + this.funderFormGroup.get('reference').setValidators(Validators.required); this.funderFormGroup.get('reference').updateValueAndValidity(); } else if (this.isClone && !this.isNewVersion) { @@ -381,7 +403,8 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { } else { this.funderFormGroup.get('label').enable(); this.funderFormGroup.get('reference').enable(); - this.funderFormGroup.get('reference').setValidators(Validators.required); + if(this.isRequired) + this.funderFormGroup.get('reference').setValidators(Validators.required); this.funderFormGroup.get('reference').updateValueAndValidity(); } } else if (this.isFinalized || this.isNewVersion || !this.isUserOwner) { @@ -405,17 +428,19 @@ export class FundingInfoComponent extends BaseComponent implements OnInit { } registerFormListeners() { - this.funderFormGroup.valueChanges - .pipe(takeUntil(this._destroyed)) - .subscribe(x => { - this.funderValueChanged(x); - }) + if (this.funderFormGroup != null) { + this.funderFormGroup.valueChanges + .pipe(takeUntil(this._destroyed)) + .subscribe(x => { + this.funderValueChanged(x); + }) + } } funderValueChanged(funder: any) { if ((funder.label !== "" && funder.label !== null && funder.label !== undefined && !isNullOrUndefined(funder.reference) && funder.reference.length ) || (funder.existFunder !== null && funder.existFunder !== undefined && funder.existFunder.id !== undefined)) { - this.grantformGroup.reset(); + //this.grantformGroup.reset(); this.grantformGroup.enable(); this.setGrantValidators(); } else { diff --git a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts index a2e00cd8d..b06b1fb89 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/funder-form-model.ts @@ -36,9 +36,9 @@ export class FunderFormModel { createValidationContext(): ValidationContext { const baseContext: ValidationContext = new ValidationContext(); baseContext.validation.push({ key: 'id', validators: [] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'label', validators: [BackendErrorValidator(this.validationErrorModel, 'label')] }); baseContext.validation.push({ key: 'status', validators: [] }); - baseContext.validation.push({ key: 'existFunder', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'existFunder')] }); + baseContext.validation.push({ key: 'existFunder', validators: [BackendErrorValidator(this.validationErrorModel, 'existFunder')] }); baseContext.validation.push({ key: 'reference', validators: [BackendErrorValidator(this.validationErrorModel, 'reference')] }); return baseContext; } diff --git a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts index 9a922c6a7..aa2f38789 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/grant-tab/grant-tab-model.ts @@ -41,10 +41,10 @@ export class GrantTabModel { createValidationContext(): ValidationContext { const baseContext: ValidationContext = new ValidationContext(); baseContext.validation.push({ key: 'id', validators: [] }); - baseContext.validation.push({ key: 'label', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'label')] }); + baseContext.validation.push({ key: 'label', validators: [BackendErrorValidator(this.validationErrorModel, 'label')] }); baseContext.validation.push({ key: 'status', validators: [] }); - baseContext.validation.push({ key: 'description', validators: [Validators.required, BackendErrorValidator(this.validationErrorModel, 'description')] }); - baseContext.validation.push({ key: 'existGrant', validators: [Validators.required, ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'existGrant')] }); + baseContext.validation.push({ key: 'description', validators: [BackendErrorValidator(this.validationErrorModel, 'description')] }); + baseContext.validation.push({ key: 'existGrant', validators: [ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'existGrant')] }); baseContext.validation.push({ key: 'funderId', validators: [ValidJsonValidator, BackendErrorValidator(this.validationErrorModel, 'funderId')] }); baseContext.validation.push({ key: 'reference', validators: [BackendErrorValidator(this.validationErrorModel, 'reference')] }); return baseContext; 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..1527c2c8d 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/listing/listing-item/dmp-listing-item.component.ts b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts index aa1830664..73760cb11 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.ts @@ -28,6 +28,9 @@ import { ExtraPropertiesFormModel } from '../../editor/general-tab/extra-propert import { GrantTabModel } from '../../editor/grant-tab/grant-tab-model'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { HttpClient } from '@angular/common/http'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; @Component({ selector: 'app-dmp-listing-item-component', @@ -53,6 +56,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { private authentication: AuthService, public enumUtils: EnumUtils, private dmpService: DmpService, + private dmpProfileService: DmpProfileService, private language: TranslateService, private uiNotificationService: UiNotificationService, private lockService: LockService, @@ -173,6 +177,16 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { this.dmpModel.status = DmpStatus.Draft; this.dmpFormGroup = this.dmpModel.buildForm(); + if (!isNullOrUndefined(this.dmpFormGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.dmpFormGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + if (!isNewVersion) { this.dmpFormGroup.get('label').setValue(dmp.label + " New"); } @@ -180,6 +194,48 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { }); } + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.dmpFormGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.dmpFormGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.dmpFormGroup.removeControl('project'); + } + } + openCloneDialog(isNewVersion: boolean) { const dialogRef = this.dialog.open(CloneDialogComponent, { maxWidth: '700px', diff --git a/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.html b/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.html index 941a735a4..66874939c 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.html +++ b/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.html @@ -30,14 +30,14 @@
    -
    + + -
    +
    -->
    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..a29352f1a 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 @@ -61,8 +61,10 @@ delete
    -
    {{'DMP-OVERVIEW.GRANT' | translate}}
    -
    {{ dmp.grant.label }}
    +
    +
    {{'DMP-OVERVIEW.GRANT' | translate}}
    +
    {{ dmp.grant.label }}
    +
    {{'DMP-OVERVIEW.RESEARCHERS' | translate}}
    @@ -87,7 +89,7 @@
    horizontal_rule
    -
    {{'DMP-OVERVIEW.DATASETS-USED' | translate}}
    +
    {{'DMP-OVERVIEW.DESCRIPTIONS-USED' | translate}}
    diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss index 9833fa58d..5f3773e0b 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss @@ -332,7 +332,7 @@ vertical-align: bottom; } -::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { +:host ::ng-deep .mat-form-field-appearance-outline .mat-form-field-infix { padding: 0rem 0rem 0.4rem 0rem !important; } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index d7978b1cb..c7c59f7bb 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -1,52 +1,54 @@ -import {Component, ElementRef, OnInit, ViewChild} from '@angular/core'; -import {MatDialog} from '@angular/material/dialog'; -import {ActivatedRoute, Params, Router} from '@angular/router'; -import {DatasetStatus} from '@app/core/common/enum/dataset-status'; -import {DmpStatus} from '@app/core/common/enum/dmp-status'; -import {Principal} from '@app/core/model/auth/principal'; -import {DatasetOverviewModel} from '@app/core/model/dataset/dataset-overview'; -import {DatasetsToBeFinalized} from '@app/core/model/dataset/datasets-toBeFinalized'; -import {DmpOverviewModel} from '@app/core/model/dmp/dmp-overview'; -import {UserInfoListingModel} from '@app/core/model/user/user-info-listing'; -import {AuthService} from '@app/core/services/auth/auth.service'; -import {DmpService} from '@app/core/services/dmp/dmp.service'; +import { Location } from '@angular/common'; +import { Component, ElementRef, OnInit, ViewChild } from '@angular/core'; +import { FormGroup } from '@angular/forms'; +import { MatDialog } from '@angular/material/dialog'; +import { ActivatedRoute, Params, Router } from '@angular/router'; +import { DatasetStatus } from '@app/core/common/enum/dataset-status'; +import { DmpStatus } from '@app/core/common/enum/dmp-status'; +import { Role } from "@app/core/common/enum/role"; +import { Principal } from '@app/core/model/auth/principal'; +import { DatasetOverviewModel } from '@app/core/model/dataset/dataset-overview'; +import { DatasetsToBeFinalized } from '@app/core/model/dataset/datasets-toBeFinalized'; +import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration'; +import { DmpModel } from '@app/core/model/dmp/dmp'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpOverviewModel } from '@app/core/model/dmp/dmp-overview'; +import { DoiModel } from '@app/core/model/doi/doi'; +import { UserInfoListingModel } from '@app/core/model/user/user-info-listing'; +import { VersionListingModel } from '@app/core/model/version/version-listing.model'; +import { AuthService } from '@app/core/services/auth/auth.service'; +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; +import { DepositRepositoriesService } from '@app/core/services/deposit-repositories/deposit-repositories.service'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; +import { DmpService } from '@app/core/services/dmp/dmp.service'; +import { LockService } from '@app/core/services/lock/lock.service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; -import {ConfirmationDialogComponent} from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { PopupNotificationDialogComponent } from '@app/library/notification/popup/popup-notification.component'; import { DmpFinalizeDialogComponent, DmpFinalizeDialogInput, DmpFinalizeDialogOutput } from '@app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component'; -import {BreadcrumbItem} from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; -import {BaseComponent} from '@common/base/base.component'; -import {TranslateService} from '@ngx-translate/core'; +import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; +import { BaseComponent } from '@common/base/base.component'; +import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; +import { TranslateService } from '@ngx-translate/core'; import * as FileSaver from 'file-saver'; -import {Observable, of as observableOf} from 'rxjs'; -import {map, takeUntil} from 'rxjs/operators'; -import {Role} from "@app/core/common/enum/role"; -import {DmpInvitationDialogComponent} from '../invitation/dmp-invitation-dialog.component'; -import {ConfigurationService} from '@app/core/services/configuration/configuration.service'; -import {Location} from '@angular/common'; -import {FormGroup} from '@angular/forms'; -import {LockService} from '@app/core/services/lock/lock.service'; -import {VersionListingModel} from '@app/core/model/version/version-listing.model'; -import {CloneDialogComponent} from '../clone/clone-dialog/clone-dialog.component'; -import {DmpModel} from '@app/core/model/dmp/dmp'; -import {DmpEditorModel} from '../editor/dmp-editor.model'; -import {FunderFormModel} from '../editor/grant-tab/funder-form-model'; -import {ProjectFormModel} from '../editor/grant-tab/project-form-model'; -import {GrantTabModel} from '../editor/grant-tab/grant-tab-model'; -import {ExtraPropertiesFormModel} from '../editor/general-tab/extra-properties-form.model'; -import {StartNewDmpDialogComponent} from '../start-new-dmp-dialogue/start-new-dmp-dialog.component'; -import {MatomoService} from '@app/core/services/matomo/matomo-service'; -import {PopupNotificationDialogComponent} from '@app/library/notification/popup/popup-notification.component'; -import {DepositRepositoriesService} from '@app/core/services/deposit-repositories/deposit-repositories.service'; -import {DepositConfigurationModel} from '@app/core/model/deposit/deposit-configuration'; -import {DoiModel} from '@app/core/model/doi/doi'; -import {isNullOrUndefined} from '@app/utilities/enhancers/utils'; +import { Observable, of as observableOf } from 'rxjs'; +import { map, takeUntil } from 'rxjs/operators'; +import { CloneDialogComponent } from '../clone/clone-dialog/clone-dialog.component'; +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 { DmpInvitationDialogComponent } from '../invitation/dmp-invitation-dialog.component'; +import { StartNewDmpDialogComponent } from '../start-new-dmp-dialogue/start-new-dmp-dialog.component'; @Component({ selector: 'app-dmp-overview', @@ -81,6 +83,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { private route: ActivatedRoute, private router: Router, private dmpService: DmpService, + private dmpProfileService: DmpProfileService, private depositRepositoriesService: DepositRepositoriesService, private translate: TranslateService, private authentication: AuthService, @@ -110,7 +113,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dmp = data; - if(!this.hasDoi()) { + if (!this.hasDoi()) { this.selectedModel = this.dmp.dois[0]; } this.checkLockStatus(this.dmp.id); @@ -137,7 +140,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.dmp = data; - if(!this.hasDoi()) { + if (!this.hasDoi()) { this.selectedModel = this.dmp.dois[0]; } // this.checkLockStatus(this.dmp.id); @@ -157,12 +160,12 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } }); this.depositRepositoriesService.getAvailableRepos() - .pipe(takeUntil(this._destroyed)) - .subscribe( - repos => { - this.depositRepos = repos; - }, - error => this.depositRepos = []); + .pipe(takeUntil(this._destroyed)) + .subscribe( + repos => { + this.depositRepos = repos; + }, + error => this.depositRepos = []); } onFetchingDeletedCallbackError(redirectRoot: string) { @@ -207,6 +210,17 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.dmpModel.fromModel(data); this.dmpModel.status = DmpStatus.Draft; this.formGroup = this.dmpModel.buildForm(); + + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + if (!isNewVersion) { this.formGroup.get('label').setValue(this.dmp.label + " New"); } @@ -214,6 +228,48 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { }); } + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } + openCloneDialog(isNewVersion: boolean) { const dialogRef = this.dialog.open(CloneDialogComponent, { maxWidth: '900px', @@ -516,7 +572,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { return this.depositRepos.filter(repo => !this.dmp.dois.find(doi => doi.repositoryId === repo.repositoryId)); } - moreDeposit(){ + moreDeposit() { return (this.dmp.dois.length < this.depositRepos.length); } @@ -552,30 +608,34 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe((result: DmpFinalizeDialogOutput) => { if (result && !result.cancelled) { - var datasetsToBeFinalized: DatasetsToBeFinalized = { - uuids: result.datasetsToBeFinalized - }; - this.dmpService.finalize(datasetsToBeFinalized, this.dmp.id) - .pipe(takeUntil(this._destroyed)) - .subscribe( - complete => { - if(extraProperties.visible){ - //this.publish(this.dmp.id); - this.dmpService.publish(this.dmp.id) - .pipe(takeUntil(this._destroyed)) - .subscribe(() => { - //this.hasPublishButton = false; - this.dmp.status = DmpStatus.Finalized; - this.onUpdateCallbackSuccess(); - }); - } - else{ - this.dmp.status = DmpStatus.Finalized; - this.onUpdateCallbackSuccess(); - } - }, - error => this.onUpdateCallbackError(error) - ); + this.checkIfAnyProfileIsUsedLessThanMin(data).subscribe(checked => { + if (!checked) { + var datasetsToBeFinalized: DatasetsToBeFinalized = { + uuids: result.datasetsToBeFinalized + }; + this.dmpService.finalize(datasetsToBeFinalized, this.dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe( + complete => { + if (extraProperties.visible) { + //this.publish(this.dmp.id); + this.dmpService.publish(this.dmp.id) + .pipe(takeUntil(this._destroyed)) + .subscribe(() => { + //this.hasPublishButton = false; + this.dmp.status = DmpStatus.Finalized; + this.onUpdateCallbackSuccess(); + }); + } + else { + this.dmp.status = DmpStatus.Finalized; + this.onUpdateCallbackSuccess(); + } + }, + error => this.onUpdateCallbackError(error) + ); + } + }) } }); @@ -583,6 +643,38 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } + private checkIfAnyProfileIsUsedLessThanMin(dmpModel: DmpModel): Observable { + const blueprintId = dmpModel.profile.id; + return this.dmpProfileService.getSingleBlueprint(blueprintId) + .pipe(map(result => { + return result.definition.sections.some(section => { + if (!section.hasTemplates) + return false; + return section.descriptionTemplates.some(template => { + if (!(template.minMultiplicity > 0)) + return false; + let count = 0; + dmpModel.datasets.filter(dataset => dataset.dmpSectionIndex === (section.ordinal - 1)).forEach(dataset => { + if (dataset.profile.id === template.descriptionTemplateId) { + count++; + } + }) + if (count < template.minMultiplicity) { + this.dialog.open(PopupNotificationDialogComponent, { + data: { + title: this.language.instant('DMP-OVERVIEW.MIN-DESCRIPTIONS-DIALOG.TITLE', { 'minMultiplicity': template.minMultiplicity }), + message: this.language.instant('DMP-OVERVIEW.MIN-DESCRIPTIONS-DIALOG.MESSAGE',) + }, maxWidth: '30em' + }); + return true; + } + else + return false; + }) + }) + }), takeUntil(this._destroyed)); + } + // newVersion(id: String, label: String) { // let url = this.router.createUrlTree(['/plans/new_version/', id, { dmpLabel: label }]) // window.open(url.toString(), '_blank') @@ -643,7 +735,7 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.router.navigate(['/datasets', 'new', this.dmp.id]); } - selectDoi(doiModel: DoiModel){ + selectDoi(doiModel: DoiModel) { this.selectedModel = doiModel; const foundIdx = this.dmp.dois.findIndex(el => el.id == doiModel.id); this.dmp.dois.splice(foundIdx, 1); @@ -652,17 +744,17 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { createDoiLink(doiModel: DoiModel): string { const repository = this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId); - if(typeof repository !== "undefined"){ - if(doiModel.repositoryId == "Zenodo"){ + if (typeof repository !== "undefined") { + if (doiModel.repositoryId == "Zenodo") { const doiarr = doiModel.doi.split('.'); const id = doiarr[doiarr.length - 1]; return repository.repositoryRecordUrl + id; } - else{ + else { return repository.repositoryRecordUrl + doiModel.doi; } } - else{ + else { return ""; } } @@ -765,11 +857,13 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { this.lockService.checkLockStatus(id).pipe(takeUntil(this._destroyed)) .subscribe(lockStatus => { this.lockStatus = lockStatus - if(lockStatus){ - this.dialog.open(PopupNotificationDialogComponent,{data:{ - title:this.language.instant('DMP-OVERVIEW.LOCKED-DIALOG.TITLE'), - message:this.language.instant('DMP-OVERVIEW.LOCKED-DIALOG.MESSAGE') - }, maxWidth:'30em'}); + if (lockStatus) { + this.dialog.open(PopupNotificationDialogComponent, { + data: { + title: this.language.instant('DMP-OVERVIEW.LOCKED-DIALOG.TITLE'), + message: this.language.instant('DMP-OVERVIEW.LOCKED-DIALOG.MESSAGE') + }, maxWidth: '30em' + }); } }); } 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..208a8f2e0 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 @@ -1,6 +1,4 @@ import { FormBuilder, FormGroup, Validators } from "@angular/forms"; -import { Status } from '@app/core/common/enum/status'; -import { DmpProfile, DmpProfileDefinition } from '@app/core/model/dmp-profile/dmp-profile'; import { DmpModel } from '@app/core/model/dmp/dmp'; import { DmpDynamicField } from '@app/core/model/dmp/dmp-dynamic-field'; import { DmpDynamicFieldDependency } from '@app/core/model/dmp/dmp-dynamic-field-dependency'; @@ -17,6 +15,8 @@ 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"; +import { DmpExtraFieldEditorModel } from "../editor/dmp-editor.model"; export class DmpWizardEditorModel { public id: string; @@ -33,17 +33,17 @@ 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; + public extraFields: Array = []; public dynamicFields: Array = []; public validationErrorModel: ValidationErrorModel = new ValidationErrorModel(); public extraProperties: ExtraPropertiesFormModel; fromModel(item: DmpModel): DmpWizardEditorModel { this.id = item.id; - this.profile = item.profile; + this.profile = item.profile.id; this.label = item.label; this.groupId = item.groupId; this.version = item.version; @@ -58,7 +58,7 @@ export class DmpWizardEditorModel { this.profiles = item.profiles; this.associatedUsers = item.associatedUsers; this.users = item.users; - if (item.definition) { this.definition = item.definition; } + if (item.extraFields) { item.extraFields.map(x => this.extraFields.push(new DmpExtraFieldEditorModel().fromModel(x))); } if (item.dynamicFields) { item.dynamicFields.map(x => this.dynamicFields.push(new DmpDynamicFieldEditorModel().fromModel(x))); } this.creator = item.creator; this.extraProperties.fromModel(item.extraProperties); @@ -90,9 +90,12 @@ export class DmpWizardEditorModel { const dynamicFields = new Array(); if (this.dynamicFields) { this.dynamicFields.forEach(item => dynamicFields.push(item.buildForm())); } - formGroup.addControl('dynamicFields', new FormBuilder().array(dynamicFields)); + const extraFields = new Array(); + if (this.extraFields) { this.extraFields.forEach(item => extraFields.push(item.buildForm())); } + formGroup.addControl('extraFields', new FormBuilder().array(extraFields)); + return formGroup; } diff --git a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts index b25b10731..1d8c100a7 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dmp/wizard/dmp-wizard.component.ts @@ -5,6 +5,8 @@ import { FormGroup } from '@angular/forms'; import { MatSnackBar } from '@angular/material/snack-bar'; import { ActivatedRoute, Params, Router } from '@angular/router'; import { DmpModel } from '@app/core/model/dmp/dmp'; +import { DmpBlueprintDefinition, SystemFieldType } from '@app/core/model/dmp/dmp-blueprint/dmp-blueprint'; +import { DmpProfileService } from '@app/core/services/dmp/dmp-profile.service'; import { DmpService } from '@app/core/services/dmp/dmp.service'; import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; import { FunderFormModel } from '@app/ui/dmp/editor/grant-tab/funder-form-model'; @@ -13,6 +15,7 @@ import { ProjectFormModel } from '@app/ui/dmp/editor/grant-tab/project-form-mode import { DmpWizardEditorModel } from '@app/ui/dmp/wizard/dmp-wizard-editor.model'; import { BreadcrumbItem } from '@app/ui/misc/breadcrumb/definition/breadcrumb-item'; import { IBreadCrumbComponent } from '@app/ui/misc/breadcrumb/definition/IBreadCrumbComponent'; +import { isNullOrUndefined } from '@app/utilities/enhancers/utils'; import { BaseComponent } from '@common/base/base.component'; import { ValidationErrorModel } from '@common/forms/validation/error-model/validation-error-model'; import { TranslateService } from '@ngx-translate/core'; @@ -35,6 +38,7 @@ export class DmpWizardComponent extends BaseComponent implements OnInit, IBreadC constructor( private dmpService: DmpService, + private dmpProfileService: DmpProfileService, private language: TranslateService, private snackBar: MatSnackBar, private route: ActivatedRoute, @@ -58,6 +62,16 @@ export class DmpWizardComponent extends BaseComponent implements OnInit, IBreadC this.dmp.fromModel(data); this.formGroup = this.dmp.buildForm(); + if (!isNullOrUndefined(this.formGroup.get('profile').value)) { + this.dmpProfileService.getSingleBlueprint(this.formGroup.get('profile').value) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + this.checkForGrant(result.definition); + this.checkForFunder(result.definition); + this.checkForProject(result.definition); + }); + } + if (this.route.routeConfig.path.startsWith('new_version/')) { this.formGroup.get('version').setValue(this.formGroup.get('version').value + 1); this.formGroup.controls['label'].disable(); @@ -75,6 +89,47 @@ export class DmpWizardComponent extends BaseComponent implements OnInit, IBreadC }); } + private checkForGrant(blueprint: DmpBlueprintDefinition) { + let hasGrant = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.GRANT) { + hasGrant = true; + } + } + )); + if (!hasGrant) { + this.formGroup.removeControl('grant'); + } + } + + private checkForFunder(blueprint: DmpBlueprintDefinition) { + let hasFunder = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.FUNDER) { + hasFunder = true; + } + } + )); + if (!hasFunder) { + this.formGroup.removeControl('funder'); + } + } + + private checkForProject(blueprint: DmpBlueprintDefinition) { + let hasProject = false; + blueprint.sections.forEach(section => section.fields.forEach( + field => { + if (field.category as unknown === 'SYSTEM' && field.type === SystemFieldType.PROJECT) { + hasProject = true; + } + } + )); + if (!hasProject) { + this.formGroup.removeControl('project'); + } + } submit() { this.saving = true; 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/dataset-description-form/components/form-composite-field/form-composite-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html index 24f35ac7a..80d8606c0 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field/form-composite-field.component.html @@ -10,7 +10,7 @@
    -
    @@ -52,7 +52,7 @@
    -
    @@ -64,10 +64,10 @@
    diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html index ccfc2e038..e24890e11 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.html @@ -114,7 +114,8 @@ [placeholder]="form.get('data').value.label" [required]="form.get('validationRequired').value" [wrapperClasses]="'full-width editor ' + - ((form.get('validationRequired').value && form.get('value').touched && form.get('value').hasError('required')) ? 'required' : '')"> + ((form.get('validationRequired').value && form.get('value').touched && form.get('value').hasError('required')) ? 'required' : '')" + [editable]="!form.get('value').disabled">
    @@ -125,7 +126,7 @@
    + [multiple]="false" [accept]="typesToString()" [disabled]="form.get('value').disabled"> {{ form.value.value.name }} @@ -134,12 +135,13 @@
    - @@ -422,12 +424,14 @@
    - + {{'GENERAL.VALIDATION.REQUIRED' | translate}} - + {{ type.name }} @@ -451,7 +455,7 @@
    -
    +
    {{'GENERAL.VALIDATION.REQUIRED' | translate}} @@ -467,7 +471,7 @@
    - + {{'GENERAL.VALIDATION.REQUIRED' | translate}}
    diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts index 23320fe92..0bc73c23f 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.ts @@ -5,7 +5,7 @@ import { DatasetProfileComboBoxType } from '@app/core/common/enum/dataset-profil import { DatasetProfileFieldViewStyle } from '@app/core/common/enum/dataset-profile-field-view-style'; import { DatasetProfileInternalDmpEntitiesType } from '@app/core/common/enum/dataset-profile-internal-dmp-entities-type'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; -import { DatasetExternalAutocompleteCriteria } from '@app/core/query/dataset/daatset-external-autocomplete-criteria'; +import { DatasetExternalAutocompleteCriteria, DatasetExternalAutocompleteOptionsCriteria } from '@app/core/query/dataset/daatset-external-autocomplete-criteria'; import { DatasetCriteria } from '@app/core/query/dataset/dataset-criteria'; import { DmpCriteria } from '@app/core/query/dmp/dmp-criteria'; import { RequestItem } from '@app/core/query/request-item'; @@ -61,7 +61,7 @@ export class FormFieldComponent extends BaseComponent implements OnInit { @Input() form: FormGroup; @Input() datasetProfileId: any; @Input() isChild: Boolean = false; - @Input() autocompleteOptions: AutoCompleteSingleData; + autocompleteOptions: AutoCompleteSingleData[]; visible: boolean = true; _renderStyle: DatasetProfileFieldViewStyle = null; @@ -189,6 +189,9 @@ export class FormFieldComponent extends BaseComponent implements OnInit { subtitleFn: (item) => { try { return item['source'] ? this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-SUBTITLE') + item['source'] : this.language.instant('DATASET-WIZARD.EDITOR.FIELDS.EXTERNAL-AUTOCOMPLETE-NO-SOURCE') } catch { return '' } } } } + if(isNullOrUndefined(this.datasetProfileId)){ + this.autocompleteOptions = this.form.get('data').value.autoCompleteSingleDataList; + } } switch (this.form.get('viewStyle').value.renderStyle) { @@ -268,7 +271,7 @@ export class FormFieldComponent extends BaseComponent implements OnInit { initialItems: () => this.searchDatasetExternalRegistries(''), displayFn: (item) => { try { return typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name } catch { return '' } }, titleFn: (item) => { try { return typeof (item) == 'string' ? JSON.parse(item)['name'] : item.name } catch { return '' } }, - subtitleFn: (item) => { try { return item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') } catch { return '' } }, + subtitleFn: (item) => { try { return item.source ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.source : item.tag ? this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.SOURCE:') + item.tag : this.language.instant('TYPES.EXTERNAL-DATASET-TYPE.NO-SOURCE') } catch { return '' } }, valueAssign: (item) => { try { return typeof (item) == 'string' ? item : JSON.stringify(item) } catch { return '' } } }; break; @@ -314,8 +317,12 @@ export class FormFieldComponent extends BaseComponent implements OnInit { break; case DatasetProfileFieldViewStyle.DatasetIdentifier: const value = this.form.get('value').value; + const disabled = this.form.disabled; this.form.removeControl('value'); this.form.addControl('value', new DatasetIdModel(value).buildForm()); + if(disabled) { + this.form.disable(); + } this.datasetIdInitialized = true; break; case DatasetProfileFieldViewStyle.Currency: @@ -329,8 +336,12 @@ export class FormFieldComponent extends BaseComponent implements OnInit { break; case DatasetProfileFieldViewStyle.Validation: const value1 = this.form.get('value').value; + const disabled1 = this.form.disabled; this.form.removeControl('value'); this.form.addControl('value', new DatasetIdModel(value1).buildForm()); + if(disabled1) { + this.form.disable(); + } //this.datasetIdInitialized = true; break; } @@ -377,29 +388,32 @@ export class FormFieldComponent extends BaseComponent implements OnInit { // } searchFromAutocomplete(query: string) { - const autocompleteRequestItem: RequestItem = new RequestItem(); - autocompleteRequestItem.criteria = new DatasetExternalAutocompleteCriteria(); - let parseIdArray: string[] = this.form.get('id').value.split('_'); - if(parseIdArray.length > 1) { - autocompleteRequestItem.criteria.fieldID = parseIdArray[parseIdArray.length - 1]; - } else { - autocompleteRequestItem.criteria.fieldID = this.form.get('id').value; - } - if (typeof this.datasetProfileId === 'string') { - autocompleteRequestItem.criteria.profileID = this.datasetProfileId; - } else if (this.datasetProfileId != null) { - autocompleteRequestItem.criteria.profileID = this.datasetProfileId.id; - } else if (this.autocompleteOptions != null) { - autocompleteRequestItem.criteria.autocompleteOptions = this.autocompleteOptions; - } else { - throw "Could not load autocomplete options."; - } - autocompleteRequestItem.criteria.like = query; if (this.autocompleteOptions) { + const autocompleteRequestItem: RequestItem = new RequestItem(); + autocompleteRequestItem.criteria = new DatasetExternalAutocompleteOptionsCriteria(); + autocompleteRequestItem.criteria.autoCompleteSingleDataList = this.autocompleteOptions; + autocompleteRequestItem.criteria.like = query; return this.datasetExternalAutocompleteService.queryApi(autocompleteRequestItem); } - return this.datasetExternalAutocompleteService.queryAutocomplete(autocompleteRequestItem); + else{ + const autocompleteRequestItem: RequestItem = new RequestItem(); + autocompleteRequestItem.criteria = new DatasetExternalAutocompleteCriteria(); + let parseIdArray: string[] = this.form.get('id').value.split('_'); + if(parseIdArray.length > 1) { + autocompleteRequestItem.criteria.fieldID = parseIdArray[parseIdArray.length - 1]; + } else { + autocompleteRequestItem.criteria.fieldID = this.form.get('id').value; + } + if (typeof this.datasetProfileId === 'string') { + autocompleteRequestItem.criteria.profileID = this.datasetProfileId; + } + else if (this.datasetProfileId != null) { + autocompleteRequestItem.criteria.profileID = this.datasetProfileId.id; + } + autocompleteRequestItem.criteria.like = query; + return this.datasetExternalAutocompleteService.queryAutocomplete(autocompleteRequestItem); + } } searchResearchers(query: string) { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts index 25691b74f..dd3cfa289 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component.ts @@ -1,4 +1,4 @@ -import { Component, ElementRef, Input, OnInit } from '@angular/core'; +import {ChangeDetectorRef, Component, ElementRef, Input, OnChanges, OnInit, SimpleChanges} from '@angular/core'; import { AbstractControl, FormArray, FormControl, FormGroup } from '@angular/forms'; import { VisibilityRulesService } from '@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service'; import { BaseComponent } from '@common/base/base.component'; @@ -9,7 +9,7 @@ import { takeUntil } from 'rxjs/operators'; templateUrl: './form-progress-indication.component.html', styleUrls: ['./form-progress-indication.component.scss'] }) -export class FormProgressIndicationComponent extends BaseComponent implements OnInit { +export class FormProgressIndicationComponent extends BaseComponent implements OnInit, OnChanges { @Input() formGroup: FormGroup; @Input() isDmpEditor: boolean; @Input() isDatasetEditor: boolean; @@ -23,6 +23,16 @@ export class FormProgressIndicationComponent extends BaseComponent implements On public value = 0; ngOnInit() { + this.init(); + } + + ngOnChanges(changes: SimpleChanges) { + if(changes.formGroup) { + this.init(); + } + } + + init() { setTimeout(() => {this.calculateValueForProgressbar();}); this.formGroup .valueChanges @@ -38,7 +48,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup); } else if (this.isDatasetEditor) { this.progressSoFar = this.countFormControlsValidForProgress(this.formGroup) + this.countFormControlsWithValueForProgress(this.formGroup); - this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup) + this.CountFormControlDepthLengthFotTotal(this.formGroup); + this.total = this.countFormControlsRequiredFieldsForTotal(this.formGroup, true) + this.CountFormControlDepthLengthFotTotal(this.formGroup); } else { this.progressSoFar = this.countFormControlsWithValueForProgress(this.formGroup); this.total = this.CountFormControlDepthLengthFotTotal(this.formGroup); @@ -51,7 +61,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On let valueCurent = 0; if (formControl instanceof FormGroup) { if (this.checkFormsIfIsFieldsAndVisible(formControl) && this.checkIfIsRequired((formControl as FormGroup))) { - if (this.haseValue(formControl)) + if (this.hasValue(formControl)) valueCurent++; } if (this.chechFieldIfIsFieldSetAndVisible((formControl as FormGroup)) && this.checkIfIsRequired((formControl as FormGroup))) { @@ -69,11 +79,8 @@ export class FormProgressIndicationComponent extends BaseComponent implements On } return valueCurent; } - private haseValue(formGroup: FormGroup): boolean { - if (formGroup.get('value').value != null && formGroup.get('value').value !== '' && this.visibilityRulesService.checkElementVisibility(formGroup.get('id').value)) { - return true; - } - return false; + private hasValue(formGroup: FormGroup): boolean { + return formGroup.get('value').valid && formGroup.get('value').value != null && formGroup.get('value').value !== '' && this.visibilityRulesService.checkElementVisibility(formGroup.get('id').value); } private compositeFieldsGetChildsForProgress(formGroup: FormGroup): number { @@ -146,7 +153,7 @@ export class FormProgressIndicationComponent extends BaseComponent implements On countFormControlsValidForProgress(formControl: AbstractControl): number { let valueCurrent = 0; if (formControl instanceof FormControl) { - if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl['nativeElement'] && formControl.valid) { + if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl.valid) { valueCurrent++; } } else if (formControl instanceof FormGroup) { @@ -162,20 +169,22 @@ export class FormProgressIndicationComponent extends BaseComponent implements On return valueCurrent; } - countFormControlsRequiredFieldsForTotal(formControl: AbstractControl): number { + countFormControlsRequiredFieldsForTotal(formControl: AbstractControl, checkVisibility = false): number { let valueCurrent = 0; if (formControl instanceof FormControl) { - if (this.controlRequired(formControl) && this.controlEnabled(formControl) && formControl['nativeElement']) { + if (this.controlRequired(formControl) && this.controlEnabled(formControl)) { valueCurrent++; } } else if (formControl instanceof FormGroup) { - Object.keys(formControl.controls).forEach(item => { - const control = formControl.get(item); - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control); - }); + if(!checkVisibility || (!formControl.get('id')?.value || this.visibilityRulesService.checkElementVisibility(formControl.get('id').value))) { + Object.keys(formControl.controls).forEach(item => { + const control = formControl.get(item); + valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(control, checkVisibility); + }); + } } else if (formControl instanceof FormArray) { formControl.controls.forEach(item => { - valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item); + valueCurrent = valueCurrent + this.countFormControlsRequiredFieldsForTotal(item, checkVisibility); }); } return valueCurrent; diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html index a71b95049..43c45f710 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.html @@ -32,7 +32,7 @@
    - + @@ -44,7 +44,7 @@ + [wrapperClasses]="'mb-2'" [editable]="!compositeFieldFormGroup.get('commentFieldValue').disabled">
    @@ -116,7 +116,7 @@
    {{fieldFormGroup.getRawValue() | fieldValue | translate}} - -
    - + @@ -139,7 +139,7 @@
    - + @@ -151,7 +151,7 @@ + [wrapperClasses]="' mb-2'" [editable]="!fieldsetEntry.form.get('commentFieldValue').disabled">
    diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts index a87a937a9..f04760f7d 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.ts @@ -158,7 +158,6 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha const outerRules = (this.visibilityRulesService.getVisibilityDependency(target) as VisibilityRuleSource[]).filter(x => x.sourceControlId === element.id); const updatedRules = outerRules.map(x => { - console.log(idMappings, element); return {...x, sourceControlId: idMappings.find(y => y.old === element.id).new}; }); @@ -217,6 +216,9 @@ export class FormSectionComponent extends BaseComponent implements OnInit, OnCha } addMultipleField(fieldsetIndex: number) { + if(this.form.get('compositeFields').get('' + fieldsetIndex).disabled) { + return; + } const compositeFieldToBeCloned = (this.form.get('compositeFields').get('' + fieldsetIndex) as FormGroup).getRawValue(); const multiplicityItemsArray = ((this.form.get('compositeFields').get('' + fieldsetIndex).get('multiplicityItems'))); diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html index c827ecbf3..ca244cf88 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.html @@ -10,7 +10,6 @@
    - {{form | json}} diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts index 44c1dd3fa..cfdeffefa 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/tableOfContentsMaterial/table-of-contents.ts @@ -57,6 +57,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges @Input() selectedFieldsetId:string; private _tocentrySelected:ToCEntry = null; + private isSelecting: boolean = false; private _intersectionObserver: IntersectionObserver; private _actOnObservation: boolean = true; public hiddenEntries:string[] = []; @@ -442,8 +443,14 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges } onToCentrySelected(entry: ToCEntry = null, execute: boolean = true){ - this.tocentrySelected = entry; - this.entrySelected.emit({entry: entry, execute: execute}); + if(!this.isSelecting) { + this.isSelecting = true; + this.tocentrySelected = entry; + this.entrySelected.emit({entry: entry, execute: execute}); + setTimeout(() => { + this.isSelecting = false; + }, 600); + } } private _findTocEntryById(id: string, tocentries: ToCEntry[]): ToCEntry{ @@ -496,6 +503,7 @@ export class TableOfContents extends BaseComponent implements OnInit, OnChanges return this.tocentries.some(e => this.internalTable.invalidChildsVisible(e)); } + protected readonly console = console; } export interface LinkToScroll { 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/config/config.json b/dmp-frontend/src/assets/config/config.json index 3b2190325..50fe387e4 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -48,6 +48,10 @@ { "label": "GENERAL.LANGUAGES.POLISH", "value": "pl" + }, + { + "label": "GENERAL.LANGUAGES.BASQUE", + "value": "baq" } ], "loginProviders": { @@ -101,5 +105,10 @@ "allowOrganizationCreator": true, "useSplash": false, "orcidPath": "https://orcid.org/", - "maxFileSizeInMB": 10 + "maxFileSizeInMB": 10, + "newReleaseNotification": { + "link": "https://www.openaire.eu/gazing-the-future-output-management-plans", + "versionCode": "0", + "expires": "2024-02-15T00:00" + } } diff --git a/dmp-frontend/src/assets/i18n/baq.json b/dmp-frontend/src/assets/i18n/baq.json new file mode 100644 index 000000000..4e81b6799 --- /dev/null +++ b/dmp-frontend/src/assets/i18n/baq.json @@ -0,0 +1,1921 @@ +{ + "APP_NAME": "Argos", + "APP_NAME_CAPS": "ARGOS", + "GENERAL": { + "VALIDATION": { + "REQUIRED": "Derrigorrezkoa", + "GRANT-START-AFTER-END": "Diru-laguntzaren hasiera-data ezin da izan amaiera-data baino geroagokoa", + "PATTERN-_": "Karaktere hau \"_\" ez dago baimenduta", + "URL": { + "LABEL": "URL", + "MESSAGE": "Mesedez, eman baliozko URL bat" + } + }, + "DELETE-CONFIRMATION": { + "TITLE": "Kontuz", + "MESSAGE": "Ziur zaude item hau ezabatu nahi duzula?", + "POSITIVE": "Bai", + "NEGATIVE": "Ezeztatu" + }, + "SNACK-BAR": { + "SUCCESSFUL-CREATION": "Ondo sortu da", + "SUCCESSFUL-UPDATE": "Ondo eguneratu da", + "SUCCESSFUL-LOGIN": "Saioa-hasiera egokia", + "SUCCESSFUL-LOGOUT": "Saio-amaiera egokia", + "SUCCESSFUL-EMAIL-SEND": "E-maila ondo bidali da", + "SUCCESSFUL-COPY-TO-CLIPBOARD": "Arbelean kopiatu da", + "UNSUCCESSFUL-LOGOUT": "Saio-amaiera ez da burutu", + "UNSUCCESSFUL-LOGIN": "Saio-hasiera ez da burutu", + "SUCCESSFUL-DATASET-PROFILE-DELETE": "Ondo ezabatu da", + "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Txantiloi hau ezin da ezabatu, Datu-multzo honekin lotuta dagoelako", + "SUCCESSFUL-DELETE": "Ondo ezabatu da", + "UNSUCCESSFUL-DELETE": "Ez da ondo ezabatu", + "UNSUCCESSFUL-EMAIL-SEND": "E-mailaren bidalketak huts egin du", + "UNSUCCESSFUL-REMOVE-TEMPLATE": "Ezin da txantiloia ezabatu, DKP honetako Datu-multzo bat edo gehiagok txantiloi hau erabiltzen du" + }, + "ERRORS": { + "HTTP-REQUEST-ERROR": "Espero gabeko akats bat gertatu da" + }, + "NAMES": { + "DATASET": "Datu-multzoa" + }, + "STATUSES": { + "EDIT": "Editatuta", + "FINALISED": "Amaituta" + }, + "FORM-VALIDATION-DISPLAY-DIALOG": { + "WARNING": "Kontuz!", + "THIS-FIELD": "Eremu honek", + "HAS-ERROR": "Errorea dauka", + "REQUIRED": "Derrigorrezkoa", + "EMAIL": "E-mail baliogabea", + "MIN-VALUE": "Gutxieneko balio hau izan behar du {{min}}", + "MAX-VALUE": "Gehienezko balio hau izan behar du {{max}}", + "ACTIONS": { + "CANCEL": "Itxi" + } + }, + "CONFIRMATION-DIALOG": { + "DELETE-ITEM": "Item hau ezabatu nahi duzu?", + "DELETE-USER": "Kolaboratzaile hau ezabatu nahi duzu?", + "FINALIZE-ITEM": "Item honekin amaitu nahi duzu?", + "UNFINALIZE-ITEM": "Amaiera desegin nahi duzu?", + "PUBLISH-ITEM": "Item hau argitaratu nahi duzu?", + "ADD-DATASET": "Zure DKPra Datu-multzoa gehitzen jarraitu nahi duzu? Datu-multzo gehiago gehitu ditzakezu hau erabilita \"Gehitu Datu-multzoa (Laguntzailea)\" menua.", + "ZENODO-DOI": "Objektuen identifikatzaile digitala (DOI) sortu nahi duzu {{username}} DKParen erabiltzaile honekin?", + "LEAVE-PAGE": "Saioa uzten baduzu, zure aldaketak galdu egingo dira.", + "LEAVE-WARNING": "Gorde gabeko aldaketak dituzu!", + "PRIVACY-POLICY-NAMES": "DKP honetan sartuta dauden pertsona guztien izenak publikoki ikusgai egongo dira. Honekin ados zaude?", + "ACTIONS": { + "CONFIRM": "Bai", + "NO": "Ez", + "DELETE": "Ezabatu", + "REMOVE": "Kendu", + "CANCEL": "Ezeztatu", + "LEAVE": "Utzi", + "POLICY-AGREE": "Egin izenak publikoki ikusgai.", + "REQUIRED": "Kutxan klikatzea derrigorrezkoa da." + } + }, + "NOTIFICATION-DIALOG": { + "POPUP": { + "TITLE": "Datu-multzoa faltan", + "MESSAGE": "Gutxienez Datu-multzo bat sortu behar da DKPa gordetzeko.", + "CLOSE": "Itxi" + } + }, + "START-NEW-DMP-DIALOG": { + "IMPORT": "Inportatu", + "FUNCTION-SUPPORTS": "funtzioak onartzen du", + "JSON-FILES": ".json fitxategiak", + "PRODUCED": "ekoiztuta", + "RDA-SPECIFICATIONS": "RDAren zehaztapenen arabera", + "MACHINE-ACTIONABLE": "makina bidez prozesatu daitezkeen DKPetarako", + "UPLOAD-FILE": "Fitxategia kargatu", + "REPLACE-FILE": "Fitxategia ordezkatu" + }, + "INVITATION-DIALOG": { + "HINT": "Sakatu koma edo intro egileen artean", + "SUCCESS": "Gonbidapena ondo bidali da", + "ERROR": "Gonbidapenaren bidalketak huts egin du" + }, + "DMP-TO-DATASET-DIALOG": { + "FROM-DMP": "Modu egokian sortu da zure", + "DMP": "DKPa", + "TO-DATASET": "Hona transferituko zaizu", + "DATASET": "Datu-multzoa", + "EDITOR": "editorea", + "START": "Has gaitezen" + }, + "ACTIONS": { + "VIEW-ALL": "Ikusi DENAK", + "SHOW-MORE": "Erakutsi gehiago", + "LOAD-MORE": "Kargatu gehiago", + "LOAD-LESS": "Kargatu gutxiago", + "SHOW-LESS": "Erakutsi gutxiago", + "LOG-IN": "Hasi saioa", + "TAKE-A-TOUR": "Laguntza behar duzu? Buelta bat eman..", + "NO-MORE-AVAILABLE": "Ez dago beste emaitzarik eskuragarri" + }, + "PREPOSITIONS": { + "OF": "-en" + }, + "TITLES": { + "PREFIX": "{{ APP_NAME }} - ", + "GENERAL": "Datuen Kudeaketa Planen Sortzailea", + "ABOUT": "Honi buruz", + "PRIVACY": "Pribatutasun-politika", + "OPENSOURCE-LICENCES": "Lizentzia irekiak", + "TERMS": "Zerbitzuaren baldintzak", + "COOKIES-POLICY": "Cookie Politika", + "PLANS": "Nire DKPak", + "EXPLORE-PLANS": "Argitaratutako DKPak", + "QUICK-WIZARD": "DKP Berria (Laguntzailea)", + "PLANS-NEW": "DKP Berria (Aditua)", + "DMP-NEW": "DKP Berria", + "DATASETS": "Nire Datu-multzoak", + "EXPLORE": "Argitaratutako Datu-multzoak", + "DATASETCREATEWIZARD": "Gehitu Datu-multzoak (Laguntzailea)", + "GRANTS": "Nire diru-laguntzak", + "DMP-PROFILES": "DKP Txantiloiak", + "DATASET-PROFILES": "Datu-multzoen txantiloiak", + "USERS": "Erabiltzaileak", + "PROFILE": "Nire profila", + "LOGIN": "Hasi saioa", + "DMP-OVERVIEW": "DKParen Ikuspegi orokorra", + "DMP-EDIT": "Editatu DKPa", + "DATASET-OVERVIEW": "Datu-multzoen Ikuspegi orokorra", + "DATASET-EDIT": "Datu-multzoa Ikusi/Editatu", + "DMP-NEW-VERSION": "DKP Bertsio Berria", + "DMP-CLONE": "DKPa Klonatu", + "DATASET-NEW": "Datu-multzo Berria", + "GRANT-NEW": "Diru-laguntza Berria", + "GRANT-EDIT": "Diru-laguntza Ikusi/Editatu", + "DMP-PROFILE-NEW": "DKP Txantiloi Berria", + "DMP-PROFILE-EDIT": "Editatu DKP Txantiloia", + "DATASET-PROFILES-NEW": "Datu-multzo Txantiloi Berria", + "DATASET-PROFILES-EDIT": "Editatu Datu-multzo Txantiloia", + "EXPLORE-PLANS-OVERVIEW": "Argitaratutako DKParen Ikuspegi orokorra", + "DATASET-PUBLIC-EDIT": "Ikusi Argitaratutako Datu-multzoa", + "DMP-PUBLIC-EDIT": "Ikusi Argitaratutako DKPa", + "DATASET-COPY": "Kopiatu Datu-multzoa", + "DATASET-UPDATE": "Eguneratu Datu-multzoa", + "DATASET-PROFILES-NEW-VERSION": "Datu-multzo Txantiloiaren Bertsio Berria", + "DATASET-PROFILES-CLONE": "Datu-multzo Txantiloiaren Klon Berria", + "LANGUAGE-EDITOR": "Hizkuntza editorea", + "GUIDE-EDITOR": "Erabiltzaile gidaren editorea", + "LANGUAGE": "Hizkuntza", + "SIGN-IN": "Sartu kontuan" + }, + "FILE-TYPES": { + "PDF": "PDF", + "XML": "XML", + "JSON": "RDA JSON", + "DOC": "Dokumentua" + }, + "LANGUAGES": { + "ENGLISH": "Ingelesa", + "GREEK": "Grekoa", + "SPANISH": "Espainiera", + "GERMAN": "Alemana", + "TURKISH": "Turkiera", + "SLOVAK": "Eslovakiera", + "SERBIAN": "Serbiera", + "PORTUGUESE": "Portugesa", + "CROATIAN": "Kroaziera", + "POLISH": "Poloniera", + "BASQUE": "Basque" + } + }, + "COOKIE": { + "MESSAGE": "Webgune honek cookieak erabiltzen ditu erabiltzaile esperientzia hobetzeko.", + "DISMISS": "Onartu", + "DENY": "Cookieak errefusatu", + "LINK": "Gehiago jakin", + "POLICY": "Cookie-politika" + }, + "EMAIL-CONFIRMATION": { + "EXPIRED-EMAIL": "E-mail gonbidapena iraungia", + "CARD-TITLE": "E-maila", + "REQUEST-EMAIL-HEADER": "Ia amaitu dugu! Idatzi zure e-maila.", + "REQUEST-EMAIL-TEXT": "E-maila berretsi egin beharko duzu aplikazioa erabiltzeko.", + "SUBMIT": "Bidali", + "SENT-EMAIL-HEADER": "E-mail bat bidali zaizu! Mesedez, begiratu zure sarrera-ontzia.", + "EMAIL-FOUND": "E-maila baieztatuta dago" + }, + "HOME": { + "DMPS": "DKPak", + "DATASETS": "Datu-multzoak", + "LOGIN": { + "TITLE": "Hasi saioa", + "TEXT": "Ez duzu zertan erregistratutako kontu bat izan behar honetarako {{ APP_NAME_CAPS }}" + } + }, + "NAV-BAR": { + "BREADCRUMB-ROOT": "Aginte-panela", + "TITLE": "{{ APP_NAME_CAPS }}", + "GRANTS": "Diru-laguntzak", + "GRANT": "Diru-laguntza", + "DMP": "DKPa", + "DMPS": "DKPak", + "MY-DMPS": "NIRE DKPak", + "DATASETS": "Datu-multzoak", + "DATASET": "Datu-multzoa", + "PUBLIC-DATASETS": "Esploratu {{ APP_NAME_CAPS }}", + "USERS": "Erabiltzaileak", + "DATASETS-ADMIN": "Datu-multzoen Txantiloiak", + "DMP-PROFILES": "DKPen Txantiloiak", + "ABOUT": "Honi buruz", + "MY-DATASET-DESCRIPTIONS": "NIRE DATU-MULTZOAK", + "DATASET-DESCRIPTION-WIZARD": "Datu-multzoen Laguntzailea", + "PUBLIC DATASETS": "ARGITARATUTAKO DATU-MULTZOAK", + "PUBLIC-DMPS": "ARGITARATUTAKO DKPak", + "HOME": "HASIERAKO ORRIA", + "DMP-WIZARD": "DKP Laguntzailea", + "DATASET-TEMPLATES": "DATU-MULTZOEN TXANTILOIAK", + "TEMPLATE": "TXANTILOIA", + "DMP-TEMPLATES": "DKP TXANTILOIAK", + "USERS-BREADCRUMB": "ERABILTZAILEAK", + "START-NEW-DMP": "Hasi DKP berria", + "START-NEW-DMP-TXT": "Hutsetik hasi edo honekin lanean jarraitu {{ APP_NAME }}! Sortu DKP berri bat edo kargatu existitzen den DKP bat hona {{ APP_NAME }}", + "START-WIZARD": "Hasi laguntzailea", + "IMPORT-FROM-FILE": "Inportatu fitxategi batetatik", + "SEARCH": { + "DATASET": "Datu-multzoa", + "DMP": "DKPa", + "GRANT": "Diru-laguntza", + "PUBLISHED": "Argitaratuta" + } + }, + "SIDE-BAR": { + "GENERAL": "OROKORRA", + "ABOUT": "Honi buruz", + "DASHBOARD": "Aginte-panela", + "DMP": "DATUAK KUDEATZEKO PLANAK", + "MY-DMPS": "Nire DPKak", + "DATASETS": "DATU-MULTZOAK", + "GRANTS": "DIRU-LAGUNTZAK", + "NEW DATASET": "Datu-multzo berria", + "QUICK-WIZARD": "DKP berria (Laguntzailea)", + "QUICK-WIZARD-DATASET": "Gehitu Datu-multzoa (Laguntzailea)", + "ADD-EXPERT": "DKP berria (Aditua)", + "MY-DATASET-DESC": "Nire Datu-multzoak Desk.", + "MY-DATASETS": "Nire Datu-multzoak", + "MY-GRANTS": "Nire Diru-laguntzak", + "HISTORY": "HISTORIA", + "HISTORY-VISITED": "AZKEN BISITA", + "HISTORY-EDITED": "EDITATUTAKO AZKENA", + "PUBLIC": "ARGITARATUTA", + "PUBLIC-DMPS": "DKP Publikoak", + "PUBLIC-DESC": "Datu-multzo Publikoak Desk.", + "ACCOUNT": "KONTUA", + "ADMIN": "ADMIN", + "DATASET-TEMPLATES": "Datu-multzoen Txantiloiak", + "DMP-TEMPLATES": "DKP Txantiloiak", + "USERS": "Erabiltzaileak", + "LANGUAGE-EDITOR": "Hizkuntza editorea", + "GUIDE-EDITOR": "Erabiltzaile Gida Editorea", + "CO-BRANDING": "Marka partekatua", + "SUPPORT": "Laguntza", + "FEEDBACK": "Bidali feedback-a" + }, + "DATASET-PROFILE-EDITOR": { + "TITLE": { + "NEW": "API Bezero Berria", + "NEW-PROFILE": "Datu-multzoen Txantiloi Berria", + "NEW-PROFILE-VERSION": " -ren Bertsio Berria", + "NEW-PROFILE-CLONE": " -ren Klon Berria" + }, + "FIELDS": { + "DATASET-TITLE": "Datu-multzoaren Txantiloiaren Izena", + "DATASET-DESCRIPTION": "Deskribapena", + "ROLES": "Funtzioak" + }, + "STEPS": { + "GENERAL-INFO": { + "TITLE": "Informazio Orokorra", + "DATASET-TEMPLATE-NAME": "Datu-multzoaren txantiloiaren izena", + "DATASET-TEMPLATE-NAME-HINT": "Datu-multzoaren txantiloia zehazten duen izenburua.", + "DATASET-TEMPLATE-DESCRIPTION": "Deskribapena", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "Datu-multzoaren deskribapen laburra, aplikazio-eremua eta helburuak.", + "DATASET-TEMPLATE-LANGUAGE": "Datu-multzoaren txantiloiaren hizkuntza", + "DATASET-TEMPLATE-SELECT-LANGUAGE": "Aukeratu hizkuntza", + "DATASET-TEMPLATE-USERS": "Editoreak", + "DATASET-TEMPLATE-USERS-HINT": "Gehitu editoreak eta gorde aldaketak, hauei jakinarazteko.", + "DATASET-TEMPLATE-REMOVE-USER": "Kendu Editorea", + "DATASET-TEMPLATE-NO-USERS-YET": "... Ez dago editorerik oraindik", + "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Baliozkotu eta Gehitu Editorea", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Datu-multzoaren txantiloiaren deskribapena", + "UNTITLED": "Izenbururik gabea", + "QUESTION": "Galdera", + "TEMPLATE-OUTLINE": "Txantiloiaren eskema", + "ERRORS": { + "USER-NOT-FOUND": "Erabiltzailea ez da aurkitu." + } + }, + "PAGE-INFO": { + "PAGE-NAME": "Kapituluaren Izena", + "PAGE-NAME-HINT": "Datu-multzoaren kapituluari izen bat jarri.", + "PAGE-DESCRIPTION": "Deskribapena", + "PAGE-DESCRIPTION-HINT": "Idatzi kapituluari buruzko deskribapen laburra.", + "ACTIONS": { + "CREATE-FIRST-PAGE": "Sortu lehenengo kapitulua", + "CREATE-NEW-SUBSECTION": "Atala", + "CREATE-NEW-SECTION": "Kapitulua", + "CREATE-FIRST-SECTION": "Sortu lehenengo atala", + "NOTHING-HERE-HINT": "Ez dago oraindik ezer.", + "START-CREATING-PAGE-START": "Hasi hemendik ", + "START-CREATING-PAGE-END": "lehenengo kapitulua sortzen.", + "CREATE-SECTION": "Sortu atala" + }, + "PAGE": "Kapitulua" + }, + "SECTION-INFO": { + "SECTION-NAME": "Atalaren izena", + "SECTION-NAME-HINT": "Atalari izen bat jarri.", + "SECTION-DESCRIPTION": "Deskribapena", + "SECTION-DESCRIPTION-HINT": "Idatzi atalari buruzko deskribapen laburra.", + "SECTION": "Atala" + }, + "PAGES": { + "TITLE": "Kapituluaren Deskribapena", + "PAGE-PREFIX": "Kapitulua", + "PAGE-INPUT-TITLE": "Kapituluaren Izenburua", + "DATASET-DETAILS": "Datu-multzoaren zehaztapenak", + "EXTERNAL-REFERENCES": "Kanpo-erreferentziak", + "DESCRIPTION": "Deskribapena" + }, + "FORM": { + "TITLE": "Formularioaren Deskribapena", + "SECTION": { + "TITLE": "Atalaren Informazioa", + "FIELDS": { + "ID": "Atalaren identifikatzailea", + "TITLE": "Atalaren Izena", + "PAGE": "Agertuko den orrialdea", + "ORDER": "Ordena", + "DESCRIPTION": "Deskribapena", + "FIELDS-TITLE": "Eremuak", + "SUB-SECTIONS-TITLE": "Azpiatalak" + }, + "ACTIONS": { + "ADD-SUB-SECTION": "Gehitu Azpiatala +", + "ADD-FIELD": "Gehitu Eremua +" + } + }, + "COMPOSITE-FIELD": { + "TITLE": "Eremu Konposatuaren Informazioa", + "SIMPLE-FIELD-TITLE": "Eremuaren Informazioa", + "SUB-FIELDS-TITLE": "Bigarren mailako eremuak", + "FIELDS": { + "COMPOSITE-CHECKBOX": "Eremu Konposatua", + "MULTIPLICITY-CHECKBOX": "Anizkoiztasuna", + "COMMENT-CHECKBOX": "Iruzkinen Eremua Gehitu", + "COMPOSITE-TITLE": "Konposatutako Eremuaren Izena", + "FIELD-TITLE": "Eremuaren Izena", + "DESCRIPTION": "Deskribapena", + "EXTENDED-DESCRIPTION": "Deskribapen Zabalagoa", + "ADDITIONAL-INFORMATION": "Informazio Gehigarria", + "MULTIPLICITY-MIN": "Gutxieneko Anizkoiztasuna", + "MULTIPLICITY-MAX": "Gehienezko Anizkoiztasuna", + "MULTIPLICITY-PLACEHOLDER": "Anizkoiztasunaren Markagailuaren Testua", + "MULTIPLICITY-TABLEVIEW": "Sarrerak taulan ikusi", + "MULTIPLICITY-ADD-ONE-FIELD": "Gehitu gehiago", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Gehitu errenkada", + "ORDER": "Eskatu", + "COMMENT-PLACEHOLDER": "Mesedez Zehaztu", + "COMMENT-HINT": "Eman informazio gehigarria edo justifikatu zure hautaketa", + "SEMANTICS": "Semantika", + "EXPORT": "Esportazioan gehitu" + }, + "ACTIONS": { + "ADD-CHILD-FIELD": "Gehitu azpieremua +" + } + }, + "FIELD": { + "FIELDS": { + "RULES-TITLE": "Baldintzazko Galderak", + "FIELD-RULES-VALUE": "Balioa", + "ID": "Atalaren identifikatzailea", + "VIEW-STYLE": "Mota", + "MULTIPLICITY-MIN": "Gutxieneko Anizkoiztasuna", + "MULTIPLICITY-MAX": "Gehienezko Anizkoiztasuna", + "ORDER": "Eskatu", + "DEFAULT-VALUE": "Balio Lehentsia", + "VALIDATION": "Baliozkotzea", + "MULTIPLICITY-CHECKBOX": "Anizkoiztasuna", + "FIELD-TEXT-AREA-TITLE": "Testu-eremuko Datuak", + "FIELD-TEXT-AREA-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-RICH-TEXT-AREA-TITLE": "Testu-eremu aberastuaren Datuak", + "FIELD-RICH-TEXT-AREA-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-UPLOAD-TITLE": "Kargatu", + "FIELD-UPLOAD-PLACEHOLDER": "Kargatu Markagailuaren Testua", + "FIELD-UPLOAD-MAX-FILE-SIZE": "Gehienezko Fitxategiaren Neurria ({{maxfilesize}} Megabyte arte)", + "FIELD-UPLOAD-CUSTOM-FILETYPE": "Beste fitxategi mota batzuk", + "FIELD-UPLOAD-SELECT-FILETYPE": "Fitxategi motak aukeratu", + "FIELD-UPLOAD-LABEL": "euskarri motaren izena", + "FIELD-UPLOAD-VALUE": "euskarri motaren balioa", + "FIELD-BOOLEAN-DECISION-TITLE": "Erabaki-datu boolearrak", + "FIELD-BOOLEAN-DECISION-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-CHECKBOX-TITLE": "Datuen Kutxa", + "FIELD-CHECKBOX-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-FREE-TEXT-TITLE": "Testu Libreko Datuak", + "FIELD-FREE-TEXT-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-COMBO-BOX-TYPE": "Kutxa Konbinatu Mota", + "FIELD-WORD-LIST-TITLE": "Hitzen Zerrendako Datuak", + "FIELD-WORD-LIST-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-WORD-LIST-LABEL": "Etiketa", + "FIELD-WORD-LIST-VALUE": "Balioa", + "FIELD-INTERNAL-DMP-ENTITIES-TYPE": "Barne DKP entitate mota", + "FIELD-RESEARCHERS-TITLE": "Ikertzaileek Osatu", + "FIELD-RESEARCHERS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-DATASETS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-DMPS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-RADIO-BOX-TITLE": "Radio Box Data", + "FIELD-RADIO-BOX-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-RADIO-BOX-LABEL": "Etiketa", + "FIELD-RADIO-BOX-VALUE": "Balioa", + "FIELD-AUTOCOMPLETE-TITLE": "Datuak autoosatu", + "FIELD-AUTOCOMPLETE-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-AUTOCOMPLETE-SOURCE-TITLE": "Iturriak", + "FIELD-AUTOCOMPLETE-ADD_SOURCE": "Gehitu Iturria", + "FIELD-AUTOCOMPLETE-TYPE": "Iturri Mota", + "FIELD-AUTOCOMPLETE-TYPE-UNCACHED": "Katxerik gabe", + "FIELD-AUTOCOMPLETE-TYPE-CACHED": "Katxearekin", + "FIELD-AUTOCOMPLETE-LABEL": "Etiketa", + "FIELD-AUTOCOMPLETE-VALUE": "Balioa", + "FIELD-AUTOCOMPLETE-SOURCE": "Iturria", + "FIELD-AUTOCOMPLETE-URL": "URLa", + "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Erroaren Aukerak", + "FIELD-DATE-PICKER-TITLE": "Data hautatzailea", + "FIELD-DATE-PICKER-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-DATE-PICKER-LABEL": "Etiketa", + "FIELD-DATE-PICKER-VALUE": "Balioa", + "FIELD-MULTIPLE-AUTOCOMPLETE": "Autoosatze anitza", + "FIELD-MULTIPLE-WORDLIST": "Aukeraketa anitza", + "FIELD-CURRENCY-TITLE": "Datu monetarioak", + "FIELD-CURRENCY-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-REGISTRIES-TITLE": "Metadatuak", + "FIELD-REGISTRIES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-SERVICES-TITLE": "Zerbitzuen Datuak", + "FIELD-SERVICES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-ORGANIZATIONS-TITLE": "Erakundeen Datuak", + "FIELD-ORGANIZATIONS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-EXTERNAL-DATASETS-TITLE": "Kanpo Datu-multzoen Datuak", + "FIELD-EXTERNAL-DATASETS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-DATA-REPOSITORIES-TITLE": "Datu-gordailuen Datuak", + "FIELD-DATA-REPOSITORIES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-PUB-REPOSITORIES-TITLE": "Argitalpenen gordailuak", + "FIELD-PUB-REPOSITORIES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-JOURNALS-REPOSITORIES-TITLE": "Aldikzariak", + "FIELD-JOURNALS-REPOSITORIES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-TAXONOMIES-TITLE": "Taxonomien Datuak", + "FIELD-TAXONOMIES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-LICENSES-TITLE": "Lizentzien Datuak", + "FIELD-LICENSES-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-PUBLICATIONS-TITLE": "Argitalpenen Datuak", + "FIELD-PUBLICATIONS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-TAGS-TITLE": "Etiketen Datuak", + "FIELD-TAGS-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-DATASET-IDENTIFIER-TITLE": "Datu-multzoen Identifikazio Datuak", + "FIELD-DATASET-IDENTIFIER-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "FIELD-VALIDATOR-TITLE": "Balidatzailearen Datuak", + "FIELD-VALIDATOR-PLACEHOLDER": "Sarrera Markagailuaren Testua", + "EXTERNAL-DATASET-TYPE-NAME": "Mota", + "EXTERNAL-DATASET-TYPES": { + "PRODUCED": "Ekoiztutako datu-multzoa", + "REUSED": "Berrerabilitako datu-multzoa", + "OTHER": "Bestelakoak" + } + }, + "ERROR-MESSAGES": { + "FIELD-OTHER-SOURCES-REQUIRED": "Gutxienez iturri bat eman behar da.", + "FIELD-RADIO-AT-LEAST-ONE-REQUIRED": "Gutxienez aukera bat eman behar da.", + "FIELD-SELECT-AT-LEAST-ONE-REQUIRED": "Gutxienez aukera bat eman behar da." + }, + "DEFAULT-VALUES": { + "NONE": "Bat ere ez", + "BOOLEAN-DECISION": { + "YES": "Bai", + "NO": "Ez" + }, + "CHECK-BOX": { + "CHECKED": "Egiaztatuta", + "UNCHECKED": "Egiaztatu gabe" + } + }, + "ACTIONS": { + "ADD-RULE": "Gehitu Ikusgarritasun Araua +" + }, + "STATUS": { + "CALCULATING-PREVIEW": "... aurrebista kalkulatzen", + "PREVIEW-UPDATED": "Aurrebista eguneratua!" + } + }, + "RULE": { + "FIELDS": { + "RULE-TYPE": "Arau Mota", + "TARGET": "Helburu eremuaren Id", + "VALUE": "Derrigorrezko balioa", + "RULE-IF": "Balioa hauxe bada", + "RULE-THEN": "jarraian Galdera erakutsi", + "FIELDSETS": "Galderak", + "FIELDS": "Sarrerak" + }, + "HINTS": { + "ELEMENT-CHILD-OF-TARGET": "Elementu hau hautatutako sarreraren jatorria da.", + "ELEMENT-HIDDEN-FROM-ELEMENT": "Elementu honek ezkutatu egiten du ikusgaitasun-araua aplikatu nahi zaion sarrerako elementu edo jatorrizko elementu bat." + } + }, + "FORM-VALIDATION": { + "ERROR-MESSAGES": { + "PAGE-MUST-HAVE-SECTION": "Kapitulu bakoitzak gutxienez atal bat izan behar du.", + "NEEDS-MORE-INFORMATION": " informazio gehiago behar da.", + "MUST-HAVE-SECTION-OR-FIELDSET": " atala edo galdera izan behar du.", + "MISSING": "Faltan", + "PROVIDE-PAGE-AND-SECTION": "Ziurtatu kapitulu bat eta gutxienez kapitulu bakoitzeko atal bat daudela." + } + }, + "TABLE-OF-CONTENTS": { + "ERROR-MESSAGES": { + "FIELDSET-MUST-HAVE-PARENT-SECTION": "Galdera atal baten pean baino ezin da egon.", + "INPUT-SECTION-SAME-LEVEL": "Ezin da maila berean galdera eta atalik egon.", + "DRAG-NOT-SUPPORTED": "Ezin da atala arrastatu eta askatu helmugako edukiontzian.", + "PAGE-ELEMENT-ONLY-TOP-LEVEL": "Kapituluko elementuak goiko mailan baino ezin dira egon" + } + } + }, + "TOOLKIT": { + "GENERAL-TOOLS": "Galdera erremintak", + "NEW-INPUT-SET": "Gehitu Galdera", + "CLONE": "Klonatu", + "DELETE": "Ezabatu" + } + }, + "ACTIONS": { + "SAVE": "Gorde", + "SAVE-AND-CONTINUE": "Gorde eta Jarraitu", + "SAVE-AND-CLOSE": "Gorde eta Itxi", + "FINALIZE": "Amaitu", + "UPDATE": "Eguneratu", + "UPDATE-AND-CONTINUE": "Eguneratu eta Jarraitu", + "UPDATE-AND-CLOSE": "Eguneratu eta Itxi", + "CANCEL": "Ezeztatu", + "DELETE": "Ezabatu", + "ADD-PAGE": "Gehitu Orrialdea +", + "ADD-SECTION": "Gehitu Atala +", + "VALIDATE": "Baliozkotu", + "PREVIEW-AND-FINALIZE": "Aurreikusi eta Amaitu", + "BACK-TO-TOP": "Gora itzuli", + "FIELD": { + "MAKE-IT-REQUIRED": "Beharrezko datuak sartu", + "ADD-VISIBILITY-RULE": "Baldintzazko galdera egin", + "DELETE-INPUT": "Sarrera hau ezabatu", + "PREVIEW": "Aurreikusi", + "NOT-INITIALIZED": "Oraindik hasi gabea", + "MOVE-UP": "Mugitu sarrera hau gora", + "MOVE-DOWN": "Mugitu sarrera hau behera" + }, + "FIELDSET": { + "ADD-INPUT": "Gehitu sarrera", + "COMMENT-FIELD": "Iruzkinen eremua", + "INCLUDE-COMMENT-FIELD": "Emandako galderari iruzkin-eremu bat gehitu zaio.", + "ENABLE-MULTIPLICITY": "Erabiltzaileak erantzun bat baino gehiago eman diezaioke egindako galderari.", + "MULTIPLICITY": "Anizkoiztasuna", + "MORE": "Gehiago.." + } + }, + "FEEDBACK-MESSAGES": { + "SAVE-SUCCESS": "Aldaketak modu egokian gorde dira." + }, + "ERRORS": { + "INVALID-VISIBILITY-RULES": { + "MESSAGE-START": "Baliozkoak ez diren ikusgaitasun-arauak hauteman dira hemen ", + "MESSAGE-END": ". Konpondu nahi dituzu?", + "CONFIRM-YES": "Bai, ezabatu arau baliogabeak", + "CONFIRM-NO": "Ez, mantendu itzazu.", + "REMOVE-SUCCESS": "Baliogabeak diren ikusgaitasun-arauak modu egokian ezabatu dira." + } + } + }, + "GRANT-LISTING": { + "TITLE": "Diru-laguntzak", + "SUBTITLE": "Diru-laguntzaren azpititulua", + "ACTIONS": { + "NEW": "Diru-laguntza Berria" + } + }, + "DMP-LISTING": { + "DMP": "DKP", + "GRANT": "Diru-laguntza", + "TITLE": "Datuen Kudeaketarako Planak", + "OWNER": "Jabea", + "MEMBER": "Kidea", + "CREATOR": "Sortzailea", + "EDITED": "Editatuta", + "FINALIZED": "Amaituta", + "PUBLISHED": "Argitaratuta", + "VERSION": "Bertsioa", + "CONTAINED-DATASETS": "Bildutako datu-multzoak", + "TEXT-INFO": "DKP batek erakusten du nola bildu edota sortu diren datu-multzoak, nola prozesatu eta aztertu diren, hau da, zer tresna, arau, metodologia eta abarrekin, baina baita datu-multzoen segurtasun-kopiak non eta nola egiten diren ere, non argitaratu eta gordetzen diren, datuen kontserbazio eta administrazio lanetan aritzen den pertsonalari lotutako kostuak edo datuak kudeatzeko zerbitzuak eskuratu edo sortzeko kostuak barne.", + "TEXT-INFO-QUESTION": "Ez zaude ziur nolakoa den DKP bat praktikan? Arakatu publikoak diren DKPak eta", + "LINK-ZENODO": "LIBER komunitatea Zenodon", + "GET-IDEA": "ideia bat izateko!", + "SORT-BY": "Honela ordenatu", + "COLUMNS": { + "NAME": "Izena", + "GRANT": "Diru-laguntza", + "PROFILE": "Txantiloia", + "CREATION-TIME": "Sorrera ordua", + "ORGANISATIONS": "Erakundeak", + "LATEST_VERSION": "Azken bertsioa", + "ACTIONS": "Ekintzak", + "DATASETS": "Datu-multzoak", + "STATUS": "Egoera", + "PEOPLE": "Pertsonak", + "VERSION": "Bertsioa" + }, + "ACTIONS": { + "NEW": "DKP Berria", + "NEW-WITH-WIZARD": "DKP Berria Laguntzailea erabilita", + "EDIT": "Editatu", + "INVITE": "Kolaboratzaileak gonbidatu", + "INVITE-AUTHORS": "Egileak gonbidatu", + "INVITE-SHORT": "Gonbidatu", + "ADD-DATASET": "Gehitu Datu-multzoa DKPra", + "ADD-DATASET-DESCRIPTION": "Gehitu datu-multzoa", + "ADD-DATASET-SHORT": "Gehitu Datu-multzoa", + "DATASETS": "Zerrendatu DKPeko datu-multzo guztiak", + "NEW-VERSION": "Bertsio Berria", + "START-NEW-VERSION": "Hasi Bertsio Berria", + "VIEW-VERSION": "DKP Bertsio Guztiak", + "CLONE": "Klonatu", + "COPY": "Kopiatu", + "DELETE": "Ezabatu", + "DEPOSIT": "Gordailutu", + "EXPORT": "Esportatu", + "MAKE-PUBLIC": "Publiko egin", + "PUBLISH": "Argitaratu", + "FINALIZE": "Amaitu", + "UNFINALIZE": "Desegin Amaiera", + "ADV-EXP": "Esportazio Aurreratua", + "EXP-AS": "Esportatu honela", + "DOWNLOAD-XML": "XMLa Deskargatu", + "DOWNLOAD-DOCX": "Dokumentua Deskargatu", + "DOWNLOAD-PDF": "PDFa Deskargatu", + "SETTINGS": "Ezarpenak", + "GETDOI": "DOIa Lortu" + }, + "TOOLTIP": { + "DMP-STATUS": { + "DRAFT": "Sarbide pribatua - DKP Editagarria", + "FINALIZED": "Sarbide pribatua - DKP Itxia", + "PUBLISHED": "Sarbide publikoa - DKP Itxia" + }, + "LEVEL-OF-ACCESS": "Sarbide-maila", + "INVOLVED-DATASETS": "Inplikatutako Datu-multzoak", + "TEMPLATES-INVOLVED": "Inplikatutako Datu-multzoen Txantiloiak" + }, + "VIEW-ALL-VERSIONS": "Honen bertsio guztiak", + "EMPTY-LIST": "Hutsik dago oraindik." + }, + "DMP-PUBLIC-LISTING": { + "TITLE": "Argitaratutako Datuen Kudeaketarako Planak", + "OWNER": "Jabea", + "MEMBER": "Kidea", + "CREATOR": "Sortzailea", + "VIEW-ONLY": "Ikusi Bakarrik", + "TOOLTIP": { + "PUBLISHED": "Sarbide publikoa - DKP Itxia", + "INVOLVED-DATASETS": "Inplikatutako Datu-multzoak", + "TEMPLATES-INVOLVED": "Inplikatutako Datu-multzoen Txantiloiak" + }, + "EMPTY-LIST": "Hustik dago oraindik." + }, + "DMP-UPLOAD": { + "TITLE": "Inportatu Datuak Kudeatzeko Plana", + "UPLOAD-BUTTON": "Kargatu", + "UPLOAD-SUCCESS": "Inpotazioa ondo burutu da", + "ACTIONS": { + "IMPORT": "Inportatu", + "CANCEL": "Ezeztatu" + }, + "PLACEHOLDER": "DKPren izenburua" + }, + "DATASET-WIZARD": { + "TITLE": { + "NEW": "Datu-multzo Berria" + }, + "EDITOR": { + "FIELDS": { + "EXTERNAL-DATASET-TYPE": "Mota", + "EXTERNAL-AUTOCOMPLETE-SUBTITLE": "Iturria: ", + "EXTERNAL-AUTOCOMPLETE-NO-SOURCE": "Iturria ez da eman" + } + }, + "FIRST-STEP": { + "TITLE": "Datu-multzoaren Informazioa", + "DMP": "Datuen Kudeaketa Plana", + "PROFILE": "Datu-multzoen Txantiloia", + "SUB-TITLE": "Hemen sortua: " + }, + "SECOND-STEP": { + "TITLE": "Kanpo-erreferentziak", + "EXTERNAL-HINT": "Kanpo iturrietatik hornitutako balioen zerrenda" + }, + "THIRD-STEP": { + "TITLE": "Deskribapena" + }, + "ACTIONS": { + "NEXT": "Hurrengoa", + "BACK": "Atzera", + "CLOSE": "Itxi", + "BACK-TO": "Bueltatu", + "DELETE": "Ezabatu", + "GO-TO-GRANT": "Datu-multzoaren diru-laguntzara joan", + "GO-TO-DMP": "Datu-multzoaren DKPera joan", + "SAVE": "Gorde", + "SAVE-AND-CONTINUE": "Gorde eta Jarraitu", + "SAVE-AND-ADD": "Gorde eta Berria Gehitu", + "SAVE-AND-CLOSE": "Gorde eta Itxi", + "SAVE-AND-FINALISE": "Gorde eta Amaitu", + "FINALIZE": "Amaitu", + "REVERSE": "Amaiera Desegin", + "INFO": "Amaitutako DKPen Datu-multzoak ezin dira bukatu gabekoetara itzuli", + "LOCK": "Beste erabiltzaile batek blokeatutako datu-multzoa", + "DOWNLOAD-PDF": "PDFa Deskargatu", + "DOWNLOAD-XML": "XMLa deskargatu", + "DOWNLOAD-DOCX": "DOCX Deskargatu", + "COPY-DATASET": "Datu-multzoa Kopiatu", + "UPDATE-DATASET-PROFILE": "Txantiloia Eguneratu", + "VALIDATE": "Baliozkotu", + "UNDO-FINALIZATION-QUESTION": "Amaiera desegin?", + "CONFIRM": "Bai", + "REJECT": "Ez" + }, + "MESSAGES": { + "DATASET-NOT-FOUND": "Datu-multzoa ez da existitzen", + "DATASET-NOT-ALLOWED": "Ez daukazu datu-multzo honetara sarbiderik", + "SUCCESS-UPDATE-DATASET-PROFILE": "Datu-multzoaren Txantiloia behar bezala eguneratu da", + "MISSING-FIELDS": "Bete gabeko derrigorrezko eremu batzuk daude. Mesedez, DKPa berrikusi eta ziurtatu derrigorrezko galdera guztiak erantzun direla eta URLak baliodun sarrera batekin eman direla. (Falta diren eremuak gorriz markatuta daude)", + "NO-FILES-SELECTED": "Ez dago kargatzeko fitxategirik aukeratuta", + "LARGE-FILE-OR-UNACCEPTED-TYPE": "Fitxategi hau handiegia da edo ez da bateragarria.", + "MAX-FILE-SIZE": "Igotako fitxategiek {{maxfilesize}} MB izan behar dute gehienez.", + "ACCEPTED-FILE-TYPES": "Onartutako euskarri motak hauek dira: " + }, + "UPLOAD": { + "UPLOAD-XML": "Inportatu", + "UPLOAD-XML-FILE-TITLE": "Inportatu Datu-multzoen Txantiloia", + "UPLOAD-XML-NAME": "Datu-multzoaren Txantiloiaren Izena", + "UPLOAD-XML-IMPORT": "Fitxategia", + "UPLOAD-XML-FILE-CANCEL": "Ezeztatu" + }, + "NEW-VERSION-FROM-FILE": { + "NEW-VERSION-XML": "Inportatu", + "NEW-VERSION-XML-FILE-TITLE": "Fitxategiaren Bertsio Berria honetarako {{datasetName}}", + "NEW-VERSION-XML-FILE-CANCEL": "Ezeztatu", + "NEW-VERSION-XML-SUCCESSFUL": "Bertsio berria modu egokian kargatu da" + }, + "DIALOGUE": { + "TITLE": "Kopiatu Datu-multzoa DKP honetan", + "DMP-SEARCH": { + "PLACEHOLDER": "DKPa Bilatu" + }, + "COPY": "Kopiatu", + "CANCEL": "Ezeztatu", + "NEXT": "Hurrengoa", + "ERROR-MESSAGE": "Ez dauka datu-multzoen Txantiloi hau" + }, + "LOCKED": { + "TITLE": "Datu-multzoa blokeatuta dago", + "MESSAGE": "Beste norbait datu-multzoa aldatzen ari da momentu honetan. Datu-multzoa ikus dezakezu baina ezin duzu aldaketarik egin. Aldaketak egiteko, beranduago saiatu." + } + }, + "DMP-OVERVIEW": { + "GRANT": "Diru-laguntza", + "DMP-AUTHORS": "DKParen Egileak", + "RESEARCHERS": "Ikertzaileak", + "DATASETS-USED": "Erabilitako datu-multzoa", + "COLLABORATORS": "Kolaboratzaileak", + "PUBLIC": "Publikoa", + "PRIVATE": "Pribatua", + "LOCKED": "Blokeatuta", + "UNLOCKED": "Desblokeatuta", + "YOU": "zu", + "LOCK": "Blokeoa", + "TOOLTIP": { + "LEVEL-OF-ACCESS": "Sarbide-maila", + "INVOLVED-DATASETS": "Inplikatutako Datu-multzoak", + "TEMPLATES-INVOLVED": "Inplikatutako Datu-multzoen Txantiloiak" + }, + "ERROR": { + "DELETED-DMP": "Eskatutako DKPa ezabatuta dago", + "FORBIDEN-DMP": "Ez daukazu DKP honetan sartzeko baimenik" + }, + "MULTIPLE-DIALOG": { + "ZENODO-LOGIN": "Zenodorekin sartu", + "USE-DEFAULT": "Erabili Token lehenetsia" + }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Zein kontu erabili nahi duzu?", + "LOGIN": "Sartu honekin {{repository}}", + "NO-REPOSITORIES": "Ez dago argitaratzeko biltegirik", + "SELECT-REPOSITORIES": "Aukeratu depositurako biltegia", + "AUTHORIZE": "Baimena eman", + "CANCEL": "Ezeztatu" + }, + "LOCKED-DIALOG": { + "TITLE": "DKPa blokeatuta dago", + "MESSAGE": "Beste norbait DKPa aldatzen ari da momentu honetan. Aldatu edo ikusteko, beranduago saiatu." + } + }, + "DATASET-OVERVIEW": { + "DATASET-AUTHORS": "Datu-multzoaren egileak", + "ERROR": { + "DELETED-DATASET": "Eskatutako datu-multzoa ezabatuta dago", + "FORBIDEN-DATASET": "Ez daukazu datu-multzo honetara sartzeko baimenik" + }, + "LOCKED": { + "TITLE": "Datu-multzoa blokeatuta dago", + "MESSAGE": "Beste norbait datu-multzoa aldatzen ari da momentu honetan. Aldatu edo ikusteko, beranduago saiatu." + }, + "FINALISE-POPUP": { + "MESSAGE": "Datu-multzoen Editorera bideratua izango zara non aukeratutako datu-multzoarekin amaitzeko aukera izango duzun. Jarraitu nahi duzu?", + "CONFIRM": "Ados", + "CANCEL": "Ezeztatu" + } + }, + "DATASET-LISTING": { + "TITLE": "Datu-multzoak", + "DATASET-DESCRIPTION": "Datu-multzoa", + "SELECT-DATASETS-TO-CLONE": "Aukeratu zein datu-multzo sartu nahi dituzun DKP berrian. Aukeratutako datu-multzoak editagarriak izango dira.", + "SELECT-DATASETS-NONE": "Ez dago Datu-multzorik erabilgarri DKP honetarako.", + "TEXT-INFO": "Datu-multzoak aldez aurretik definitutako txantiloiak jarraituta dokumentatzen dira, txantiloi horiek datu-multzoen deskribapenen edukia ezartzen dute. Hemen {{ APP_NAME }}, DKP batek dokumentatutako datu-multzoen deskribapen adina izan ditzake. Nabigatu ", + "TEXT-INFO-REST": " {{ APP_NAME }} DKPetan deskribatutako datu-multzoei begiratu bat emateko", + "LINK-PUBLIC-DATASETS": "Datu-multzo Publikoak", + "TEXT-INFO-PAR": "Datu-multzo berriak existitzen diren DKPetara gehitu daitezke edozein momentutan eta txantiloi bat baino gehiagorekin deskribatu daitezke. Datu-multzoak klonatu ere egin daitezke eta beste DKP batzuetan berrerabili, baita ezabatu ere DKPanari bere osotasunean kalte egin gabe.", + "COLUMNS": { + "NAME": "Izena", + "REFERNCE": "Erreferentzia", + "GRANT": "Diru-laguntza", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)", + "STATUS": "Egoera", + "DESCRIPTION": "Deskribapena", + "CREATED": "Sortuta", + "PUBLISHED": "Argitaratuta", + "FINALIZED": "Amaituta", + "LAST-EDITED": "Azkenengoz editatuta", + "ACTIONS": "Ekintzak", + "DMP": "DKPa", + "PROFILE": "Txantiloia", + "DATAREPOSITORIES": "Datuen Biltegiak", + "REGISTRIES": "Erregistroak", + "SERVICES": "Zerbitzuak" + }, + "ACTIONS": { + "EDIT": "Editatu", + "MAKE-IT-PUBLIC": "Publiko egin", + "VIEW": "Ikusi", + "NEW": "Datu-multzo Berria", + "CREATE-NEW": "Datu-multzo berria sortu", + "EXPORT": "Esportatu", + "INVITE-COLLABORATORS": "Kolaboratzaileak gonbidatu", + "INVITE-SHORT": "Gonbidatu" + }, + "STATES": { + "EDITED": "Editatuta", + "PUBLIC": "Publikoa", + "FINALIZED": "Amaituta", + "PUBLISHED": "Argitaratuta" + }, + "TOOLTIP": { + "DATASET-STATUS": { + "DRAFT": "Sarbide pribatua - Datu-multzo editagarria", + "FINALIZED": "Sarbide pribatua - Datu-multzo Itxia" + }, + "DMP": "DKPa", + "GRANT": "Diru-laguntza", + "TEMPLATES-INVOLVED": "Datu-multzoaren Txantiloia", + "VERSION": "DKP Bertsioa", + "PART-OF": "Honen parte da", + "TO-DMP": "DKPra", + "DMP-FOR": "DKParentzat" + }, + "EMPTY-LIST": "Hutsik dago oraindik." + }, + "DATASET-PUBLIC-LISTING": { + "TITLE": "Argitaratutako Datu-multzoak", + "TOOLTIP": { + "FINALIZED": "Sarbide pribatua - Datu-multzo Itxia", + "DMP": "DKPa", + "GRANT": "Diru-laguntza", + "TEMPLATES-INVOLVED": "Datu-multzoaren Txantiloia" + }, + "EMPTY-LIST": "Hutsik dago oraindik." + }, + "DATASET-PROFILE-LISTING": { + "TITLE": "Datu-multzoen Txantiloiak", + "COLUMNS": { + "NAME": "Izena", + "REFERNCE": "Erreferentzia", + "GRANT": "Diru-laguntza", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)", + "ROLE": "Rola", + "TEMPLATE": "Txantiloia", + "ORGANIZATION": "Erakundea", + "STATUS": "Egoera", + "VISITED": "Bisitatua", + "EDITED": "Editatua", + "DESCRIPTION": "Deskribapena", + "CREATED": "Sortua", + "ACTIONS": "Ekintzak", + "DMP": "DKPa", + "PROFILE": "Txantiloia", + "DATAREPOSITORIES": "Datuen Biltegiak", + "REGISTRIES": "Erregistroak", + "SERVICES": "Zerbitzuak" + }, + "ACTIONS": { + "EDIT": "Editatu", + "MAKE-IT-PUBLIC": "Publiko egin", + "VIEW": "Ikusi", + "CLONE": "Klonatu", + "NEW-VERSION": "Bertsio Berria", + "NEW-VERSION-FROM-FILE": "Fitxategiaren Bertsio Berria", + "VIEW-VERSIONS": "Datu-multzoen Txantiloien Bertsio Guztiak", + "DELETE": "Ezabatu", + "CREATE-DATASET-TEMPLATE": "Sortu Datu-multzoen Txantiloia" + } + }, + "DATASET-UPLOAD": { + "TITLE": "Inportatu Datu-multzoa", + "UPLOAD-BUTTON": "Kargatu", + "ACTIONS": { + "IMPORT": "Inportatu", + "CANCEL": "Ezeztatu" + }, + "PLACEHOLDER": "Datu-multzoaren Izenburua", + "DATASET-PROFILE": { + "SELECT": "Aukeratu Datu-multzoaren Txantiloia" + }, + "SNACK-BAR": { + "SUCCESSFUL-CREATION": "Ondo inportatu da", + "UNSUCCESSFUL": "Zerbait gaizki joan da" + } + }, + "DMP-PROFILE-EDITOR": { + "TITLE": { + "NEW": "DKP Txantiloi Berria", + "EDIT": "Editatu" + }, + "FIELDS": { + "TITLE": "Eremuak", + "LABEL": "Izena", + "TYPE": "Mota", + "DATATYPE": "Datu Mota", + "REQUIRED": "Derrigorrezkoa", + "EXTERNAL-AUTOCOMPLETE": { + "TITLE": "Datu autoosatuak", + "MULTIPLE-AUTOCOMPLETE": "Autoosatze Anizkoitza", + "PLACEHOLDER": "Sarrera Markagailua", + "URL": "URLa", + "OPTIONS-ROOT": "Erro Aukerak", + "LABEL": "Etiketa", + "VALUE": "Balioa" + } + }, + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu", + "DELETE": "Ezabatu", + "FINALIZE": "Amaitu", + "DOWNLOAD-XML": "XMLa Deskargatu" + }, + "CONFIRM-DELETE-DIALOG": { + "MESSAGE": "DKP txantiloi hau ezabatu nahi duzu?", + "CONFIRM-BUTTON": "Bai, ezabatu", + "CANCEL-BUTTON": "Ez" + } + }, + "GRANT-EDITOR": { + "TITLE": { + "NEW": "Diru-laguntza Berria", + "EDIT": "Editatu" + }, + "FIELDS": { + "LABEL": "Izenburua", + "ABBREVIATION": "Laburdura", + "URI": "URLa", + "START": "Hasi", + "END": "Amaitu", + "DESCRIPTION": "Deskribapena", + "LOGO": "Diru-laguntzaren Logoa" + }, + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu", + "DELETE": "Ezabatu", + "GO-TO-DMPS": "DKPetara joan", + "VISIT-WEBSITE": "Webgunea bisitatu" + } + }, + "DMP-EDITOR": { + "TITLE": { + "NEW": "Datuen Kudeaketarako Plan Berria", + "EDIT": "Editatu", + "EDIT-DMP": "DKPa editatzen", + "ADD-DATASET": "Datu-multzoa gehitzen", + "EDIT-DATASET": "Datu-multzoa editatzen", + "CLONE-DMP": "Klonatu", + "NEW-VERSION": "Bertsio Berria", + "CREATE-DATASET": "Datu-multzoa sortzen", + "SUBTITLE": "Ondorengoak emandako DOIa", + "PREVIEW-DATASET": "Datu-multzoaren aurrebista" + }, + "FIELDS": { + "NAME": "DKParen Izenburua", + "RELATED-GRANT": "Erlazionatutako Diru-laguntza", + "DESCRIPTION": "Deskribapena", + "DESCRIPTION-HINT": "Deskribatu labur DKParen testuingurua eta helburua", + "ORGANISATIONS": "Erakundeak", + "ORGANISATIONS-HINT": "Gehitu hemen DKPak sortzen eta berrikusten laguntzen duten erakundeen izenak", + "RESEARCHERS": "Ikertzaileak", + "RESEARCHERS-HINT": "Gehitu hemen DKPan deskribatutako datuak ekoitzi, prozesatu eta aztertu dituzten pertsonen izenak.", + "AUTHORS": "Egileak", + "TEMPLATES": "Txantiloiak", + "TEMPLATE": "DKP Txantiloia", + "DATASET-TEMPLATES": "Erlazionatutako Datu-multzoen Txantiloiak", + "SELECT-TEMPLATE": "Aukeratu zure datu-multzoa deskribatzeko txantiloi bat", + "PROFILE": "DKP Txantiloia", + "PROJECT": "Proiektua", + "GRANT": "Diru-laguntza", + "GRANTS": "Diru-laguntzak", + "GRANTS-HINT": "Aurkitu zure ikerketaren diru-laguntza edo gehitu berria", + "FUNDER": "Finantzatzailea", + "FUNDER-HINT": "Aukeratu zure ikerketaren finantzatzaile bat edo gehitu berria", + "FUNDING-ORGANIZATIONS": "Erakunde finantzatzaileak", + "PROJECT-HINT": "{{ APP_NAME }}en dauden proiektuak diru-laguntza bateko jarduera desberdin gisa jasotzen dira edo eskema kolaboratiboetako diru-laguntza desberdinetan jasotako ekintza amankomun bezala, adibidez, ekarpenen deialdi irekiak. Mesedez, zure proiektua kategoria honetan badago, bete zure erankundeari lotutako diru-laguntza. Beste kasu guztietarako, mesedez, hutsik utzi eta autoosatu egingo da.", + "STATUS": "DKParen egoera", + "EXTERNAL-SOURCE-HINT": "Kanpo iturrietatik hornitutako balioen zerrenda", + "COLLABORATORS": "Kolaboratzaileak", + "LANGUAGE": "Hizkuntza", + "LANGUAGE-HINT": "Aukeratu zure DKParen hizkuntza", + "LICENSE": "Lizentzia", + "VISIBILITY": "Sarbide eskubideak", + "VISIBILITY-HINT": "Aukeratu nola agertuko den DKPa Zenodon argitaratu ondoren. Sarbide Irekia aukeratzerakoan, DKPa Zeonodon irekian egongo da argitaratze-dataren ondoren. Sarbide mugatua aukeratzerakoan, DKPa mugatuta egongo da argitaratu ondoren.", + "PUBLICATION": "Argitaratze-data", + "CONTACT": "Kontaktua", + "COST": "Kostuak", + "DATASETS": "Datu-multzoak" + }, + "ACTIONS": { + "GO-TO-GRANT": "DKParen Diru-laguntzara joan", + "GO-TO-DATASETS": "Datu-multzoetara joan", + "SAVE-CHANGES": "Aldaketak Gorde", + "SAVE": "Gorde", + "CANCEL": "Ezeztatu", + "DELETE": "Ezabatu", + "DELETE-DATASET": "Datu-multzoa ezabatu", + "DISCARD": "Baztertu", + "FINALISE": "Amaitu", + "LOCK": "DKPa beste erabiltzaile batek blokeatu du", + "PERMISSION": "Ez daukazu DKP hau editatzeko baimenik", + "INSERT-MANUALLY": "Eskuz sartu", + "CREATE-DATASET": "Berria sortu", + "DISABLED-EXPORT": "Mesedez zure aldaketak gorde DKP hau esportatzeko" + }, + "PLACEHOLDER": { + "DESCRIPTION": "Deskribapenarekin bete", + "ORGANIZATION": "Aukertau erakundea", + "AUTHORS": "Egileak aukeratu", + "RESEARCHERS": "Ikertzaileak aukeratu" + }, + "SNACK-BAR": { + "UNSUCCESSFUL-DOI": "DOIa ez da behar bezala sortu", + "SUCCESSFUL-DOI": "DOIa ondo sortu da", + "UNSUCCESSFUL-FINALIZE": "DKP ez da behar bezala amaitu" + }, + "DATASET-TEMPLATE-LIST": { + "TITLE": "Datu-multzoaren Txantiloiak Erabilgarri", + "TEXT": "Aukeratutako Datu-multzoaren Profilak: ", + "OK": "Ados" + }, + "VISIBILITY": { + "PUBLIC": "Sarbide Irekia", + "RESTRICTED": "Sarbide Mugatua" + }, + "STEPPER": { + "USER-GUIDE": "Gidaren pausoak", + "MAIN-INFO": "Informazio nagusia", + "FUNDING-INFO": "Finantziazioa", + "DATASET-SELECTION": "Datu-multzoaten aukeraketa", + "DATASET-INFO": "Datu-multzoaren informazioa", + "LICENSE-INFO": "License", + "DATASET": "Datu-multzoa", + "PREVIOUS": "Aurrekoa", + "NEXT": "Hurrengoa" + }, + "MAIN-INFO": { + "INTRO": "{{ APP_NAME }}en dagoen DKP batek ikerketaren inguruko funtsezko informazioa jasotzen du, hala nola, helburuak eta inplikatutako ikertzaileak, baina baita ikerketako datu-multzoen dokumentazioa ere, emandako urratsak eta datuak kudeatzeko jarduera guztietan erabilitako bitartekoak nabarmentzen dituena.", + "HINT": "DKParen deskribapen laburra, honen irismena eta helburuak.", + "TYPING": "Idatzi izenaren letra gehiago, zuzena aurkitzea errazagoa izan dadin.", + "UNIQUE-IDENTIFIER": "Identifikatzaile Bakarra", + "RESEARCHER-IDENTIFIER-EXISTS": "Ikertzailearen identifikatzailea dagoeneko existitzen da.", + "ORGANISATION-IDENTIFIER-EXSTS": "Erakundearen identifikatzailea dagoeneko existitzen da.", + "IDENTIFIER-EXISTS-RESEARCHER-LIST": "Identifikatzaile hau dagoeneko ikertzaileen zerrendako ikertzaile batek erabiltzen du.", + "IDENTIFIER-EXISTS-ORGANISATION-LIST": "Identifikatzaile hau dagoeneko erakundeen zerrendako erakunde batek erabiltzen du.", + "SAVE": "Gorde", + "CANCEL": "Ezeztatu" + }, + "FUNDING-INFO": { + "INTRO": "DKP Editorea erabiltzen ari zara. Irismenaren inguruko informazioa gehitu hemen, finantziazioa, zure DKPeko aktoreak eta erabaki sarbide eta berrerabilpen kontuak sortzen ari zaren DKParen ekoizpenerako.", + "FIND": "Ezin duzu zuzena aurkitu?", + "UNIQUE-IDENTIFIER": "Identifikatzaile Bakarra", + "IDENTIFIER-FUNDER-EXISTS": "Adierazitako identifikatzailea duen finantzatzailea existitzen da.", + "IDENTIFIER-GRANT-EXISTS": "Adierazitako identifikatzailea duen diru-laguntza existitzen da.", + "IDENTIFIER-PROJECT-EXISTS": "Adierazitako identifikatzailea duen proiektua existitzen da." + }, + "DATASET-INFO": { + "INTRO": "{{ APP_NAME }} en dagoen DKP batek ikerketaren inguruko funtsezko informazioa jasotzen du, hala nola, helburuak eta inplikatutako ikertzaileak, baina baita ikerketako datu-multzoen dokumentazioa ere, emandako pausoak eta datuak kudeatzeko jarduera guztietan erabilitako bitartekoak nabarmentzen dituena.", + "SECOND-INTRO": "Datu-multzoak aldez aurretik definitutako txantiloiak jarraituta dokumentatzen dira, txantiloi horiek datu-multzoen deskribapenen edukia ezartzen dute. Hemen {{ APP_NAME }}, DKP batek dokumentatutako datu-multzoen deskribapen adina izan ditzake.", + "FIND": "Ezin duzu zuzena aurkitu?", + "HINT": "Aukeratu zure data-multzoak deskribatzeko txantiloia. Txantiloi bat baino gehiago aukeratu ditzakezu." + }, + "LICENSE-INFO": { + "INTRO": "DKP bakoitzak lizentziari buruzko informazio espezifikoa izan dezake irekiera-maila eta erabilgarritasunari dagokienez, eta horrela zehaztu ahal izango duzu nork ikus dezakeen zure datu-multzoa eta zenbateko epean izango den pribatua", + "HINT": "Eman lizentzia bat zure DKPari zerrendatik egokiena iruditzen zaizuna aukeratuz.", + "TYPING": "Idatzi izenaren letra gehiago, zuzena aurkitzea errazagoa izan dadin." + }, + "DATASET-DESCRIPTION": { + "INTRO": "Oro har, zure ikerketa datuek 'fair'(Findable, Accessible, Interoperable, Reusable) izan behar dute, hau da, aurkitzeko modukoak, eskuragarriak, elkarreragingarriak eta berrerabilgarriak. Printzipio hauek inplementazio-aukeren aurretik daude eta ez dute inplementazio-teknologiarik, -araurik, edo -irtenbiderik iradokitzen. Txantiloi honek ez du fair printzipioen inplementazio tekniko zorrotza izan nahi, baizik eta fair printzipioetan oinarritzen den kontzeptu orokor gisa ulertu behar da." + }, + "CHANGES": "gorde gabeko aldaketak", + "CLONE-DIALOG": { + "CLONE": "Klonatu", + "SAVE": "Gorde", + "CANCEL": "Ezeztatu" + }, + "LOCKED": { + "TITLE": "DKPa blokeatuta dago", + "MESSAGE": "Beste norbait DKPa aldatzen ari da momentu honetan. Datu-multzoa ikus dezakezu, baina ezingo duzu aldaketarik egin." + } + }, + "DMP-PROFILE-LISTING": { + "TITLE": "DKP Txantiloiak", + "CREATE-DMP-TEMPLATE": "Sortu DKP Txantiloia", + "COLUMNS": { + "NAME": "Izena", + "STATUS": "Egoera", + "CREATED": "Sortuta", + "PUBLISHED": "Argitaratuta", + "LAST-EDITED": "Azkenengoz editatuta" + }, + "UPLOAD": { + "UPLOAD-XML": "Inportatu", + "UPLOAD-XML-FILE-TITLE": "Inportatu Datuak Kudeatzeko Planaren Txantiloia", + "UPLOAD-XML-NAME": "DKP Txantiloiaren Izena", + "UPLOAD-XML-IMPORT": "Fitxategia", + "UPLOAD-XML-FILE-CANCEL": "Ezeztatu" + }, + "STATUS": { + "DRAFT": "Zirriborroa", + "FINALIZED": "Amaituta" + }, + "MESSAGES": { + "TEMPLATE-UPLOAD-SUCCESS": "Txantiloia ondo kargatu da" + } + }, + "DYNAMIC-FORM": { + "FIELDS": { + "LABEL": "Etiketa" + }, + "ACTIONS": { + "PREVIEW": "Aurrebista", + "ADD-PAGE": "Gehitu Orria +", + "ADD-SECTION": "Gehitu Atala +" + } + }, + "CRITERIA": { + "FILTERS": "Filtroak", + "GRANTS": { + "LIKE": "Bilatu", + "PERIOD-FROM": "Diru-laguntza Hasiera", + "PERIOD-TO": "Diru-laguntza Amaiera", + "GRANT-STATE-TYPE": "Diru-laguntza Egoera", + "TYPES": { + "NONE": "-", + "ON-GOING": "Martxan", + "FINISHED": "Amaituta" + } + }, + "DATASET-PROFILE": { + "LIKE": "Bilatu", + "STATUS": "Egoera" + }, + "DATA-SETS": { + "PERIOD-FROM": "Hasi", + "PERIOD-TO": "Amaitu", + "STATUS": "Egoera", + "NONE": "-", + "TAGS": "Etiketak", + "SELECT-TAGS": "Aukeratu etiketak", + "LIKE": "Bilatu Datu-multzoak", + "DRAFT-LIKE": "Bilatu Datu-multzoen Zirriborroak", + "SELECT-GRANTS": "Aukerau Diru-laguntzak", + "ROLE": "Rola", + "ORGANIZATION": "Erakundea", + "SELECT-ORGANIZATIONS": "Aukeratu Erakundeak", + "SELECT-SPEC": "Aukeratu Datu-multzoaren Zehaztapenak", + "RELATED-GRANT": "Erlazionatutako Diru-laguntza", + "SELECT-DMP": "Auketau DKPa", + "RELATED-DMP": "Erlazionatutako DKPak", + "SELECT-COLLABORATORS": "Aukeratu Kolaboratzaileak", + "RELATED-COLLABORATORS": "Erlazionatutako Kolaboratzaileak", + "SELECT-DATASET-TEMPLATES": "Aukeratu Datu-multzoaren Txantiloiak", + "RELATED-DATASET-TEMPLATES": "Erlazionatutako Datu-multzoaren Txantiloiak", + "ALL-VERSIONS": "Bertsio Guztietatik" + }, + "DMP": { + "LIKE": "Bilatu DKPak", + "GRANTS": "Diru-laguntzak", + "SELECT-GRANTS": "Aukeratu Diru-laguntzak", + "SELECT-COLLABORATORS": "Aukeratu Kolaboratzaileak", + "RELATED-COLLABORATORS": "Erlazionatutako Kolaboratzaileak", + "SELECT-DATASET-TEMPLATES": "Aukeratu Datu-multzoaren Txantiloia", + "RELATED-DATASET-TEMPLATES": "Erlazionatutako Datu-multzoaren Txantiloia" + }, + "USERS": { + "LABEL": "Bilatu", + "ROLE": "Rola", + "SHOW": "Erakutsi" + }, + "SELECT": "Hautatu aukera bat", + "LIKE": "Bilatu" + }, + "DATASET-EDITOR": { + "TITLE": { + "NEW": "Datuak Kudeatzeko Plan Berria", + "EDIT": "Editatu", + "INTRO": "Datu-multzoen Editorea erabiltzen ari zara. Erantzun hemen zure datuak kudeatzeko jarduerak deskribatzen dituzten galderei.", + "INTRO-TIP": "Aholkua: Gehitu datu-multzo berriak datu mota desberdinak deskribatzeko, edo diziplinazko datuak deskribatzeko, informazioaren nahasmena ekiditeko." + }, + "FIELDS": { + "NAME": "Datu-multzoaren izena", + "TITLE": "Datu-multzoaren izenburua", + "DESCRIPTION": "Deskribapena", + "PROFILE": "Txantiloia", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)", + "DMP": "DKP", + "SELECT-DMP": "Aukeratu DKPa", + "DATAREPOSITORIES": "Datuen Biltegiak", + "REGISTRIES": "Erregistroak", + "SERVICES": "Zerbitzuak", + "EXTERNAL-DATASETS": "Kanpoko Datu-multzoak", + "EXTERNAL-DATASETS-DESCRIPTION": "DKPan deskribatutako batekin erlazionatutako datu-multzoak, bai ekoizpenean erabilitakoak edo deribatuak direnak edo hauek erabileraren azpiproduktuak", + "EXTERNAL-DATASET-TYPE": "Kanpoko Datu-multzo Mota", + "EXTERNAL-DATASET-INFO": "Kanpoko Datu-multzoaren Informazioa", + "DATAREPOSITORIES-INFO": "Datuen Biltegien Informazioa", + "EXTERNAL-LINK": "Kanpoko esteka", + "TAGS": "Etiketak", + "CREATE": "Berria Sortu" + }, + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu", + "DELETE": "Ezabatu", + "UPDATE": "Eguneratu", + "DISCARD": { + "DISCARD-NEW-MESSAGE": "Gorde ez diren aldaketa guztiak galdu egingo dira. Jarraitu nahi duzu?", + "DISCARD-NEW-CONFIRM": "Bai, aldaketak leheneratu.", + "DISCARD-NEW-DENY": "Ez.", + "DISCARD-EDITED-MESSAGE": "Gorde ez diren aldaketa guztiak galdu egingo dira. Jarraitu nahi duzu?", + "DISCARD-EDITED-CONFIRM": "Bai, aldaketak leheneratu.", + "DISCARD-EDITED-DENY": "Ez." + }, + "DISABLED-EXPORT": "Mesedez, gorde zure aldaketak Datu-multzo hau esportatzeko" + }, + "PLACEHOLDER": { + "DESCRIPTION": "Bete deskribapenarekin", + "EXTERNAL-LINK": "Eman kanpoko URL baten esteka" + }, + "HINT": { + "DESCRIPTION": "Labur deskribatu Datu-multzoaren testuingurua eta helburua", + "TITLE": "Honi buruzko deskribapen laburra ", + "TITLE-REST": " dituen irismen eta helburuei buruzkoa da." + }, + "VERSION-DIALOG": { + "ABOUT": "Bertsioen kontrola automatizatuta dago.", + "QUESTION": "Badirudi zure Datu-multzoaren Txantiloia zaharkituta dagoela. Azken bertsiora eguneratu nahi duzu?" + }, + "ERRORS": { + "ERROR-OCCURED": "Errore bat gertatu da.", + "MESSAGE": "Mezua: " + }, + "QUESTION": { + "EXTENDED-DESCRIPTION": { + "VIEW-MORE": "Gehiago ikusi", + "VIEW-LESS": "Gutxiago ikusi" + } + } + }, + "DATASET-CREATE-WIZARD": { + "ACTIONS": { + "NEXT": "Hurrengoa", + "BACK": "Atzera", + "SAVE": "Gorde" + }, + "FIRST-STEP": { + "TITLE": "DKP", + "PLACEHOLDER": "Aukeratu existitzen den DKP bat" + }, + "PREFILL-STEP": { + "TITLE": "Zure Datu-multzoa abiarazi", + "PREFILL": "Bete", + "OR": "EDO", + "HINT": "Aukeratu Zenodotik datu-multzoa zure txantiloiko galdera batzuk automatikoki berreskuratzeko edo hasi galderei eskuz erantzuten.", + "MANUALLY": "Eskuz", + "PROFILE": "Datu-multzoaren Txantiloia", + "PREFILLED-DATASET": "Aurrez betetako Datu-multzoa", + "SEARCH": "Datu-multzo bat edo software bat bilatzeko idazten hasi", + "NEXT": "Hurrengoa" + } + }, + "INVITATION-EDITOR": { + "TITLE": "Bidali gonbidapenak ", + "AUTOCOMPLETE-USER": "Erabiltzailea", + "AUTOCOMPLETE-EMAIL": "E-maila", + "AUTOCOMPLETE-USER-EMAIL": "Kat edo kat@adibidea.com", + "ACTIONS": { + "SEND-INVITATION": "Bidali Gonbidapenak", + "CANCEL": "Ezeztatu" + } + }, + "USERS": { + "LISTING": { + "TITLE": "Erabiltzaileak", + "EMAIL": "E-maila", + "LAST-LOGGED-IN": "Azken konexioa", + "LABEL": "Etiketa", + "ROLES": "Rolak", + "NAME": "Izena", + "PERMISSIONS": "Baimenak", + "EXPORT": "Esportatu erabiltzaileak" + }, + "ACTIONS": { + "EDIT": "Editatu", + "SAVE": "Gorde" + } + }, + "TYPES": { + "APP-ROLE": { + "ADMIN": "Administratzailea", + "USER": "Erabiltzailea", + "MANAGER": "Kudeatzailea", + "DATASET-TEMPLATE-EDITOR": "Datu-multzoaren Txantiloi Editorea" + }, + "DMP-PROFILE-FIELD": { + "DATA-TYPE": { + "DATE": "Data", + "NUMBER": "Zenbakia", + "TEXT": "Testua", + "EXTERNAL-AUTOCOMPLETE": "Kanpo Autoosaketa" + }, + "TYPE": { + "INPUT": "Sarrera" + } + }, + "DATASET-STATUS": { + "DRAFT": "Zirriborroa", + "FINALISED": "Amaituta", + "ANY": "Edozein", + "DRAFT-DESC": "Erregistroen Zirriborroak" + }, + "DATASET-ROLE": { + "OWNER": "Jabea", + "MEMBER": "Kidea", + "ANY": "Edozein" + }, + "EXTERNAL-DATASET-TYPE": { + "SOURCE": "Iturria", + "SOURCES": "Iturriak", + "SOURCE:": "Iturria: ", + "NO-SOURCE": "Ez du iturriarekin loturarik", + "OUTPUT": "Irteera", + "SELECT": "Aukeratu" + }, + "DMP": { + "FINALISED": "Amaituta", + "DRAFT": "Zirriborroa" + }, + "DMP-VISIBILITY": { + "VISIBILITY": "Ikusgaitasuna", + "PUBLIC": "Argitaratuta", + "FINALIZED": "Amaituta", + "DRAFT": "Zirriborroa", + "ANY": "Edozein" + }, + "DATASET-PROFILE-FIELD-VALIDATION-TYPE": { + "NONE": "Bat ere ez", + "REQUIRED": "Derrigorrezkoa" + }, + "DATASET-PROFILE-FIELD-VIEW-STYLE": { + "BOOLEAN-DECISION": "Erabaki Boolearra", + "CHECKBOX": "Kontrol-laukia", + "COMBO-BOX": "Kutxa Konbinatua", + "INTERNAL-DMP-ENTITIES": "DKParen Barne Entitateak", + "FREE-TEXT": "Testu librea", + "RADIO-BOX": "Radio Box", + "TEXT-AREA": "Testu-eremua", + "RICH-TEXT-AREA": "Testu Aberastuaren Eremua", + "UPLOAD": "Kargatu", + "DATE-PICKER": "Data hautatzailea", + "EXTERNAL-DATASETS": "Kanpoko Datu-multzoak", + "DATA-REPOSITORIES": "Datuen Biltegiak", + "PUB-REPOSITORIES": "Argitalpenen Biltegiak", + "JOURNALS-REPOSITORIES": "Aldizkariak", + "TAXONOMIES": "Taxonomiak", + "LICENSES": "Lizentziak", + "PUBLICATIONS": "Argitalpenak", + "REGISTRIES": "Metadatuak", + "SERVICES": "Zerbitzuak", + "TAGS": "Etiketak", + "RESEARCHERS": "Ikertzaileak", + "ORGANIZATIONS": "Erakundeak", + "DATASET-IDENTIFIER": "Datu-multzoaren Identifikatzailea", + "CURRENCY": "Moneta", + "VALIDATION": "Balidatzailea", + "OTHER": "Bestelakoa", + "SELECT": "Aukeratu" + }, + "DATASET-PROFILE-UPLOAD-TYPE": { + "DOWNLOAD": "Fitxategia deskargatu" + }, + "DATASET-PROFILE-COMBO-BOX-TYPE": { + "WORD-LIST": "Hitzen zerrenda", + "AUTOCOMPLETE": "Autoosatu", + "EXTERNAL-SOURCE-HINT": "Kanpo iturrietatik hornitutako balioen zerrenda", + "ACTIONS": { + "YES": "Bai", + "NO": "Ez" + } + }, + "DATASET-PROFILE-INTERNAL-DMP-ENTITIES-TYPE": { + "RESEARCHERS": "Ikertzaileak", + "DMPS": "DKPak", + "DATASETS": "Datu-multzoak", + "EXTERNAL-SOURCE-HINT": "Kanpo iturrietatik hornitutako balioen zerrenda" + }, + "DATASET-PROFILE-VALIDATOR": { + "ACTION": "Baliozkotu", + "REPOSITORIES-PLACEHOLDER": "Biltegiak" + }, + "DATASET-PROFILE-IDENTIFIER": { + "IDENTIFIER-TYPE": "Identifikatzaile Mota" + }, + "RECENT-ACTIVITY-ORDER": { + "CREATED": "Sortuta", + "LABEL": "Etiketa", + "MODIFIED": "Aldatuta", + "FINALIZED": "Amaituta", + "PUBLISHED": "Argitaratuta", + "STATUS": "Egoera" + } + }, + "ADDRESEARCHERS-EDITOR": { + "TITLE": "Gehitu Ikertzaile bat", + "FIRST_NAME": "Izena", + "LAST_NAME": "Abizena", + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu" + } + }, + "ADDORGANIZATION-EDITOR": { + "TITLE": "Gehitu Erakunde bat", + "NAME": "Izena", + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu" + } + }, + "ADDEDITCOST-EDITOR": { + "ADD-TITLE": "Gehitu Kostua", + "EDIT-TITLE": "Editatu Kostua", + "CODE": "Kodea", + "DESCRIPTION": "Deskribapena", + "TITLE": "Izenburua", + "VALUE": "Balioa", + "ACTIONS": { + "SAVE": "Gorde", + "CANCEL": "Ezeztatu" + } + }, + "DMP-WIZARD": { + "FIRST-STEP": { + "DMP": "DKP Editorea", + "DATASETS": "Datu-multzoa" + }, + "ACTIONS": { + "NEXT": "Hurrengoa", + "BACK": "Atzera", + "SAVE": "Gorde" + } + }, + "DMP-RELATED-GRANT": { + "RELATED-GRANT": "Erlazionatutako Diru-laguntza" + }, + "DMP-RELATED-COLLABORATOR": { + "RELATED-COLLABORATOR": "Erlazionatutako Kolaboratzaileak", + "SELECT-COLLABORATORS": "Aukeratu Kolaboratzaileak" + }, + "DMP-RELATED-ORGANIZATION": { + "RELATED-ORGANIZATION": "Erakundea", + "SELECT-ORGANIZATIONS": "Aukeratu Erakundeak" + }, + "DATASET-PROFILE": { + "PREVIEW": "Aurrebista", + "FORM-DESCRIPTION": "Formuralioaren Deskribapena", + "PAGES-DESCRIPTION": "Orrialdeen Deskribapena" + }, + "RECENT-ACTIVITY": { + "MY-TITLE-GRANT": "Nire azken jarduerak Diru-laguntzetan", + "MY-TITLE-DMP": "Nire azken jarduerak DKPetan", + "MY-TITLE-DATASET": "Nire azken jarduerak Datu-multzoetan", + "LAST-VISITED-DMP": "Azkenengoz Bisitatutako Datuen Kudeaketarako Plana", + "LAST-EDITED-DMP": "Azkenengoz Editatutako Datuen Kudeaketarako Plana", + "LICENSE": "Jarraian dauden DKPak publiko daude lizentzia honen pean ##" + }, + "FILE-UPLOADER": { + "DEFAULT": "Aukeratu fitxategi bat", + "GRANT": "", + "UPLOAD": "Kargatu" + }, + "URL-LISTING-COMPONENT": { + "SHOW-MORE": "Erakutsi gehiago" + }, + "HOMEPAGE": { + "OPEN-DMPS": { + "STATS": "{{ APP_NAME_CAPS }} Aginte-panela" + }, + "MY-DMPS": { + "STATS": "Nire Aginte-panela" + } + }, + "ABOUT": { + "TITLE-DASHED": "-Honi buruz-", + "TITLE": "Honi buruz", + "MAIN-CONTENT": "Gure helburua da zure ikerketa-datuak FAIR izatea, hau da, aurkitzeko modukoak, eskuragarriak, elkarreragingarriak eta berrerabilgarriak. Printzipio hauek inplementazio-aukeren aurretik daude eta ez dute inplementazio-teknologiarik, -araurik, edo -irtenbiderik iradokitzen.", + "CONTRIBUTORS": "Diru-emaileak", + "WELCOME": "Ongi etorri {{ APP_NAME_CAPS }}ra", + "WELCOME-MESSAGE": "Sortu, Lotu, Partekatu Datuen Kudeaketarako Planak" + }, + "FOOTER": { + "CONTACT-SUPPORT": "Kontaktatu Laguntzarekin", + "FAQ": "Ohiko Galderak", + "GUIDE": "Erabiltzailearen Gida", + "GLOSSARY": "Glosarioa", + "TERMS-OF-SERVICE": "Zerbitzuaren Baldintzak", + "ABOUT": "Honi buruz", + "COOKIES-POLICY": "Cookie-politika", + "PRIVACY-POLICY": "Pribatutasun-politika" + }, + "GLOSSARY": { + "TITLE": "Glosarioa", + "TITLE-DASHED": "-Glosarioa-", + "CLOSE": "Itxi" + }, + "FAQ": { + "TITLE": "FAQ", + "TITLE-DASHED": "-FAQ-", + "CLOSE": "Itxi" + }, + "GUIDE": { + "TITLE": "Erabiltzailearen Gida", + "TITLE-DASHED": "-Erabiltzailearen Gida-", + "CLOSE": "Itxi", + "SAVE": "Gorde" + }, + "PRIVACY-POLICY": { + "TITLE": "-Pribatutasun-politika-", + "MAIN-CONTENT": "" + }, + "OPENSOURCE-LICENCES": { + "TITLE": "Lizentzia irekiak", + "MAIN-CONTENT": "" + }, + "TERMS-OF-SERVICE": { + "TITLE": "Zerbitzuaren Baldintzak", + "MAIN-CONTENT": "" + }, + "COOKIES-POLICY": { + "TITLE": "Cookie-politika" + }, + "CONTACT": { + "SUPPORT": { + "TITLE": "Kontaktatu Laguntzarekin", + "SUBTITLE": "Zertan lagun zaitzakegu", + "SUBJECT": "Gaia", + "DESCRIPTION": "Deskribapena", + "CANCEL": "Ezeztatu", + "SEND": "Bidali" + }, + "TITLE-DASHED": "-Kontaktatu Laguntzarekin-", + "GUIDE": "Gida", + "HELP": "Laguntza", + "GLOSSARY": "Glosarioa" + }, + "LANGUAGE": { + "TITLE": "Hizkuntza", + "TITLE-DASHED": "-Hizkuntza-", + "CLOSE": "Itxi" + }, + "DASHBOARD": { + "MY-GRANTS": "Nire Diru-laguntzak", + "GRANTS": "Diru-laguntzak", + "MY-DMPS": "Nire DKPak", + "TITLE": "Zer da {{ APP_NAME_CAPS }}?", + "DMP-QUESTION": "Zer da DKP bat hemen {{ APP_NAME_CAPS }}?", + "INFO-TEXT": "{{ APP_NAME_CAPS }} zerbitzu irekia eta hedagarria da, Datuak Kudeatzeko Planen kudeaketa, baliozkotzea, monitorizazioa eta mantenketa sinplifikatzen dituena. Eragileei (ikertzaileak, kudeatzaileak, ikuskatzaileak, etab.) prozesagarriak diren DKPak sortzeko aukera ematen die, azpiegitura desberdinen artean libreki truka daitezkeenak, datuen kudeaketa prozesuko alderdi espezifikoak gauzatzeko, datuen jabeen asmoen eta konpromisoaren arabera.", + "INFO-DMP-TEXT": "Datuak Kudeatzeko Plana (DKP) dokumentu bizia da eta ikerketa baten bizialdian zehar eta ondoren sortzen edota berrerabiltzen diren datu-multzoak deskribatzen ditu. DKPen xedea da, ikertzaileei funtsezko informazioa ematea beraien ikerketa emaitzak berrekoiztu, birbanatu eta berrerabiltzeko, horrela, haien baliozkotasuna eta ustiapena bermatuz.", + "NEW-QUESTION": "Berria zara DKPekin? Bisitatu", + "START-YOUR-FIRST-DMP": "Hasi zure lehen DKP", + "OPEN-AIR-GUIDE": "OpenAIRE’ren Ikertzaileentzako Gida", + "LEARN-MORE": "bat sortzeko moduari buruz gehiago jakiteko!", + "ORGANIZATIONS": "Erlazionatutako Erakundeak", + "DMPS": "DKPak", + "MY-DATASETS": "Nire Datu-multzoak", + "DATASETS": "Datu-multzoak", + "SEARCH": "BILATU...", + "DATA-MANAGEMENT-PLANS": "DATUAK KUDEATZEKO PLANAK", + "PERSONAL-USAGE": "Erabilera pertsonala", + "PUBLIC-USAGE": "Erabilera publikoa", + "DATASET-DESCRIPTIONS": "Datu-multzoak", + "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Datu-multzoak", + "PUBLIC-DMPS": "DKP Publikoak", + "PUBLIC-DATASETS": "Datu-multzo Publikoak", + "RELATED-ORGANISATIONS": "Erlazionatutako Erakundeak", + "DRAFTS": "Zirriborroak", + "ALL": "Guztiak", + "EMPTY-LIST": "Hutsik dago oraindik.", + "LATEST-ACTIVITY": "Azkenengo jarduera", + "DMP-ABOUT-BEG": "DKP batek {{ APP_NAME }} ikerketaren inguruko funtsezko informazioan datza, hala nola xedea, helburuak eta parte hartzen duten ikertzaileak, baina baita ikerketaren datu-multzoen dokumentazioari buruzkoa ere, hain zuzen ere", + "DMP-ABOUT-END": ", datuak kudeatzeko jarduera guztietan jarraitutako pausoak eta erabilitako bitartekoak nabarmentzen dituena.", + "SELECT-DMP": "Aukeratu DKP bat zure Datu-multzorako", + "ACTIONS": { + "ADD-DATASET-DESCRIPTION": "Gehitu Datu-multzoa", + "ADD-DATASET": "Gehitu Datu-multzoa", + "ADD-DMP-DESCRIPTION": "Gehitu DKParen Deskribapena" + }, + "TOUR-GUIDE": { + "DMP": "Hau da zure aginte-panela. Parte hartu duzun edo zuk zeuk sortutako DKP guztiak ikusi eta editatu ditzakezu.", + "START-NEW": "Sortu zure DKPa Hasi DKP berria aukerarekin.", + "IMPORT-DMP": "DKP bat inportatu dezakezu", + "START-WIZARD": "edo berri bat sortu hemen {{ APP_NAME }}.", + "DATASET": "Hau da zure aginte-panela. Parte hartu duzun edo zuk zeuk sortutako Datu-multzo guztiak ikusi eta editatu ditzakezu.", + "NEW-DATASET": "Gehitu Datu-multzoa aukerarekin, datu-multzo berriak deskriba ditzakezu ikerketa-prozesuaren edozein unetan.", + "GOT-IT": "Ulertuta!", + "LEAVE-TOUR": "Tourra utzi" + }, + "ADD-NEW-DATASET": { + "OPTIONS-NOT-ENOUGH": "Aukera hauek ez dira nahikoa?", + "START-NEW-DMP": "Hasi DKP berria" + } + }, + "USER-DIALOG": { + "USER-PROFILE": "Nire Profila", + "USER-PROFILE-SETTINGS": "Nire Profilaren Ezarpenak...", + "EXIT": "Atera ", + "LOG-OUT": "Saioa itxi" + }, + "USER-PROFILE": { + "MERGING-SUCCESS": "Bi profilen arteko lotura ondo egin da.", + "MERGING-EMAILS-DIALOG": { + "TITLE": "Lotutako kontua egiaztatu", + "MESSAGE": "Ekintza hau berresteko e-mail bat bidali zaizu. Behin onartuta, kontuak bateratuta ikusteko aukera izango duzu. Bateratu duzun azken e-mail kontua izango da {{ APP_NAME }}en DKParen erregistro eta jarduera guztiak dituena." + }, + "UNLINK-ACCOUNT": { + "TITLE": "Bereizi nahi duzun kontua egiaztatu", + "MESSAGE": "Ekintza hau berresteko e-mail bat bidali zaizu zure kontu nagusira. Behin onartuta, {{accountToBeUnlinked}} kontuak zure egungo ARGOS profilera konektatuta egoteari utziko dio." + }, + "UNLINK-ACCOUNT-DIALOG": { + "MESSAGE": "\"Konfirmatu\" sakatzean, kontu honetatik egindako ARGOS jardueraren transferentzia onartzen duzu zure ARGOS kontu nagusira, azken hau izango da lehenengo agertuko dena. Deslotutako kontuarekin berriro sartzen saiatzen bazara, zure ARGOS esperientzia zerotik hasi ahal izango duzu, hutsik dagoen aginte-panel batean.", + "CONFIRM": "Konfirmatu", + "CANCEL": "Ezeztatu" + }, + "SETTINGS": { + "TITLE": "Ezarpenak", + "TIMEZONE": "Ordu-eremua", + "CULTURE": "Kultura", + "LANGUAGE": "Hizkuntza", + "CONNECTED-WITH": "Honekin konektatuta", + "NAME": "Izena", + "ORGANIZATION": "Erakundea", + "ROLE": "Rola", + "SELECT-ROLE": "Aukeratu Rola", + "ACCOUNTS": "Kontuak", + "EMAILS": "E-mailak", + "YOUR-EMAIL": "Zure E-maila" + }, + "ASSOCIATED-DMPS": "Lotutako DKPak", + "DMPS": { + "SHOW-ALL": "Erakutsi guztiak", + "CREATOR": "Sortzailea", + "MEMBER": "Kidea" + }, + "ZENODO": { + "LOGIN": "Konektatu Zenodora", + "LOGOUT": "Kendu Zenodo", + "AUTHORIZE": "Baimendu Zenodo", + "TITLE": "Zenodo Kontua", + "DESCRIPTION": "Zenodo Kontura Lotuta" + }, + "ROLE-ORGANIZATION": { + "FACULTY": "Fakultatea", + "LIBRARIAN": "Liburuzaina", + "RESEARCHER": "Ikertzailea", + "STUDENT": "Ikaslea", + "EARLY-CAREER-RESEARCHER": "Ikertzaile berria (doktoregaia, graduondokoa)", + "RESEARCH-ADMINISTRATOR": "Ikerketa Administratzailea", + "REPOSITORY-MANAGER": "Biltegiko Kudeatzailea", + "RESEARCH-INFRASTRUCTURE": "Ikerketa-azpiegitura", + "SERVICE-PROVIDER": "Zerbitzuaren Hornitzailea", + "PUBLISHER": "Argitaratzailea", + "RESEARCH-FUNDER": "Ikerketa Finantzatzailea", + "POLICY-MAKER": "Politika arduraduna", + "SME-INDUSTRY": "Industria", + "OTHER": "Bestelakoa" + }, + "ACTIONS": { + "SAVE": "Gorde", + "LINK-NEW": "Berria lotu", + "LINK-NEW-ACCOUNT": "Kontu berria lotu", + "UNLINK-ACCOUNT": "Deslotu", + "UNLINK-ACCOUNT-DISABLED": "Ezin duzu e-maila zure kontu nagusitik bereizi", + "ADD": "Gehitu", + "CANCEL": "Ezeztatu" + } + }, + "DATASET-REFERENCED-MODELS": { + "SERVICES": { + "TITLE": "Gehitu Zerbitzu Berria", + "LABEL": "Etiketa", + "ABBREVIATION": "Laburdura", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)" + }, + "DATA-REPOSITORY": { + "TITLE": "Gehitu Datuen Biltegi Berria", + "LABEL": "Etiketa", + "ABBREVIATION": "Laburdura", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)" + }, + "EXTERNAL-DATASET": { + "TITLE": "Gehitu Kanpoko Datu-multzoa", + "LABEL": "Etiketa", + "ABBREVIATION": "Laburdura" + }, + "REGISTRY": { + "TITLE": "Gehitu Erregistro Berria", + "LABEL": "Etiketa", + "ABBREVIATION": "Laburdura", + "URI": "Baliabide Identifikatzaile Uniformea (Uri)" + } + }, + "FACET-SEARCH": { + "FILTER": "Filtroa", + "GRANT-STATUS": { + "TITLE": "Diru-laguntzaren Egoera", + "OPTIONS": { + "ANY": "Edozein", + "ACTIVE": "Aktibo", + "INACTIVE": "Ez-aktibo" + } + }, + "GRANT": { + "TITLE": "Erlazionatutako Diru-laguntza", + "FILTER": "Filtratu Diru-laguntzak" + }, + "PROFILES": { + "TITLE": "Datu-multzoaren zehaztapena" + }, + "ROLE": { + "TITLE": "Rola", + "ANY": "Edozein", + "OWNER": "Jabea", + "MEMBER": "Kidea" + }, + "DMP-ORGANISATIONS": { + "TITLE": "Erakundea", + "FILTER": "Filtratu Erakundeak" + } + }, + "DMP-FINALISE-DIALOG": { + "DMP": "DKPa", + "DATASETS": "Datu-multzoak", + "EMPTY": "Orain arte ez dago DKP honetarako datu-multzorik", + "SUBMIT": "Bidali", + "FINALISE-TITLE": "Datu-multzoen zirriborro hauetakoren bat amaitu bahi duzu?", + "ALREADY-FINALISED-DATASETS": "Amaitutako datu-multzoak", + "NONE": "Bat ere ez", + "VALIDATION": { + "AT-LEAST-ONE-DATASET-FINALISED": "Gutxienez datu-multzo bat amaituta izan behar duzu" + }, + "IMPACT": "Ekintza honek zure DKPa amaitutzat emango du eta ezingo duzu berriro editatu.", + "AFTER-FINALIZATION-PUBLISH": "Zure DKPa amaitu ondoren, argitaratu egingo da eta {{ APP_NAME_CAPS }} tresnan publikoki ikusgai egongo da.", + "AFTER-FINALIZATION-RESTRICT-ACCESS": "Zure DKPa argitaratu daiteke eta publiko jarri {{ APP_NAME_CAPS }} tresnan behin amaituta eta sarbide-eskubideak irekitzen direnean. Egungo sarbide-eskubideak: mugatuak", + "INVALID": "Baliogabea" + }, + "DRAFTS": { + "FOR-DMP": "DKPerako:", + "FOR-GRANT": "Diru-laguntzarako:" + }, + "QUICKWIZARD": { + "CREATE-ADD": { + "CREATE": { + "TITLE": "Sortu DKP berria", + "SUBTITLE": "Sortu DKP berria eta deskribatu zure Datu-multzoa(k) gure laguntzaileak pausoz pauso gidatuta DKP batek izan beharreko funtsezko elementuetan barrena.", + "QUICKWIZARD_CREATE": { + "TITLE": "DKP Laguntzailea", + "POST-SELECTION-INFO": "Laguntzaile honek DKP berri bat sortzea ahalbidetzen dizu, honetarako beharrezkoa den funtsezko informazioa soilik emanez eta, ondoren, DKP honen pean kudeatutako Datu-multzo bat edo gehiago deskribatuz. Laguntzailearekin bukatzean, DKPa editatzen jarraitu ahal izango duzu, honen ezarpen aurreratuetara sartuz, DKParen editorearen bitartez, Datu-multzo gehiago gehituz edo aurrekoak editatuz.", + "ACTIONS": { + "DELETE": "Ezabatu", + "SAVE": "Gorde", + "SAVE-AND-FINALIZE": "Gorde eta amaitu", + "NEXT": "Hurrengoa", + "BACK": "Atzera", + "CREATE-NEW-GRANT": "Gehitu Diru-laguntza", + "EXIST-GRANT": "Erabili existitzen den Diru-laguntza", + "CREATE-NEW-FUNDER": "Gehitu Finantzatzailea", + "EXIST-FUNDER": "Erabili existitzen den Finantzatzailea", + "CREATE-NEW-PROJECT": "Gehitu Proiektua", + "EXIST-PROJECT": "Erabili existitzen den Proiektua" + }, + "FIRST-STEP": { + "TITLE": "Diru-laguntza", + "ABOUT-GRANT": "Bilatu zure DKPari lotuta dagoen diru-laguntza eta lotu finantzatzaileen informazioari. Diru-laguntza zerrendan agertzen ez bada edo diru-laguntza deialdi baterako DKPa sortzen ari bazara edo beste helburua batzuetarako, erabili \"Gehitu Diru-laguntza\"", + "ABOUT-NEW-GRANT": "DKPa diru-laguntza deialdi baterako sortzen ari bazara, erabilera instituzional edo ikerketa-komunitaterako, edo prestakuntza- eta hezkuntza helburuetarako, gehitu informazioa jarraian diru-laguntza berri bat sortuz.", + "ABOUT-FUNDER": "Bilatu zure DKPari lotuta joatea nahi duzun finantzatzailea eta, ondoren, aukeratu finantzatzaile hori lotuta dagoen diru-laguntza. Finantzatzailea zerrendan agertzen ez bada, erabili \"Gehitu Finantzatzailea\"", + "ABOUT-NEW-FUNDER": "Diru-laguntza deialdi baterako DKPa sortzen ari bazara, erabilera instituzional edo ikerketa-komunitaterako, edo prestakuntza- eta ikerketa-helburuekin, eta zerrendan agertzen ez den finantzatzaile batekin lotu nahi baduzu, sortu finantzatzaile berria", + "ABOUT-PROJECT": "Bilatu zure DKPa lotuta dagoen proiektua. Proiektua zerrendan agertzen ez bada, erabili \"Gehitu Proiektua\"", + "ABOUT-NEW-PROJECT": "", + "OR": "edo", + "FIELDS": { + "SELECT-GRANT": "Aukeratu DKPari lotutako diru-laguntza", + "SELECT-FUNDER": "Aukeratu DKPari lotutako diru-laguntzaren finantzatzailea", + "SELECT-PROJECT": "Aukeratu DKPari lotutako proiektua", + "GRANT-LABEL": "Diru-laguntzaren Izena", + "FUNDER-LABEL": "Finantzatzailearen Izena", + "PROJECT-LABEL": "Proiektuaren Izena", + "LABEL-HINT": "Gehitu diru-laguntzaren izena diru-laguntzaren deialdian agertzen den bezala", + "DESCRIPTION": "Deskribapena", + "DESCRIPTION-HINT": "Azaldu labur diru-laguntzaren xedea eta helburuak" + } + }, + "SECOND-STEP": { + "TITLE": "DKP Profila", + "ABOUT": "Datuen Kudeaketarako Plan bat diru-laguntzaren inguruko galdera multzo bati zehaztasun maila egoki batekin erantzutean datza, edo sortzen ari zaren DKParen helburua modu egokian jasotzean. DKP bakoitzaren edukiak aldatu egiten dira aukeratutako Datu-multzoen Txantiloien arabera, txantiloi hauek finantzatzaileen, erakundeen, ikerketa-komunitateen baldintza politikei erantzuteko galderak dituzte.", + "NEW-TITLE": "", + "DMP-NAME": "Diru-laguntza honetarako DKPa : ", + "FIELDS": { + "NAME": "DKParen izenburua", + "DESCRIPTION": "Laburpena", + "DESCRIPTION-HINT": "Deskribatu labur DKParen testuingurua eta xedea", + "PROFILE": "Datu-multzoaren Txantiloia", + "PROFILE-HINT": "Aukeratu zure Datu-multzoa(k) deskribatzeko txantiloia. Datu-multzoen Txantiloi desberdinak aukeratu nahi badituzu, erabili \"DKP Berria (Aditua)\". Halaber, datu-multzo berriak gehitu ditzakezu edozein momentutan DKPa sortu ondoren.", + "HELP": "Ez baduzu txantiloirik aurkitzen edo zure erakundera, ikerketa-komunitatera edo prestakuntza-beharretara pertsonalizatutako txantiloi bat sortu nahi baduzu, jarri gurekin harremanetan mesedez." + } + }, + "THIRD-STEP": { + "TITLE": "Datu-multzoa", + "NEW-TITLE": "", + "DATASET-LABEL": "Datu-multzoaren izenburua", + "DATASET-NAME": "Datu-multzoa: ", + "DATASET-NAME-FOR": " DKPerako: ", + "LIST-BUTTON-TOOLTIP": "Datu-multzoen Zerrenda", + "ADD-BUTTON-TOOLTIP": "Gehitu Datu-multzoa" + } + } + }, + "ADD": { + "TITLE": "Gehitu Datu-multzoa existitzen den DKP batetan", + "DATASET-WIZARD": "Datu-multzoaren Laguntzailea", + "POST-SELECTION-INFO": "Laguntzaile honek existitzen diren DKPetan Datu-multzoak gehitzearen prozesua sinplifikatzen du, gidatu egiten zaitu eta ataza osatzeko funtsezkoa den informazioa bakarrik eskatzen dizu. Datu-multzo baten ezaugarrietara sarbide osoa, Sistemaren datu-multzoen sarbide menuen bitartez lor daiteke.", + "SUBTITLE": "Laguntzaile honek DKP baten testuinguruan kudeatutako datu-multzo gehigarriak deskribatzeko aukera ematen dizu, hauen deskribapenerako funtsezko informazioa emanez.", + "CREATED": "Noiz sortuta" + } + }, + "SAVE-DIALOG": { + "TITLE": "Beste Datu-multzo bat gehitu nahi duzu?", + "ACTIONS": { + "AFFIRMATIVE": "Bai", + "NEGATIVE": "Ez" + } + }, + "HINT": "(Iradokitako Izen Lehenetsia)" + }, + "DATASET-PROFILE-STATUS": { + "NONE": "Bat ere ez", + "DRAFT": "Zirriborroa", + "FINALIZED": "Amaituta", + "DELETED": "Ezabatuta" + } +} \ No newline at end of file diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 392e4bf0a..a6d2d9503 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Anmeldung fehlgeschlagen", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Erfolgreich gelöscht", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Diese Vorlage kann nicht gelöscht werden, da Datensatzbeschreibungen noch damit verbunden sind", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Erfolgreich gelöscht", "UNSUCCESSFUL-DELETE": "Löschen fehlgeschlagen", "UNSUCCESSFUL-EMAIL-SEND": "E-Mail versenden fehlgeschlagen", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Neuer DMP (Assistent)", "PLANS-NEW": "Neuer DMP (Experte)", "DMP-NEW": "Neuer DMP", - "DATASETS": "Meine Datensatzbeschreibungen", - "EXPLORE": "Veröffentlichte Datensatzbeschreibungen", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Datensatzbeschreibung hinzufügen (Assistent)", "GRANTS": "Meine Förderungen", - "DMP-PROFILES": "DMP Vorlagen", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Vorlagen für Datensatzbeschreibungen", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Benutzer", "PROFILE": "Mein Profil", "LOGIN": "Anmeldung", @@ -151,10 +156,13 @@ "DATASET-NEW": "Neue Datensatzbeschreibung", "GRANT-NEW": "Neue Förderung", "GRANT-EDIT": "Förderung anzeigen/bearbeiten", - "DMP-PROFILE-NEW": "Neue DMP Vorlage", - "DMP-PROFILE-EDIT": "DMP Vorlage bearbeiten", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Neue Vorlage für Datensatzbeschreibung", "DATASET-PROFILES-EDIT": "Vorlage der Datensatzbeschreibung bearbeiten", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Übersicht über veröffentlichte DMP", "DATASET-PUBLIC-EDIT": "Veröffentlichten Datensatz anzeigen", "DMP-PUBLIC-EDIT": "Veröffentlichten DMP anzeigen", @@ -183,7 +191,8 @@ "SERBIAN": "Serbian", "PORTUGUESE": "Portuguese", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "DMPs", "MY-DMPS": "MEINE DMPs", "DATASETS": "Datensatzbeschreibungen", - "DATASET": "Datensatz", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Erkunde {{ APP_NAME_CAPS }}", "USERS": "Nutzer", "DATASETS-ADMIN": "Datensatzvorlagen", - "DMP-PROFILES": "DMP Vorlagen", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Über", "MY-DATASET-DESCRIPTIONS": "MEINE DATENSATZBESCHREIBUNGEN", "DATASET-DESCRIPTION-WIZARD": "Datensatzbeschreibungsassistent", @@ -233,7 +242,7 @@ "DMP-WIZARD": "DMP ASSISTENT", "DATASET-TEMPLATES": "DATENSATZVORLAGEN", "TEMPLATE": "VORLAGE", - "DMP-TEMPLATES": "DMP VORLAGEN", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "BENUTZER", "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 +268,19 @@ "QUICK-WIZARD-DATASET": "Füge Datensatzbeschreibung hinzu (Assistent)", "ADD-EXPERT": "Neuer DMP (Experte)", "MY-DATASET-DESC": "Meine Datensatzbeschreibungen", - "MY-DATASETS": "Meine Datensatzbeschreibungen", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Meine Förderungen", "HISTORY": "CHRONIK", "HISTORY-VISITED": "ZULETZT BESUCHT", "HISTORY-EDITED": "ZULETZT BEARBEITET", "PUBLIC": "VERÖFFENTLICHT", "PUBLIC-DMPS": "Veröffentlichte DMPs", - "PUBLIC-DESC": "Published Dataset Descriptions", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "KONTO", "ADMIN": "ADMINISTRATOR", - "DATASET-TEMPLATES": "Vorlagen für Datensatzbeschreibungen", - "DMP-TEMPLATES": "DMP Vorlagen", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Benutzer", "LANGUAGE-EDITOR": "Sprachbearbeitung", "GUIDE-EDITOR": "Benutzerhandbuch bearbeiten", @@ -281,30 +291,34 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "New API Client", - "NEW-PROFILE": "New Dataset Description Template", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "New Version Of ", "NEW-PROFILE-CLONE": "New Clone Of " }, "FIELDS": { - "DATASET-TITLE": "Dataset Description 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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,7 +328,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": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Label", @@ -615,7 +633,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 +660,8 @@ "INVITE-AUTHORS": "Invite authors", "INVITE-SHORT": "Invite", "ADD-DATASET": "Datensatzbeschreibung zum DMP hinzufügen", - "ADD-DATASET-DESCRIPTION": "Add dataset", - "ADD-DATASET-SHORT": "Add Dataset", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Alle DMP-Datensatzbeschreibungen auflisten", "NEW-VERSION": "Neue Version", "START-NEW-VERSION": "Start New Version", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "PDF herunterladen", "DOWNLOAD-XML": "XML herunterladen", "DOWNLOAD-DOCX": "DOCX herunterladen", - "COPY-DATASET": "Datensatzbeschreibung kopieren", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Vorlage aktualisieren", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +812,7 @@ "GRANT": "Förderung", "DMP-AUTHORS": "DΜP Authors", "RESEARCHERS": "Forschende", - "DATASETS-USED": "Datasets used", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Mitwirkende", "PUBLIC": "Public", "PRIVATE": "Private", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "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,13 +868,13 @@ }, "DATASET-LISTING": { "TITLE": "Datensatzbeschreibungen", - "DATASET-DESCRIPTION": "Dataset", - "SELECT-DATASETS-TO-CLONE": "Wählen Sie aus, welche Datensätze in den neuen DMP aufgenommen werden sollen. Ausgewählte Datensätze werden bearbeitbar sein.", - "SELECT-DATASETS-NONE": "Keine Datensatzbeschreibungen für diesen DMP verfügbar.", - "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", - "TEXT-INFO-PAR": "New datasets can be added to existing DMPs at any time and be described with more than one template. Datasets can also be cloned and re-used in other DMPs as well as be deleted without negatively affecting the DMP as a whole.", + "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": "Descriptions are documented following pre-defined templates which set the content of the descriptions. In {{ APP_NAME }}, a DMP can contain as many descriptions as the entities it documents. Browse ", + "TEXT-INFO-REST": " for a look at entities described in {{ APP_NAME }} DMPs", + "LINK-PUBLIC-DATASETS": "Public Descriptions", + "TEXT-INFO-PAR": "New descriptions can be added to existing DMPs at any time and be described with more than one template. Descriptions can also be cloned and re-used in other DMPs as well as be deleted without negatively affecting the DMP as a whole.", "COLUMNS": { "NAME": "Name", "REFERNCE": "Referenz", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Vorlagen für Datensatzbeschreibung", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Name", "REFERNCE": "Referenz", @@ -941,9 +963,24 @@ "CLONE": "Klon", "NEW-VERSION": "Neue Version", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Alle Vorlagenversionen für Datensatzbeschreibungen", + "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 +999,21 @@ "UNSUCCESSFUL": "Etwas ist schief gelaufen" } }, + "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", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Edit" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Bearbeiten", "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 Description", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Vorlagen", "TEMPLATE": "DMP Vorlage", "DATASET-TEMPLATES": "Zugehörige Vorlagen für Datensatzbeschreibungen", - "SELECT-TEMPLATE": "Select a template to describe your dataset", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "DMP Vorlage", "PROJECT": "Projekt", "GRANT": "Förderung", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Publication Date", "CONTACT": "Contact", "COST": "Costs", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Gehe zu DMP Förderung", @@ -1094,9 +1143,9 @@ "SUCCESSFUL-DOI": "DOI Erstellung erfolgreich", "UNSUCCESSFUL-FINALIZE": "Fertigstellung des DMP fehlgeschlagen" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Verfügbare Datensatzvorlagen", - "TEXT": "Datensatzprofile ausgewählt: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Main info", "FUNDING-INFO": "Funding info", "DATASET-SELECTION": "Dataset selection", - "DATASET-INFO": "Dataset info", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "License info", "DATASET": "Dataset", "PREVIOUS": "Previous", @@ -1138,7 +1187,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, namely dataset descriptions, 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 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "DMP Vorlagen", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Name", "STATUS": "Status", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Veröffentlicht", "LAST-EDITED": "Zuletzt bearbeitet" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Importieren", "UPLOAD-XML-FILE-TITLE": "Vorlage des Datenmanagementplans importieren", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Tags", "SELECT-TAGS": "Tags auswählen", - "LIKE": "Datensatzbeschreibung suchen", - "DRAFT-LIKE": "Search Draft Datasets", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Förderung auswählen", "ROLE": "Rolle", "ORGANIZATION": "Organisation", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Vorlagen für Datensatzbeschreibung auswählen", "RELATED-DATASET-TEMPLATES": "Zugehörige Vorlagen für Datensatzbeschreibung" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Suche", "ROLE": "Rolle", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Neuer Datenmanagementplan", "EDIT": "Bearbeiten", - "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 der Datensatzbeschreibung", - "TITLE": "Title of Dataset", + "TITLE": "Title of Description", "DESCRIPTION": "Beschreibung", "PROFILE": "Vorlage", "URI": "URI", @@ -1298,7 +1356,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." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Bestehenden DMP auswählen" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Administrator", "USER": "Benutzer", "MANAGER": "Manager", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "DATENMANAGEMENTPLÄNE", "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 +1723,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": { @@ -1687,18 +1748,19 @@ "LOG-OUT": "Abmeldung" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Einstellungen", @@ -1745,7 +1807,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", @@ -1914,5 +1976,11 @@ "DRAFT": "Draft", "FINALIZED": "Finalized", "DELETED": "Deleted" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index a608c8ca0..773feb024 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -27,7 +27,11 @@ "UNSUCCESSFUL-LOGOUT": "Unsuccessful Logout", "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", + "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "This template can not deleted, because Descriptions are associated with it", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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", @@ -101,7 +105,7 @@ }, "DMP-TO-DATASET-DIALOG": { "FROM-DMP": "You have successfully created your", - "DMP": "DMP", + "DMP": "Plan", "TO-DATASET": "You will be transferred to the", "DATASET": "Dataset", "EDITOR": "editor", @@ -125,20 +129,21 @@ "GENERAL": "Data Management Plans Creator", "ABOUT": "About", "PRIVACY": "Privacy Policy", - "OPENSOURCE-LICENCES": "Opensource Licences", + "OPENSOURCE-LICENCES": "Opensource Licenses", "TERMS": "Terms Of Service", "COOKIES-POLICY": "Cookies Policy", - "PLANS": "My DMPs", - "EXPLORE-PLANS": "Published DMPs", + "PLANS": "My Plans", + "EXPLORE-PLANS": "Published Plans", "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", - "DATASET-PROFILES": "Dataset Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", + "DATASET-PROFILES": "Description Templates", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Users", "PROFILE": "My Profile", "LOGIN": "Login", @@ -151,17 +156,20 @@ "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", - "DATASET-PROFILES-NEW": "New Dataset Template", - "DATASET-PROFILES-EDIT": "Edit Dataset Template", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", + "DATASET-PROFILES-NEW": "New Description Template", + "DATASET-PROFILES-EDIT": "Edit Description 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", "DATASET-COPY": "Copy Dataset", "DATASET-UPDATE": "Update Dataset", - "DATASET-PROFILES-NEW-VERSION": "New Version of Dataset Template", - "DATASET-PROFILES-CLONE": "New Clone of Dataset Template", + "DATASET-PROFILES-NEW-VERSION": "New Version of Description Template", + "DATASET-PROFILES-CLONE": "New Clone of Description Template", "LANGUAGE-EDITOR": "Language Editor", "GUIDE-EDITOR": "User Guide Editor", "LANGUAGE": "Language", @@ -183,7 +191,8 @@ "SERBIAN": "Serbian", "PORTUGUESE": "Portuguese", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -215,15 +224,15 @@ "TITLE": "{{ APP_NAME_CAPS }}", "GRANTS": "Grants", "GRANT": "Grant", - "DMP": "DMP", - "DMPS": "DMPs", - "MY-DMPS": "MY DMPs", + "DMP": "Plan", + "DMPS": "Plans", + "MY-DMPS": "MY Plans", "DATASETS": "Datasets", - "DATASET": "Dataset", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Explore {{ APP_NAME_CAPS }}", "USERS": "Users", - "DATASETS-ADMIN": "Dataset Templates", - "DMP-PROFILES": "DMP Templates", + "DATASETS-ADMIN": "Description Templates", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "About", "MY-DATASET-DESCRIPTIONS": "MY DATASETS", "DATASET-DESCRIPTION-WIZARD": "Dataset wizard", @@ -233,15 +242,15 @@ "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": "Start new Plan", "START-NEW-DMP-TXT": "Start fresh or continue work in {{ APP_NAME }}! Create a new DMP or upload an existing DMP to {{ APP_NAME }}", "START-WIZARD": "Start wizard", "IMPORT-FROM-FILE": "Import from file", "SEARCH": { "DATASET": "Dataset", - "DMP": "DMP", + "DMP": "Plan", "GRANT": "Grant", "PUBLISHED": "Published" } @@ -251,7 +260,7 @@ "ABOUT": "About", "DASHBOARD": "Home", "DMP": "DATA MANAGEMENT PLANS", - "MY-DMPS": "My DMPs", + "MY-DMPS": "My Plans", "DATASETS": "DATASETS", "GRANTS": "GRANTS", "NEW DATASET": "New Dataset", @@ -259,18 +268,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-DMPS": "Public Plans", + "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,30 +291,34 @@ "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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,9 +328,9 @@ }, "PAGE-INFO": { "PAGE-NAME": "Chapter Name", - "PAGE-NAME-HINT": "Set a name for the dataset chapter.", + "PAGE-NAME-HINT": "Set a name for the description chapter.", "PAGE-DESCRIPTION": "Description", - "PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the chapter is about.", + "PAGE-DESCRIPTION-HINT": "Write a brief description of what the chapter is about.", "ACTIONS": { "CREATE-FIRST-PAGE": "Create the first chapter", "CREATE-NEW-SUBSECTION": "Section", @@ -333,7 +347,7 @@ "SECTION-NAME": "Section Name", "SECTION-NAME-HINT": "Set a name for the section.", "SECTION-DESCRIPTION": "Description", - "SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about.", + "SECTION-DESCRIPTION-HINT": "Write a brief description of what the section is about.", "SECTION": "Section" }, "PAGES": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Label", @@ -589,7 +607,7 @@ }, "ERRORS": { "INVALID-VISIBILITY-RULES": { - "MESSAGE-START": "There were invalid visibilty rules detected in ", + "MESSAGE-START": "There were invalid visibility rules detected in ", "MESSAGE-END": ". Would you like to fix them?", "CONFIRM-YES": "Yes, remove invalid rules", "CONFIRM-NO": "No, keep them.", @@ -605,7 +623,7 @@ } }, "DMP-LISTING": { - "DMP": "DMP", + "DMP": "Plan", "GRANT": "Grant", "TITLE": "Data Management Plans", "OWNER": "Owner", @@ -615,9 +633,9 @@ "FINALIZED": "Finalized", "PUBLISHED": "Published", "VERSION": "Version", - "CONTAINED-DATASETS": "Contained Datasets", - "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", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", + "TEXT-INFO": "Information in a DMP show how descriptions have been collected and/or generated, how they have been processed and analyzed, i.e. using which tools, standards, methodologies etc, but also where and how descriptions 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 Plan looks in practice? Browse Public Plans and", "LINK-ZENODO": "LIBER community in Zenodo", "GET-IDEA": "to get an idea!", "SORT-BY": "Sort by", @@ -642,8 +660,8 @@ "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", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "List All DMP Datasets", "NEW-VERSION": "New Version", "START-NEW-VERSION": "Start New Version", @@ -673,7 +691,7 @@ }, "LEVEL-OF-ACCESS": "Level of Access", "INVOLVED-DATASETS": "Involved Datasets", - "TEMPLATES-INVOLVED": "Dataset Templates Involved" + "TEMPLATES-INVOLVED": "Description Templates Involved" }, "VIEW-ALL-VERSIONS": "All versions of", "EMPTY-LIST": "Nothing here yet." @@ -687,14 +705,14 @@ "TOOLTIP": { "PUBLISHED": "Public access - Closed DMP", "INVOLVED-DATASETS": "Involved Datasets", - "TEMPLATES-INVOLVED": "Dataset Templates Involved" + "TEMPLATES-INVOLVED": "Description Templates Involved" }, "EMPTY-LIST": "Nothing here yet." }, "DMP-UPLOAD": { "TITLE": "Import Data Management Plan", "UPLOAD-BUTTON": "Upload", - "UPLOAD-SUCCESS": "Import was Successfull", + "UPLOAD-SUCCESS": "Import was Successful", "ACTIONS": { "IMPORT": "Import", "CANCEL": "Cancel" @@ -715,7 +733,7 @@ "FIRST-STEP": { "TITLE": "Dataset Information", "DMP": "Data Management Plan", - "PROFILE": "Dataset Template", + "PROFILE": "Description Template", "SUB-TITLE": "Created At: " }, "SECOND-STEP": { @@ -745,7 +763,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?", @@ -755,7 +773,7 @@ "MESSAGES": { "DATASET-NOT-FOUND": "Dataset does not exist", "DATASET-NOT-ALLOWED": "You have no access to this Dataset", - "SUCCESS-UPDATE-DATASET-PROFILE": "Dataset Template updated successfully", + "SUCCESS-UPDATE-DATASET-PROFILE": "Description Template updated successfully", "MISSING-FIELDS": "There are some required fields left unfilled. Please check the DMP and make sure that all required questions are answered and URLs are provided with valid input. (Missing fields are marked in red color)", "NO-FILES-SELECTED": "There is no selected file to upload", "LARGE-FILE-OR-UNACCEPTED-TYPE": "The file is too large or its type is not supported.", @@ -764,8 +782,8 @@ }, "UPLOAD": { "UPLOAD-XML": "Import", - "UPLOAD-XML-FILE-TITLE": "Import Dataset Template", - "UPLOAD-XML-NAME": "Name Of Dataset Template", + "UPLOAD-XML-FILE-TITLE": "Import Description Template", + "UPLOAD-XML-NAME": "Name Of Description Template", "UPLOAD-XML-IMPORT": "File", "UPLOAD-XML-FILE-CANCEL": "Cancel" }, @@ -783,7 +801,7 @@ "COPY": "Copy", "CANCEL": "Cancel", "NEXT": "Next", - "ERROR-MESSAGE": "Does not contain this Dataset Template" + "ERROR-MESSAGE": "Does not contain this Description Template" }, "LOCKED":{ "TITLE":"Dataset is locked", @@ -794,7 +812,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "DΜP Authors", "RESEARCHERS": "Researchers", - "DATASETS-USED": "Datasets used", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Collaborators", "PUBLIC": "Public", "PRIVATE": "Private", @@ -805,7 +823,7 @@ "TOOLTIP": { "LEVEL-OF-ACCESS": "Level of Access", "INVOLVED-DATASETS": "Involved Datasets", - "TEMPLATES-INVOLVED": "Dataset Templates Involved" + "TEMPLATES-INVOLVED": "Description Templates Involved" }, "ERROR": { "DELETED-DMP": "The requested DMP is deleted", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "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" @@ -845,14 +867,14 @@ } }, "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.", - "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", - "TEXT-INFO-PAR": "New datasets can be added to existing DMPs at any time and be described with more than one template. Datasets can also be cloned and re-used in other DMPs as well as be deleted without negatively affecting the DMP as a whole.", + "TITLE": "Datensatzbeschreibungen", + "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": "Descriptions are documented following pre-defined templates which set the content of the descriptions. In {{ APP_NAME }}, a DMP can contain as many descriptions as the entities it documents. Browse ", + "TEXT-INFO-REST": " for a look at entities described in {{ APP_NAME }} DMPs", + "LINK-PUBLIC-DATASETS": "Public Descriptions", + "TEXT-INFO-PAR": "New descriptions can be added to existing DMPs at any time and be described with more than one template. Descriptions can also be cloned and re-used in other DMPs as well as be deleted without negatively affecting the DMP as a whole.", "COLUMNS": { "NAME": "Name", "REFERNCE": "Reference", @@ -865,7 +887,7 @@ "FINALIZED": "Finalized", "LAST-EDITED": "Last Edited", "ACTIONS": "Actions", - "DMP": "DMP", + "DMP": "Plan", "PROFILE": "Template", "DATAREPOSITORIES": "Data Repositories", "REGISTRIES": "Registries", @@ -892,9 +914,9 @@ "DRAFT": "Private access - Editable Dataset", "FINALIZED": "Private access - Closed Dataset" }, - "DMP": "DMP", + "DMP": "Plan", "GRANT": "Grant", - "TEMPLATES-INVOLVED": "Dataset Template", + "TEMPLATES-INVOLVED": "Description Template", "VERSION": "DMP Version", "PART-OF": "Part of", "TO-DMP": "To DMP", @@ -906,14 +928,14 @@ "TITLE": "Published Datasets", "TOOLTIP": { "FINALIZED": "Private access - Closed Dataset", - "DMP": "DMP", + "DMP": "Plan", "GRANT": "Grant", - "TEMPLATES-INVOLVED": "Dataset Template" + "TEMPLATES-INVOLVED": "Description Template" }, "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Dataset Templates", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Name", "REFERNCE": "Reference", @@ -928,7 +950,7 @@ "DESCRIPTION": "Description", "CREATED": "Created", "ACTIONS": "Actions", - "DMP": "DMP", + "DMP": "Plan", "PROFILE": "Template", "DATAREPOSITORIES": "Data Repositories", "REGISTRIES": "Registries", @@ -941,9 +963,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": { @@ -955,16 +992,28 @@ }, "PLACEHOLDER": "Dataset Title", "DATASET-PROFILE": { - "SELECT": "Select Dataset Template" + "SELECT": "Select Description Template" }, "SNACK-BAR": { "SUCCESSFUL-CREATION": "Imported Successfully", "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", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Edit" }, "FIELDS": { @@ -1022,9 +1071,9 @@ "TITLE": { "NEW": "New Data Management Plan", "EDIT": "Edit", - "EDIT-DMP": "Editing DMP", - "ADD-DATASET": "Adding dataset", - "EDIT-DATASET": "Editing Dataset", + "EDIT-DMP": "Editing Plan", + "ADD-DATASET": "Adding description", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Clone", "NEW-VERSION": "New Version", "CREATE-DATASET": "Creating Dataset", @@ -1039,12 +1088,12 @@ "ORGANISATIONS": "Organizations", "ORGANISATIONS-HINT": "Add here the names of the organizations contributing to the creation and revision of the DMPs", "RESEARCHERS": "Researchers", - "RESEARCHERS-HINT": "Add here the names of people that have produced, processed, analysed the data described in the DMP. ", + "RESEARCHERS-HINT": "Add here the names of people that have produced, processed, analyzed the data described in the DMP. ", "AUTHORS": "Authors", "TEMPLATES": "Templates", "TEMPLATE": "DMP Template", - "DATASET-TEMPLATES": "Related Dataset Templates", - "SELECT-TEMPLATE": "Select a template to describe your dataset", + "DATASET-TEMPLATES": "Related Description Templates", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "DMP Template", "PROJECT": "Project", "GRANT": "Grant", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Publication Date", "CONTACT": "Contact", "COST": "Costs", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Go To DMP Grant", @@ -1094,9 +1143,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,21 +1157,21 @@ "MAIN-INFO": "Main info", "FUNDING-INFO": "Funding", "DATASET-SELECTION": "Dataset selection", - "DATASET-INFO": "Dataset info", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "License", - "DATASET": "Dataset", + "DATASET": "Description", "PREVIOUS": "Previous", "NEXT": "Next" }, "MAIN-INFO": { - "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.", + "INTRO": "A Plan 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.", "HINT": "A brief description of what the DMP is about, it’s scope and objectives.", "TYPING": "Type more letters of the name so its more possible to find the correct one.", "UNIQUE-IDENTIFIER": "Unique Identifier", "RESEARCHER-IDENTIFIER-EXISTS": "Researcher identifier already exists.", - "ORGANISATION-IDENTIFIER-EXSTS": "Organisation identifier already exists.", + "ORGANISATION-IDENTIFIER-EXSTS": "Organization identifier already exists.", "IDENTIFIER-EXISTS-RESEARCHER-LIST": "This identifier is already used by a researcher in the researchers list.", - "IDENTIFIER-EXISTS-ORGANISATION-LIST": "This identifier is already used by an organisation in the organisations list.", + "IDENTIFIER-EXISTS-ORGANISATION-LIST": "This identifier is already used by an organization in the organizations list.", "SAVE":"Save", "CANCEL": "Cancel" }, @@ -1135,18 +1184,18 @@ "IDENTIFIER-PROJECT-EXISTS": "A project with the given identifier exists." }, "DATASET-INFO": { - "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.", + "INTRO": "A Plan 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": "Descriptions 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", + "INTRO": "Each DMP can contain specific license information 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", "HINT": "Assign a license to your DMP by selecting the most appropriate from the list.", "TYPING": "Type more letters of the name so its more possible to find the correct one." }, "DATASET-DESCRIPTION": { - "INTRO": "Ιn general terms, your research data should be 'fair', that is findable, accessible, interoperable and re-usable. these principles precede implementation choices and do not necessarily suggest any specific technology, standard, or implementation-solution. this template is not intended as a strict technical implementation of the fair principles, it is rather inspired by fair as a general concept." + "INTRO": "In general terms, your research data should be 'fair', that is findable, accessible, interoperable and re-usable. these principles precede implementation choices and do not necessarily suggest any specific technology, standard, or implementation-solution. this template is not intended as a strict technical implementation of the fair principles, it is rather inspired by fair as a general concept." }, "CHANGES": "unsaved changes", "CLONE-DIALOG": { @@ -1160,8 +1209,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", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Published", "LAST-EDITED": "Last Edited" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Import", "UPLOAD-XML-FILE-TITLE": "Import Data Management Plan Template", @@ -1218,8 +1272,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", @@ -1230,8 +1284,8 @@ "RELATED-DMP": "Related DMPs", "SELECT-COLLABORATORS": "Select Collaborators", "RELATED-COLLABORATORS": "Related Collaborators", - "SELECT-DATASET-TEMPLATES": "Select Dataset Templates", - "RELATED-DATASET-TEMPLATES": "Related Dataset Templates", + "SELECT-DATASET-TEMPLATES": "Select Description Templates", + "RELATED-DATASET-TEMPLATES": "Related Description Templates", "ALL-VERSIONS": "From All Versions" }, "DMP": { @@ -1240,8 +1294,12 @@ "SELECT-GRANTS": "Select Grants", "SELECT-COLLABORATORS": "Select Collaborators", "RELATED-COLLABORATORS": "Related Collaborators", - "SELECT-DATASET-TEMPLATES": "Select Dataset Templates", - "RELATED-DATASET-TEMPLATES": "Related Dataset Templates" + "SELECT-DATASET-TEMPLATES": "Select Description Templates", + "RELATED-DATASET-TEMPLATES": "Related Description Templates" + }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" }, "USERS": { "LABEL": "Search", @@ -1255,16 +1313,16 @@ "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", - "DMP": "DMP", + "DMP": "Plan", "SELECT-DMP": "Select DMP", "DATAREPOSITORIES": "Data Repositories", "REGISTRIES": "Registries", @@ -1298,16 +1356,16 @@ "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." }, "VERSION-DIALOG": { "ABOUT": "Versioning is automated.", - "QUESTION": "It seems your Dataset Template is outdated. Do you want to update it to the latest version?" + "QUESTION": "It seems your Description Template is outdated. Do you want to update it to the latest version?" }, "ERRORS":{ - "ERROR-OCCURED": "An error occured.", + "ERROR-OCCURED": "An error occurred.", "MESSAGE": "Message: " }, "QUESTION": { @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1324,17 +1386,17 @@ "SAVE": "Save" }, "FIRST-STEP": { - "TITLE": "DMP", + "TITLE": "Plan", "PLACEHOLDER": "Pick an existing DMP" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Admin", "USER": "User", "MANAGER": "Manager", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1443,7 +1505,7 @@ "DATASET-IDENTIFIER": "Dataset Identifier", "CURRENCY": "Currency", "VALIDATION": "Validator", - "OTHER": "Other", + "OTHER": "Custom", "SELECT": "Select" }, "DATASET-PROFILE-UPLOAD-TYPE": { @@ -1460,7 +1522,7 @@ }, "DATASET-PROFILE-INTERNAL-DMP-ENTITIES-TYPE": { "RESEARCHERS": "Researchers", - "DMPS": "DMPs", + "DMPS": "Plans", "DATASETS": "Datasets", "EXTERNAL-SOURCE-HINT": "List of values provided by external source(s)" }, @@ -1511,7 +1573,7 @@ }, "DMP-WIZARD": { "FIRST-STEP": { - "DMP": "DMP Editor", + "DMP": "Plan Editor", "DATASETS": "Datasets" }, "ACTIONS": { @@ -1599,7 +1661,7 @@ "MAIN-CONTENT": "" }, "OPENSOURCE-LICENCES": { - "TITLE": "Opensource licences", + "TITLE": "Opensource licenses", "MAIN-CONTENT": "" }, "TERMS-OF-SERVICE": { @@ -1631,9 +1693,9 @@ "DASHBOARD": { "MY-GRANTS": "My Grants", "GRANTS": "Grants", - "MY-DMPS": "My DMPs", + "MY-DMPS": "My Plans", "TITLE": "What is {{ APP_NAME_CAPS }}?", - "DMP-QUESTION": "What is a DMP in {{ APP_NAME_CAPS }}?", + "DMP-QUESTION": "What is a Plan in {{ APP_NAME_CAPS }}?", "INFO-TEXT": "{{ APP_NAME_CAPS }} is an open extensible service that simplifies the management, validation, monitoring and maintenance and of Data Management Plans. It allows actors (researchers, managers, supervisors etc) to create actionable DMPs that may be freely exchanged among infrastructures for carrying out specific aspects of the Data management process in accordance with the intentions and commitment of Data owners.", "INFO-DMP-TEXT": "A Data Management Plan (DMP) is a living document describing the datasets that are generated and/ or re-used during and after a research lifetime. DMPs aim to provide researchers with essential information to re-produce, re-distribute and re-purpose research results thus assuring for their validity and exploitation.", "NEW-QUESTION": "New with DMPs? Visit", @@ -1641,33 +1703,32 @@ "OPEN-AIR-GUIDE": "OpenAIRE’s Guide for Researchers", "LEARN-MORE": "to learn more about how to create one!", "ORGANIZATIONS": "Related Organizations", - "DMPS": "DMPs", + "DMPS": "Plans", "MY-DATASETS": "My Datasets", "DATASETS": "Datasets", "SEARCH": "SEARCH...", "DATA-MANAGEMENT-PLANS": "DATA MANAGEMENT PLANS", "PERSONAL-USAGE": "Personal Usage", "PUBLIC-USAGE": "Public Usage", - "DATASET-DESCRIPTIONS": "Datasets", - "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Datasets", - "PUBLIC-DMPS": "Public DMPs", + "DESCRIPTIONS": "Descriptions", + "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Descriptions", + "PUBLIC-DMPS": "Public Plans", "PUBLIC-DATASETS": "Public Datasets", - "RELATED-ORGANISATIONS": "Related Organisations", + "RELATED-ORGANISATIONS": "Related Organizations", "DRAFTS": "Drafts", "ALL": "All", "EMPTY-LIST": "Nothing here yet.", "LATEST-ACTIVITY": "Latest Activity", - "DMP-ABOUT-BEG": "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, namely", + "DMP-ABOUT-BEG": "A Plan in {{ APP_NAME }} consists of key information about research, such as purpose, objectives and researchers involved, but also about documentation of research entities, namely", "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": { "DMP": "This is your dashboard. You can view and edit all DMPs that you have either contributed to or created yourself.", - "START-NEW": "Create your DMP with Start new DMP.", + "START-NEW": "Create your Plan with Start new Plan.", "IMPORT-DMP": "You can import a DMP", "START-WIZARD": "or create new in {{ APP_NAME }}.", "DATASET": "This is your dashboard. You can view and edit all Datasets that you have either contributed to or created yourself.", @@ -1677,7 +1738,7 @@ }, "ADD-NEW-DATASET": { "OPTIONS-NOT-ENOUGH": "Are those options not enough?", - "START-NEW-DMP": "Start new DMP" + "START-NEW-DMP": "Start new Plan" } }, "USER-DIALOG": { @@ -1687,18 +1748,19 @@ "LOG-OUT": "Log Out" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Settings", @@ -1745,7 +1807,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", @@ -1807,7 +1869,7 @@ } }, "DMP-FINALISE-DIALOG": { - "DMP": "DMP", + "DMP": "Plan", "DATASETS": "Datasets", "EMPTY": "No Datasets for this DMP so far", "SUBMIT": "Submit", @@ -1870,15 +1932,15 @@ }, "SECOND-STEP": { "TITLE": "DMP Profile", - "ABOUT": "A Data Management Plan consists of a set of questions that you should answer with a level of detail appropriate to the grant or with relevance to the purpose that you are creating the DMP. Contents of each DMP vary depending on the selected Dataset Template(s) which contain(s) a set of tailored questions in response to policy requirements of funders, institutions, research communities.", + "ABOUT": "A Data Management Plan consists of a set of questions that you should answer with a level of detail appropriate to the grant or with relevance to the purpose that you are creating the DMP. Contents of each DMP vary depending on the selected Description Template(s) which contain(s) a set of tailored questions in response to policy requirements of funders, institutions, research communities.", "NEW-TITLE": "", "DMP-NAME": "DMP For Grant : ", "FIELDS": { "NAME": "Title of the DMP", "DESCRIPTION": "Summary", "DESCRIPTION-HINT": "Briefly describe the context and purpose of the DMP", - "PROFILE": "Dataset Template", - "PROFILE-HINT": "Select a template to describe your Dataset(s). If you want to select multiple Dataset Templates use \"New DMP (Expert)\". You can also add new Datasets at any time after the DMP creation.", + "PROFILE": "Description Template", + "PROFILE-HINT": "Select a template to describe your Dataset(s). If you want to select multiple Description Templates use \"New DMP (Expert)\". You can also add new Datasets at any time after the DMP creation.", "HELP": "If you can't find a template or if you want to create a personalized template for your institution, research community or training needs, please contact us." } }, @@ -1915,5 +1977,19 @@ "DRAFT": "Draft", "FINALIZED": "Finalized", "DELETED": "Deleted" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" + }, + "NEW-RELEASE-NOTIFICATION": { + "TITLE": "New ARGOS Release!", + "HINT": "Discover the all-new Argos version", + "BODY": "Discover the latest enhancements and improvements with our brand-new Argos release! Use the Default Blueprint to create plans that include funders information. Contact us to create Blueprints for institutional plans that connect to local services or for training activities. Adopt the output management plan as an overarching plan that combines different templates, e.g. data and software. Don’t miss out – explore now!", + "ACTIONS": { + "LEARN-MORE": "Learn more" + } } } diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index b970ca792..7059836c3 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Inicio de sesión fallido", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Borrado correcto", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Esta plantilla no se puede borrar, porque está asociada a descripciones del dataset", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Borrado correcto", "UNSUCCESSFUL-DELETE": "Borrado fallido", "UNSUCCESSFUL-EMAIL-SEND": "Fallo enviando el correo", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "(Asistente) Nuevo PGD", "PLANS-NEW": "Nuevo PGD (Experto)", "DMP-NEW": "Nuevo PGD", - "DATASETS": "Mis descripciones del dataset", - "EXPLORE": "Descripciones del dataset publicadas", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Añadir una descripción del dataset (Asistente)", "GRANTS": "Mis subvenciones", - "DMP-PROFILES": "Plantillas del PGD", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Dataset Description Templates", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Usuarios", "PROFILE": "Mi perfil", "LOGIN": "Iniciar sesión", @@ -151,10 +156,13 @@ "DATASET-NEW": "Nueva descripción del dataset", "GRANT-NEW": "Nueva subvención", "GRANT-EDIT": "Ver/Editar subvención", - "DMP-PROFILE-NEW": "Nueva plantilla del PGD", - "DMP-PROFILE-EDIT": "Editar la plantilla del PGD", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Nueva plantilla de descripción del dataset", "DATASET-PROFILES-EDIT": "Editar plantilla de descripción del dataset", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Resumen del PGD", "DATASET-PUBLIC-EDIT": "Ver el dataset publicado", "DMP-PUBLIC-EDIT": "Ver el PGD publicado", @@ -183,7 +191,8 @@ "SERBIAN": "Serbio", "PORTUGUESE": "Portugués", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "PGDs", "MY-DMPS": "MIS PGDs", "DATASETS": "Descripciones del dataset", - "DATASET": "Dataset", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Explorar {{ APP_NAME_CAPS }}", "USERS": "Usuarios", "DATASETS-ADMIN": "Plantilla del dataset", - "DMP-PROFILES": "Plantillas del PGD", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Acerca de", "MY-DATASET-DESCRIPTIONS": "MIS DESCRIPCIONES DEL DATASET", "DATASET-DESCRIPTION-WIZARD": "Asistente de la descripción del dataset", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Asistente PGD", "DATASET-TEMPLATES": "PLANTILLAS DEL DATASET", "TEMPLATE": "PLANTILLA", - "DMP-TEMPLATES": "PLANTILLAS PGD", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "USUARIOS", "START-NEW-DMP": "Iniciar un nuevo PGD", "START-NEW-DMP-TXT": "Un Asistente especial está disponible para ayudarle a crear su PGD de forma sencilla. Tiene una guía paso a paso con toda la información necesaria para crear un PGD facilmente.", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Añadir una descripción del dataset (Asistente)", "ADD-EXPERT": "Nuevo PGD (Experto)", "MY-DATASET-DESC": "Mis descripciones del dataset", - "MY-DATASETS": "Mis descripciones del dataset", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Mis subvenciones", "HISTORY": "HISTORIAL", "HISTORY-VISITED": "VISITADO POR ÚLTIMA VEZ", "HISTORY-EDITED": "EDITADO POR ÚLTIMA VEZ", "PUBLIC": "PUBLICADO", "PUBLIC-DMPS": "PGDs publicado", - "PUBLIC-DESC": "Descripciones del dataset publicadas", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "CUENTA", "ADMIN": "ADMINISTRADOR", - "DATASET-TEMPLATES": "Plantilla de descripción del dataset", - "DMP-TEMPLATES": "Plantillas del PGD", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Usuarios", "LANGUAGE-EDITOR": "Editor de Idiomas", "GUIDE-EDITOR": "Editor de la guía de usuario", @@ -281,24 +291,28 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Nuevo cliente API", - "NEW-PROFILE": "Nueva plantilla de descripción del dataset", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nueva verisón de ", "NEW-PROFILE-CLONE": "Nueva copia de " }, "FIELDS": { - "DATASET-TITLE": "Nombre de la plantilla de descripción del dataset", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Descripción", "ROLES": "Funciones" }, "STEPS": { "GENERAL-INFO": { "TITLE": "Información General", - "DATASET-TEMPLATE-NAME": "Nombre de la plantilla del Dataset", - "DATASET-TEMPLATE-NAME-HINT": "Un título que determine la plantilla del Dataset.", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Descripción", "DATASET-TEMPLATE-DESCRIPTION-HINT": "Una breve descripción acerca del Dataset, su alcance y objetivos.", - "DATASET-TEMPLATE-LANGUAGE": "Idioma de la plantilla del Dataset", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Seleccione un idioma", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", @@ -314,7 +328,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Nombre del capítulo", - "PAGE-NAME-HINT": "Poner un nombre al capítulo del dataset.", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Descripción", "PAGE-DESCRIPTION-HINT": "Escribir una breve descripción de lo que trata el capítulo.", "ACTIONS": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Fuente", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Optiones principales", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Campo de entrada para fecha", "FIELD-DATE-PICKER-PLACEHOLDER": "Marcador de entrada", "FIELD-DATE-PICKER-LABEL": "Etiqueta", @@ -615,7 +633,7 @@ "FINALIZED": "Finalized", "PUBLISHED": "Published", "VERSION": "Versión", - "CONTAINED-DATASETS": "Descripciones de los datasets incluídos", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "La información en un PGD muestra cómo los datasets han sido creados y/o generados, cómo han sido procesados y analizados (e.j: con qué herramientas, stándares, metodologías, etc.) y también dónde y cómo se hacen las copias de seguridad, son publicados y preservados, incluyendo los costes asociados con el personal dedicado a la curación de datos, actividades de administración o los costes para adquirir o crear servicios de administración de datos.", "TEXT-INFO-QUESTION": "¿No está seguro de cómo se verá un dataset en la práctica?. Navegue por los PGDs publicados y", "LINK-ZENODO": "Comunidad LIBER en Zenodo", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Invitar a autores", "INVITE-SHORT": "Invitar", "ADD-DATASET": "Añadir la descripción del dataset al PGD", - "ADD-DATASET-DESCRIPTION": "Añadir la descripción del dataset", - "ADD-DATASET-SHORT": "Añadir dataset", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Listar todas las descripciones de los dataset", "NEW-VERSION": "Nueva versión", "START-NEW-VERSION": "Iniciar una nueva versión", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Descargar PDF", "DOWNLOAD-XML": "Descargar XML", "DOWNLOAD-DOCX": "Descargar DOCX", - "COPY-DATASET": "Copiar la descripción del dataset", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Plantilla de modificación", "VALIDATE":"Validar", "UNDO-FINALIZATION-QUESTION" :"Deshacer finalización?", @@ -794,7 +812,7 @@ "GRANT": "Subvención", "DMP-AUTHORS": "Autores del PGD", "RESEARCHERS": "Investigadores", - "DATASETS-USED": "Datasets usados", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Colaboradores", "PUBLIC": "Publicado", "PRIVATE": "Privado", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "PGD bloqeuado", "MESSAGE":"Alguien más está modificando el PGD. Si quiere modificarlo o visualizarlo, por favor, inténtelo más tarde." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Descripción de los autores del dataset", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "El dataset pedido ha sido eliminado", "FORBIDEN-DATASET": "No tiene permisos para acceder a este Dataset" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Descripciones del dataset", - "DATASET-DESCRIPTION": "Descripción del dataset", - "SELECT-DATASETS-TO-CLONE": "Seleccione qué datasets incluye en el nuevo PDG. Los datasets será editables.", - "SELECT-DATASETS-NONE": "Las descripciones del dataset no está disponibles para este PGD.", + "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": "Los datasets se documentan siguiendo plantillas predefinidas con el contenido de las descripciones de los datasets. En {{ APP_NAME }} un PGD puede contener tantas descripciones de datasets como datasets documentados. Navegar ", "TEXT-INFO-REST": " para una mirada a los datasets descritos en los PGDs de {{ APP_NAME }}", "LINK-PUBLIC-DATASETS": "Descripciones de datasets publicados", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Nada todavía por aquí." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Plantillas de descripción del dataset", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Nombre", "REFERNCE": "Referencia", @@ -941,9 +963,24 @@ "CLONE": "Clonar", "NEW-VERSION": "Nueva versión", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Todas las versiones de las plantillas de descripción del dataset", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Borrar", - "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 +999,21 @@ "UNSUCCESSFUL": "Algo salió mal" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Nueva plantilla PGD", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Editar" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Editar", "EDIT-DMP": "Editando PGD", "ADD-DATASET": "Añadiendo dataset", - "EDIT-DATASET": "Editando Dataset", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Clonar", "NEW-VERSION": "Nueva versión", "CREATE-DATASET": "Creando una descripción del Dataset", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Plantillas", "TEMPLATE": "Plantilla del PGD", "DATASET-TEMPLATES": "Plantillas para la descripción de dataset relacionados", - "SELECT-TEMPLATE": "Seleccione una plantilla para describir su dataset", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Plantilla del PGD", "PROJECT": "Proyecto", "GRANT": "Subvención", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Fecha de publicación", "CONTACT": "Contacto", "COST": "Costes", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Ir a las subvención del PGD", @@ -1094,9 +1143,9 @@ "SUCCESSFUL-DOI": "Creación del DOI correcta", "UNSUCCESSFUL-FINALIZE": "Fallo en la finalización del PGD" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Plantilla del dataset disponible", - "TEXT": "Perfil del dataset seleccionado: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Información principal", "FUNDING-INFO": "Información sobre financiación", "DATASET-SELECTION": "Selección de datasets", - "DATASET-INFO": "Información sobre el dataset", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "License info", "DATASET": "Dataset", "PREVIOUS": "Anterior", @@ -1138,7 +1187,7 @@ "INTRO": "Un PGD en {{ APP_NAME }} consiste en la información clave sobre una investigación. Para este propósito se incluyen además de objetivos e investigaciones la documentación sobre los datasets de la investigación. En concreto la descripción de los dataset que resalta los pasos seguidos y los medios usados en las actividades administrativas.", "SECOND-INTRO": "Los datasets se documentan siguiendo plantillas predefinadas con el contenido de la descripción de los datasets. En {{ APP_NAME }} un PGD puede incluir tantas descripciones de datasets como datasets se documenten.", "FIND": "¿No se encontró el correcto?", - "HINT": "Seleccione una plantilla para descrbir sus datasets. Puede seleccionar una o más plantillas." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Cada PGD puede contener información específica sobre licencias, su visibidad y disponibilidad, que puede determinar quien puede ver sus dataset y cuánto tiempo estará restringido el acceso a los datos", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Plantilla del PGD", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Nombre", "STATUS": "Estado", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Publicado", "LAST-EDITED": "Última edición" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Importar", "UPLOAD-XML-FILE-TITLE": "Importar plantilla del Plan de Gestión de Datos", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Etiquetas", "SELECT-TAGS": "Etiquetas seleccionadas", - "LIKE": "Buscar descripciones de los datasets", - "DRAFT-LIKE": "Buscar descripciones de los datasets en borrador", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Seleccionar subvención", "ROLE": "Función", "ORGANIZATION": "Organización", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Seleccionar la plantilla de descripción del dataset", "RELATED-DATASET-TEMPLATES": "Plantilla de descripción del Dataser relacionada" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Búsqueda", "ROLE": "Función", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Nuevo Plan de Gestión de Datos", "EDIT": "Editar", - "INTRO": "Está usando el editor del Dataset. Responda aquí las cuestiones que describen sus acvtividades de gestión de datos.", - "INTRO-TIP": "Sugerencia: Añadir nuevos datasets para describir distintos tipos de datos o datos multidisciplinares para evitar mezclar información." + "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": "Nombre de la descripción del dataset", - "TITLE": "Título del Dataset", + "TITLE": "Title of Description", "DESCRIPTION": "Descripción", "PROFILE": "Plantilla", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Facilite una URL" }, "HINT": { - "DESCRIPTION": "Describa brevemente el contexto y propósito del Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Una breve descripción sobre el ", "TITLE-REST": " su alcance y objetivos." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "Ver más", "VIEW-LESS": "Ver menos" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Seleccione un PGD existente" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Administrador", "USER": "Usuario", "MANAGER": "Director", - "DATASET-TEMPLATE-EDITOR": "Editor de planitllas de Dataset" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLANES DE GESTIÓN DE DATOS", "PERSONAL-USAGE": "Uso personal", "PUBLIC-USAGE": "Public Usage", - "DATASET-DESCRIPTIONS": "Descripciones de los datasets", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Descripciones de los datasets", "PUBLIC-DMPS": "PGDs públicos", "PUBLIC-DATASETS": "Descripciónes de Dataset Públicos", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": ", esto resalta los pasos seguidos y los medios usados en las actividades de administración de datos.", "SELECT-DMP": "Select a DMP for your Dataset", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Añadir la descripción del dataset", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Añadir un dataset", "ADD-DMP-DESCRIPTION": "Añadir la descripción de un PGD" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Cerrar la sesión" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Configuración", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Borrador", "FINALIZED": "Finalizado", "DELETED": "Eliminado" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index e1846708d..c96f745e6 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -28,10 +28,14 @@ "UNSUCCESSFUL-LOGIN": "Αποτυχημένη σύνδεση", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Επιτυχής διαγραφή", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Το template δεν μπορεί να διαγραφεί, επειδή οι περιγραφές των συνόλων δεδομένων σχετίζονται με αυτό", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Επιτυχής διαγραφή", "UNSUCCESSFUL-DELETE": "Αποτυχημένη διαγραφή", "UNSUCCESSFUL-EMAIL-SEND": "Αποτυχία αποστολής email", - "UNSUCCESSFUL-REMOVE-TEMPLATE": "Αποτυχία αφαίρεσης του template, ένα ή παραπάνω σύνολα δεδομένων του συγκρεκριμένου Σχεδίου Διαχείρισης Δεδομένωνω χρησιμοποιούν αυτό το template" + "UNSUCCESSFUL-REMOVE-TEMPLATE": "Αποτυχία αφαίρεσης του template, ένα ή παραπάνω σύνολα δεδομένων του συγκεκριμένου Σχεδίου Διαχείρισης Δεδομένων χρησιμοποιούν αυτό το template" }, "ERRORS": { "HTTP-REQUEST-ERROR": "Παρουσιάστηκε μη αναμενόμενο σφάλμα" @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Νέο Σχέδιο Διαχείρισης Δεδομένων (Wizard)", "PLANS-NEW": "Νέο Σχέδιο Διαχείρισης Δεδομένων (Expert)", "DMP-NEW": "Νέο Σχέδιο Διαχείρισης Δεδομένων", - "DATASETS": "Οι Περιγραφές Συνόλων Δεδομένων Μου", - "EXPLORE": "Δημοσιευμένες Περιγραφές Συνόλων Δεδομένων", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Προσθήκη Περιγραφής Συνόλου Δεδομένων (Wizard)", "GRANTS": "Οι επιχορηγήσεις Μου", - "DMP-PROFILES": "Templates Σχεδίων Διαχείρισης Δεδομένων", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Templates Περιγραφών Συνόλων Δεδομένων", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Χρήστες", "PROFILE": "Το προφίλ μου", "LOGIN": "Σύνδεση", @@ -151,10 +156,13 @@ "DATASET-NEW": "Νέα Περιγραφή Συνόλου Δεδομένων", "GRANT-NEW": "Νέα Επιχορήγηση", "GRANT-EDIT": "Προβολή / Επεξεργασία Επιχορήγησης", - "DMP-PROFILE-NEW": "Νέο template Σχεδίου Διαχείρισης Δεδομένων", - "DMP-PROFILE-EDIT": "Επεξεργασία template Σχεδίου Διαχείρισης Δεδομένων", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Νέο template Περιγραφής Συνόλου Δεδομένων", "DATASET-PROFILES-EDIT": "Επεξεργασία template Περιγραφής Συνόλου Δεδομένων", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Επισκόπηση Δημοσιευμένου Σχεδίου Διαχείρισης Δεδομένων", "DATASET-PUBLIC-EDIT": "Προβολή Δημοσιευμένης Περιγραφής Συνόλου Δεδομένων", "DMP-PUBLIC-EDIT": "Προβολή Δημοσιευμένου Σχεδίου Διαχείρισης Δεδομένων", @@ -183,7 +191,8 @@ "SERBIAN": "Σερβικά", "PORTUGUESE": "Πορτογαλικά", "CROATIAN": "Κροατικά", - "POLISH": "Πολωνικά" + "POLISH": "Πολωνικά", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "Σχέδια Διαχείρισης Δεδομένων", "MY-DMPS": "Τα Σχέδια Διαχείρισης Δεδομένων Μου", "DATASETS": "Περιγραφές Συνόλων Δεδομένων", - "DATASET": "Σύνολο Δεδομένων", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Εξερευνήστε το {{ APP_NAME_CAPS }}", "USERS": "Χρήστες", "DATASETS-ADMIN": "Templates Συνόλων Δεδομένων", - "DMP-PROFILES": "Templates Σχεδίων Διαχείρισης Δεδομένων", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Σχετικά", "MY-DATASET-DESCRIPTIONS": "ΤΑ ΣΧΕΔΙΑ ΔΙΑΧΕΙΡΙΣΗΣ ΔΕΔΟΜΕΝΩΝ ΜΟΥ", "DATASET-DESCRIPTION-WIZARD": "Wizard Περιγραφών Συνόλων Δεδομένων", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Wizard Σχεδίων Διαχείρισης Δεδομένων", "DATASET-TEMPLATES": "TEMPLATES ΣΥΝΟΛΩΝ ΔΕΔΟΜΕΝΩΝ", "TEMPLATE": "TEMPLATE", - "DMP-TEMPLATES": "TEMPLATES ΣΧΕΔΙΩΝ ΔΙΑΧΕΙΡΙΣΗΣ ΔΕΔΟΜΕΝΩΝ", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "ΧΡΗΣΤΕΣ", "START-NEW-DMP": "Ξεκινήστε νέο DMP", "START-NEW-DMP-TXT": "Ένας ειδικός wizard δημιουργήθηκε για να σας βοηθήσει να συντάξετε το δικό σας Σχέδιο Διαχείρισης Δεδομένων εύκολα. Παρέχει έναν βήμα προς βήμα οδηγό περιλαμβάνοντας όλες τις απαραίτητες πληροφορίες για να δημιουργήσετε ένα Σχέδιο Διαχείρισης Δεδομένων εύκολα.", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Προσθήκη Περιγραφής Συνόλου Δεδομένων (Wizard)", "ADD-EXPERT": "Νέο Σχέδιο Διαχείρισης Δεδομένων(Expert)", "MY-DATASET-DESC": "Οι δικές μου Περιγραφές Συνόλου Δεδομένων", - "MY-DATASETS": "Περιγραφές Δεδομένων μου", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Οι επιχορηγήσεις μου", "HISTORY": "ΙΣΤΟΡΙΚΟ", "HISTORY-VISITED": "ΤΕΛΕΥΤΑΙΑ ΕΠΙΣΚΕΨΗ", "HISTORY-EDITED": "ΤΕΛΕΥΤΑΙΑ ΕΠΕΞΕΡΓΑΣΙΑ", "PUBLIC": "ΔΗΜΟΣΙΕΥΜΕΝΑ", "PUBLIC-DMPS": "Δημοσιευμένα Σχέδια Διαχείρισης Δεδομένων", - "PUBLIC-DESC": "Δημοσιευμένες Περιγραφές Συνόλου Δεδομένων", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "ΛΟΓΑΡΙΑΣΜΟΣ", "ADMIN": "ΔΙΑΧΕΙΡΙΣΤΗΣ", - "DATASET-TEMPLATES": "Templates Περιγραφών Συνόλου Δεδομένων", - "DMP-TEMPLATES": "Templates Σχεδίων Διαχείρισης Δεδομένων", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Users", "LANGUAGE-EDITOR": "Επεξεργαστής Γλώσσας", "GUIDE-EDITOR": "Οδηγός Χρήστη", @@ -281,30 +291,34 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Νέο API", - "NEW-PROFILE": "Νέο Template Περιγραφής Συνόλου Δεδομένων", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Νέα Έκδοση", "NEW-PROFILE-CLONE": "Νέος Κλώνος" }, "FIELDS": { - "DATASET-TITLE": "Template Περιγραφής Συνόλου Δεδομένων", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Περιγραφή", "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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,9 +328,9 @@ }, "PAGE-INFO": { "PAGE-NAME": "Chapter Name", - "PAGE-NAME-HINT": "Set a name for the dataset chapter.", + "PAGE-NAME-HINT": "Set a name for the description chapter.", "PAGE-DESCRIPTION": "Description", - "PAGE-DESCRIPTION-HINT": "Write a brief desciption of what the chapter is about.", + "PAGE-DESCRIPTION-HINT": "Write a brief description of what the chapter is about.", "ACTIONS": { "CREATE-FIRST-PAGE": "Create the first chapter", "CREATE-NEW-SUBSECTION": "Section", @@ -333,7 +347,7 @@ "SECTION-NAME": "Section Name", "SECTION-NAME-HINT": "Set a name for the section.", "SECTION-DESCRIPTION": "Description", - "SECTION-DESCRIPTION-HINT": "Write a brief desciption of what the section is about.", + "SECTION-DESCRIPTION-HINT": "Write a brief description of what the section is about.", "SECTION": "Section" }, "PAGES": { @@ -420,7 +434,7 @@ "FIELD-CHECKBOX-PLACEHOLDER": "Τοποθέτηση placeholder", "FIELD-FREE-TEXT-TITLE": "Ελεύθερο Κείμενο Δεδομένων", "FIELD-FREE-TEXT-PLACEHOLDER": "Τοποθέτηση placeholder", - "FIELD-COMBO-BOX-TYPE": "Τύπος Σύνθετου Πλασίου", + "FIELD-COMBO-BOX-TYPE": "Τύπος Σύνθετου Πλαισίου", "FIELD-WORD-LIST-TITLE": "Λίστα Λέξεων Δεδομένων", "FIELD-WORD-LIST-PLACEHOLDER": "Τοποθέτηση placeholder", "FIELD-WORD-LIST-LABEL": "Ετικέτα", @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Πηγή", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Βάση Επιλογών", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Επιλογή Ημερομηνίας", "FIELD-DATE-PICKER-PLACEHOLDER": "Τοποθέτηση placeholder", "FIELD-DATE-PICKER-LABEL": "Ετικέτα", @@ -589,7 +607,7 @@ }, "ERRORS": { "INVALID-VISIBILITY-RULES": { - "MESSAGE-START": "There were invalid visibilty rules detected in ", + "MESSAGE-START": "There were invalid visibility rules detected in ", "MESSAGE-END": ". Would you like to fix them?", "CONFIRM-YES": "Yes, remove invalid rules", "CONFIRM-NO": "No, keep them.", @@ -615,12 +633,12 @@ "FINALIZED": "Οριστικοποιημένο", "PUBLISHED": "Δημοσιευμένο", "VERSION": "Έκδοση", - "CONTAINED-DATASETS": "Δεδομένα που συμπεριλαμβάνει", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Οι πληροφορίες σε ένα Σχέδιο Διαχείρισης Δεδομένων δείχνουν πως έχουν συλλεχθεί ή και/παραχθεί, επεξεργαστεί και αναλυθεί τα σύνολα δεδομένων, π.χ. ποια εργαλεία, πρότυπα, μεθοδολογίες κλπ χρησιμοποιήθηκαν, που και πως δημιουργήθηκαν αντίγραφα ασφαλείας, δημοσιεύτηκαν και διατηρήθηκαν τα σύνολα δεδομένων. Περιλαμβάνουν οποιαδήποτε κόστη σχετίζονται με το προσωπικό που ασχολείται με την επιμέλεια δεδομένων ή τα κόστη για την απόκτηση ή ανάπτυξη υπηρεσιών διαχείρισης δεδομένων. Δεν είστε σίγουροι πως φαίνεται ένα Σχέδιο Διαχείρισης Δεδομένων στην πράξη; Εξερευνήστε τα Δημόσια Σχέδια Διαχείρισης Δεδομένων και την κοινότητα του LIBER στο Zenodo για να πάρετε μια ιδέα!", "TEXT-INFO-QUESTION": " Εξερευνήστε τα Δημόσια Σχέδια Διαχείρισης Δεδομένων και", "LINK-ZENODO": "την κοινότητα του LIBER στο Zenodo", "GET-IDEA": "για να πάρετε μια ιδέα!", - "SORT-BY": "Ταξίνομηση κατά", + "SORT-BY": "Ταξινόμηση κατά", "COLUMNS": { "NAME": "Τίτλος", "GRANT": "Επιχορήγηση", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Πρόσκληση συγγραφέων", "INVITE-SHORT": "Πρόσκληση", "ADD-DATASET": "Προσθήκη Περιγραφής Συνόλου Δεδομένων στο Σχέδιο Διαχείρισης Δεδομένων", - "ADD-DATASET-SHORT": "Προσθήκη Συνόλου Δεδομένων", - "ADD-DATASET-DESCRIPTION": "Προσθήκη Περιγραφής Συνόλου Δεδομένων", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Κατάλογος όλων των Περιγραφών Συνόλου Δεδομένων", "NEW-VERSION": "Νέα Έκδοση", "START-NEW-VERSION": "Νέα Έκδοση", @@ -736,7 +754,7 @@ "SAVE": "Save", "SAVE-AND-CONTINUE": "Αποθήκευση & Συνέχεια", "SAVE-AND-ADD": "Αποθήκευση & Προσθήκη Νέου", - "SAVE-AND-CLOSE": " Αποθήκευση & Κλείσμο", + "SAVE-AND-CLOSE": " Αποθήκευση & Κλείσιμο", "SAVE-AND-FINALISE": "Αποθήκευση και Οριστικοποίηση", "FINALIZE": "Οριστικοποίηση", "REVERSE": "Αναίρεση Οριστικοποίησης", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Λήψη PDF", "DOWNLOAD-XML": "Λήψη XML", "DOWNLOAD-DOCX": "Ληψη DOCX", - "COPY-DATASET": "Αντιφραφή Περιγραφής Συνόλου Δεδομένων", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Ενημέρωση Template", "VALIDATE":"Επικύρωση", "UNDO-FINALIZATION-QUESTION" :"Αναίρεση Οριστικοποίησης?", @@ -760,7 +778,7 @@ "NO-FILES-SELECTED": "Δεν υπάρχουν επιλεγμένα αρχεία για μεταφόρτωση", "LARGE-FILE-OR-UNACCEPTED-TYPE": "Το αρχείο είναι πολύ μεγάλο ή ο τύπος του δεν υποστηρίζεται.", "MAX-FILE-SIZE": "Τα αρχεία πρέπει να είναι έως {{maxfilesize}} MB.", - "ACCEPTED-FILE-TYPES": "Οι υποστηριζόμενοι τύποι πολυμέσων εναι: " + "ACCEPTED-FILE-TYPES": "Οι υποστηριζόμενοι τύποι πολυμέσων είναι: " }, "UPLOAD": { "UPLOAD-XML": "Εισαγωγή", @@ -794,7 +812,7 @@ "GRANT": "Επιχορήγηση", "DMP-AUTHORS": "Συγγραφείς DΜP", "RESEARCHERS": "Ερευνητές", - "DATASETS-USED": "Περιγραφές Συνόλων Δεδομένων Που Χρησιμοποιήθηκαν", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Συνεργάτες", "PUBLIC": "Δημόσιο", "PRIVATE": "Ιδιωτικό", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Συγγραφείς περιγραφής συνόλου δεδομένων", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "H επιλεγμένη Περιγραφή Δεδομένων θα διαγραφεί", "FORBIDEN-DATASET": "Δεν επιτρέπεται η πρόσβαση σε αυτή την Περιγραφή Δεδομένων" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Περιγραφές Συνόλων Δεδομένων", - "DATASET-DESCRIPTION": "Περιγραφή Δεδομένων", - "SELECT-DATASETS-TO-CLONE": "Επιλογή των συνόλων δεδομένων που θα συμπεριληφθούν στο νέο Σχέδιο Διαχείρισης Δεδομένων. Τα επιλεγμένα σύνολα δεδομένα θα είναι επεξεργάσιμα.", - "SELECT-DATASETS-NONE": "Μη διαθέσιμες Περιγραφές Συνόλου Δεδομένων για αυτό το Σχέδιο Διαχείρισης Δεδομένων", + "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": "Τα σύνολα δεδομένων τεκμηριώνονται ακολουθώντας προκαθορισμένα templates τα οποία θέτουν το περιεχόμενο των περιγραφών συνόλων δεδομένων. Στο {{ APP_NAME }}, ένα Σχέδιο Διαχείρισης Δεδομένων μπορεί να περιλαμβάνει τόσες περιγραφές συνόλου δεδομένων όσα και τα σύνολα δεδομένων που τεκμηριώνει. Περιηγηθείτε ", "TEXT-INFO-REST": " για μια ματιά στα σύνολα δεδομένων που περιγράφονται στα Σχέδια Διαχείρισης Δεδομένων του {{ APP_NAME }}", "LINK-PUBLIC-DATASETS": "Δημόσιες Περιγραφές Συνόλων Δεδομένων", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Nothing here yet." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Templates Περιγραφής Συνόλου Δεδομένων", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Τίτλος", "REFERNCE": "Αναφορά", @@ -941,9 +963,24 @@ "CLONE": "Κλώνος", "NEW-VERSION": "Νέα Έκδοση", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Όλες οι εκδόσεις των Templates Περιγραφής Συνόλου Δεδομένων", + "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 +999,21 @@ "UNSUCCESSFUL": "Κάτι πήγε στραβά" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Νέο Template Σχεδίου Διαχείρισης Δεδομένων", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Επεξεργασία" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Επεξεργασία", "EDIT-DMP": "Σχέδιο Διαχείρισης Δεδομένων σε επεξεργασία", "ADD-DATASET": "Προσθήκη Συνόλου Δεδομένων", - "EDIT-DATASET": "Σύνολο Δεδομένων σε επεξεργασία", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Κλώνος", "NEW-VERSION": "Νέα Έκδοση", "CREATE-DATASET": "Δημιουργία Συνόλου Δεδομένων", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Templates", "TEMPLATE": "Template Σχεδίου Διαχείρισης Δεδομένων", "DATASET-TEMPLATES": "Σχετικά Templates Περιγραφής Συνόλου Δεδομένων", - "SELECT-TEMPLATE": "Επιλέξτε ένα template για να περιγράψετε το σύνολο δεδομένων σας", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Template Σχεδίου Διαχείρισης Δεδομένων", "PROJECT": "Έργο", "GRANT": "Επιχορήγηση", @@ -1052,7 +1101,7 @@ "GRANTS-HINT": "Βρείτε την επιχορήγηση της έρευνας σας ή προσθέστε νέα", "FUNDER": "Χορηγός", "FUNDER-HINT": "Επιλέξτε έναν χρηματοδότη της έρευνας σας ή προσθέστε νέο", - "FUNDING-ORGANIZATIONS": "Χρημαδοτικοί οργανισμοί", + "FUNDING-ORGANIZATIONS": "Χρηματοδοτικοί οργανισμοί", "PROJECT-HINT": "Projects in {{ APP_NAME }} are perceived as distinct activities falling under a grant or common activities under different grants in collaborative schemas, eg open call for contributions. Please complete it for the grant associated to your organization if your project falls under this category. In all other cases, please leave blank and it will be autocompleted.", "STATUS": "Κατάσταση Σχεδίου Διαχείρισης Δεδομένων", "EXTERNAL-SOURCE-HINT": "Κατάλογος των τιμών που παρέχονται από εξωτερικές πηγές", @@ -1061,11 +1110,11 @@ "LANGUAGE-HINT": "Επιλέξτε τη γλώσσα του Σχεδίου Διαχείρισης Δεδομένων σας", "LICENSE": "Άδεια", "VISIBILITY": "Ορατότητα", - "VISIBILITY-HINT": "Επιλέξτε πως θα εμφανίζρται το Σχέδιο Διαχείρισης Δεδομένων στο {{ APP_NAME }}. Με την επιλογή «Δημόσιο», το Σχέδιο Διαχείρισης Δεδομένων γίνεται αυτόματα διαθέσιμο σε όλους τους χρήστες της συλλογής «Δημόσια Σχέδια Διαχείρισης Δεδομένων».", + "VISIBILITY-HINT": "Επιλέξτε πως θα εμφανίζονται το Σχέδιο Διαχείρισης Δεδομένων στο {{ APP_NAME }}. Με την επιλογή «Δημόσιο», το Σχέδιο Διαχείρισης Δεδομένων γίνεται αυτόματα διαθέσιμο σε όλους τους χρήστες της συλλογής «Δημόσια Σχέδια Διαχείρισης Δεδομένων».", "PUBLICATION": "Ημερομηνία Δημοσιοποίησης", "CONTACT": "Επικοινωνία", "COST": "Δαπάνες", - "DATASETS": "Σύνολα Δεδομένων" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Μεταβείτε στην Επιχορήγηση Σχεδίου Διαχείρισης Δεδομένων", @@ -1080,7 +1129,7 @@ "LOCK": "Κλειδωμένο Σχέδιο Διαχείρισης Δεδομένων", "PERMISSION": "Δεν έχετε άδεια να επεξεργαστείτε αυτό το Σχέδιο Διαχείρισης Δεδομένων", "INSERT-MANUALLY": "Εισάγετε το χειροκίνητα", - "CREATE-DATASET": "Δημιούργια νέου", + "CREATE-DATASET": "Δημιουργία νέου", "DISABLED-EXPORT": "Παρακαλώ αποθηκεύστε τις αλλαγές σας για να εξάγετε αυτό το Σχέδιο Διαχείρισης Δεδομένων" }, "PLACEHOLDER": { @@ -1092,11 +1141,11 @@ "SNACK-BAR": { "UNSUCCESSFUL-DOI": "Αποτυχία δημιουργίας Μονοσήμαντων Αναγνωριστικών Ψηφιακών Αντικειμένων (DOI)", "SUCCESSFUL-DOI": "Επιτυχία δημιουργίας Μονοσήμαντων Αναγνωριστικών Ψηφιακών Αντικειμένων (DOI)", - "UNSUCCESSFUL-FINALIZE": "Αποτυχία οριστικοποιήσης Σχεδίου Διαχείρισης Δεδομένων" + "UNSUCCESSFUL-FINALIZE": "Αποτυχία οριστικοποίησης Σχεδίου Διαχείρισης Δεδομένων" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Διαθέσιμα Templates Συνόλου Δεδομένων", - "TEXT": "Επιλογή Χαρακτηριστικών Συνόλου Δεδομένων:", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Κύριες Πληροφορίες", "FUNDING-INFO": "Πληροφορίες Χρηματοδότησης", "DATASET-SELECTION": "Επιλογή Συνόλου Δεδομένων", - "DATASET-INFO": "Πληροφορίες Συνόλου Δεδομένων", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Πληροφορίες Άδειας", "DATASET": "Σύνολο Δεδομένων", "PREVIOUS": "Προηγούμενο", @@ -1120,9 +1169,9 @@ "TYPING": "Προσθέστε περισσότερα γράμματα στο όνομα ώστε να είναι πιο πιθανό να βρείτε το σωστό.", "UNIQUE-IDENTIFIER": "Unique Identifier", "RESEARCHER-IDENTIFIER-EXISTS": "Researcher identifier already exists.", - "ORGANISATION-IDENTIFIER-EXSTS": "Organisation identifier already exists.", + "ORGANISATION-IDENTIFIER-EXSTS": "Organization identifier already exists.", "IDENTIFIER-EXISTS-RESEARCHER-LIST": "This identifier is already used by a researcher in the researchers list.", - "IDENTIFIER-EXISTS-ORGANISATION-LIST": "This identifier is already used by an organisation in the organisations list.", + "IDENTIFIER-EXISTS-ORGANISATION-LIST": "This identifier is already used by an organization in the organizations list.", "SAVE":"Αποθήκευση", "CANCEL": "Ακύρωση" }, @@ -1138,11 +1187,11 @@ "INTRO": "Ένα Σχέδιο Διαχείρισης στο {{ APP_NAME }} αποτελείται από τις βασικές πληροφορίες σχετικά με την έρευνα, όπως ο σκοπός, οι στόχοι και οι εμπλεκόμενοι ερευνητές, αλλά και σχετικά με την τεκμηρίωση των ερευνητικών συνόλων δεδομένων, δηλαδή τις περιγραφές δεδομένων που υπογραμμίζουν τα βήματα που ακολουθήθηκαν και τα μέσα που χρησιμοποιήθηκαν σε όλες τις δραστηριότητες διαχείρισης δεδομένων.", "SECOND-INTRO": "Τα σύνολα δεδομένων τεκμηριώνονται ακολουθώντας προκαθορισμένα templates τα οποία θέτουν το περιεχόμενο των περιγραφών συνόλου δεδομένων. Στο {{ APP_NAME }}, ένα Σχέδιο Διαχείρισης Δεδομένων μπορεί να περιλαμβάνει τόσες περιγραφές συνόλου δεδομένων όσα και τα σύνολα δεδομένων που τεκμηριώνει.", "FIND": "Δεν μπορέσατε να βρείτε το σωστό;", - "HINT": "Επιλέξτε ένα template για να περιγράψετε τα σύνολα δεδομένων σας. Μπορείτε να επιλέξετε περισσότερα από ένα template." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Κάθε Σχέδιο Διαχείρισης Δεδομένων μπορεί να περιλαμβάνει συγκεκριμένες πληροφορίες άδειας σχετικά με το πόσο ανοικτό και διαθέσιμο είναι, ώστε να μπορείτε να καθορίσετε ποιος μπορεί να δει το σύνολο δεδομένων σας και για πόσο τα δεδομένα θα είναι ιδιωτικά.", - "HINT": "Μία σύντομη περιγραφή για την άδεια που χρηρισοποιεί το Σχέδιο Διαχείρισης Δεδομένων, το είδος της και πότε θα είναι ανοικτό.", + "HINT": "Μία σύντομη περιγραφή για την άδεια που χρησιμοποιεί το Σχέδιο Διαχείρισης Δεδομένων, το είδος της και πότε θα είναι ανοικτό.", "TYPING": "Προσθέστε περισσότερα γράμματα για να είναι πιο πιθανό να βρείτε το σωστό." }, "DATASET-DESCRIPTION": { @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Templates Σχεδίων Διαχείρισης Δεδομένων", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Τίτλος", "STATUS": "Κατάσταση", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Δημοσιευμένα", "LAST-EDITED": "Τελευταία Επεξεργασία" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Εισαγωγή", "UPLOAD-XML-FILE-TITLE": "Εισαγωγή Template Σχεδίου Διαχείρισης Δεδομένων", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Ετικέτες", "SELECT-TAGS": "Επιλογή Ετικέτας", - "LIKE": "Αναζήτηση Περιγραφών Συνόλου Δεδομένων", - "DRAFT-LIKE": "Αναζήτηση Προσχέδιων Περιγραφών Συνόλου Δεδομένων", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Επιλογή Επιχορηγήσεων", "ROLE": "Ρόλος", "ORGANIZATION": "Οργανισμός", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Επιλογή Templates Περιγραφής Συνόλου Δεδομένων", "RELATED-DATASET-TEMPLATES": "Σχετικά Templates Περιγραφής Συνόλων Δεδομένων" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Αναζήτηση", "ROLE": "Ρόλος", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Νέο Σχέδιο Διαχείρισης Δεδομένων", "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": "Τίτλος Περιγραφής Συνόλου Δεδομένων", - "TITLE": "Τίτλος", + "TITLE": "Title of Description", "DESCRIPTION": "Περιγραφή", "PROFILE": "Template", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Προσθέστε έναν εξωτερικό σύνδεσμο URL" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Μία σύντομη περιγραφή του τι", "TITLE-REST": "αφορά, το πεδίο εφαρμογής του και τους στόχους του." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "Δείτε περισσότερα", "VIEW-LESS": "Δείτε λιγότερα" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Επιλέξτε ένα Σχέδιο Διαχείρισης Δεδομένων από τη συλλογή σας" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Διαχειριστής", "USER": "Χρήστης", "MANAGER": "Υπεύθυνος", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1399,7 +1461,7 @@ "SOURCES": "Πηγές", "SOURCE:": "Πηγή: ", "NO-SOURCE": "Δε συνδέεται με την πηγή", - "OUTPUT": "Αποτελέσμα", + "OUTPUT": "Αποτέλεσμα", "SELECT": "Επιλέξτε" }, "DMP": { @@ -1636,7 +1698,7 @@ "DMP-QUESTION": "Τι είναι το DMP στο {{ APP_NAME_CAPS }}?", "INFO-TEXT": "Το {{ APP_NAME_CAPS }} είναι μια ανοικτή επεκτάσιμη υπηρεσία που απλοποιεί τη διαχείριση, την επικύρωση, την παρακολούθηση και τη συντήρηση των Σχεδίων Διαχείρισης Δεδομένων. Επιτρέπει στους φορείς (ερευνητές, υπεύθυνους έρευνας, διευθυντές κλπ.) να δημιουργούν ζωντανά Σχέδια Διαχείρισης Δεδομένων που μπορούν να ανταλλάσσονται ελεύθερα μεταξύ των υποδομών για τη διεξαγωγή συγκεκριμένων πτυχών της διαδικασίας διαχείρισης Δεδομένων, σύμφωνα με τις προθέσεις και τη δέσμευση των κατόχων Δεδομένων.", "INFO-DMP-TEXT": "Ένα Σχέδιο Διαχείρισης Δεδομένων είναι ένα ζωντανό αρχείο που περιγραφεί τα σύνολα δεδομένων που έχουν παραχθεί ή και επαναχρησιμοποιηθεί κατά τη διάρκεια και μετά του κύκλου ζωής της έρευνας. Τα Σχέδια Διαχείρισης Δεδομένων έχουν ως στόχο να παρέχουν στους ερευνητές τις αναγκαίες πληροφορίες για την αναπαραγωγή, επαναδιανομή και ανακατεύθυνση του σκοπού των ερευνητικών αποτελεσμάτων ώστε να εξασφαλίζεται η εγκυρότητα και η εκμετάλλευσή τους.", - "NEW-QUESTION": "Νέος με τα DMP; Επίσκεψου", + "NEW-QUESTION": "Νέος με τα DMP; Επισκέψου", "START-YOUR-FIRST-DMP": "Ξεκινήστε το πρώτο σας DMP", "OPEN-AIR-GUIDE": "Οδηγός για ερευνητές του OpenAIRE", "LEARN-MORE": "για να μάθετε περισσότερα για το πώς να δημιουργήσετε ένα!", @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "ΣΧΕΔΙΑ ΔΙΑΧΕΙΡΙΣΗΣ ΔΕΔΟΜΕΝΩΝ", "PERSONAL-USAGE": "Προσωπική Χρήση", "PUBLIC-USAGE": "Δημόσια Χρήση", - "DATASET-DESCRIPTIONS": "Περιγραφές Συνόλου Δεδομένων", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Περιγραφές Συνόλου Δεδομένων", "PUBLIC-DMPS": "Δημόσια Σχέδια Διαχείρισης Δεδομένων", "PUBLIC-DATASETS": "Δημόσιες Περιγραφές Συνόλου Δεδομένων", @@ -1657,11 +1719,11 @@ "ALL": "Όλα", "EMPTY-LIST": "Τίποτα ακόμα εδώ.", "LATEST-ACTIVITY": "Τελευταία Δραστηριότητα", - "DMP-ABOUT-BEG": "Ένα Σχέδιο Διαχείρισης Δεδομένων αποτελέιται από τις βασικές πληροφορίες σχετικά με την έρευνα, όπως ο σκοπός, οι στόχοι και οι εμπλεκόμενοι ερευνητές, αλλά και σχετικά με την τεκμηρίωση των ερευνητικών συνόλων δεδομένων, δηλαδή", + "DMP-ABOUT-BEG": "Ένα Σχέδιο Διαχείρισης Δεδομένων αποτελείται από τις βασικές πληροφορίες σχετικά με την έρευνα, όπως ο σκοπός, οι στόχοι και οι εμπλεκόμενοι ερευνητές, αλλά και σχετικά με την τεκμηρίωση των ερευνητικών συνόλων δεδομένων, δηλαδή", "DMP-ABOUT-END": ", που υπογραμμίζουν τα βήματα που ακολουθήθηκαν και τα μέσα που χρησιμοποιήθηκαν κατά τις δραστηριότητες διαχείρισης δεδομένων.", "SELECT-DMP": "Επιλέξτε ένα Σχέδιο Διαχείρισης Δεδομένων για το Σύνολο Δεδομένων σας", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Προσθήκη Περιγραφής Συνόλου Δεδομένων", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Προσθήκη Συνόλου Δεδομένων", "ADD-DMP-DESCRIPTION": "Προσθήκη Περιγραφής Σχεδίου Διαχείρισης Δεδομένων " }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Αποσύνδεση" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ρυθμίσεις", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Πρόχειρα", "FINALIZED": "Οριστικοποιημένα", "DELETED": "Deleted" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index 8328c3b4a..87abf8f4f 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Neuspješna prijava", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Uspješno brisanje", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Nije moguće obrisati predložak zato što je povezan sa skupom podataka", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Uspješno brisanje", "UNSUCCESSFUL-DELETE": "Neuspješno brisanje", "UNSUCCESSFUL-EMAIL-SEND": "Neuspješno slanje e-maila", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Novi Plan (Čarobnjak)", "PLANS-NEW": "Novi Plan (Napredno)", "DMP-NEW": "Novi Plan", - "DATASETS": "Moji skupovi podataka", - "EXPLORE": "Objavljeni opisi skupova podataka", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Dodajte opis skupa podataka (Čarobnjak)", "GRANTS": "Moje potpore", - "DMP-PROFILES": "Predlošci planova", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Predlošci skupova podataka", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Korisnici", "PROFILE": "Moj profil", "LOGIN": "Prijava", @@ -151,10 +156,13 @@ "DATASET-NEW": "Novi opis skupa podataka", "GRANT-NEW": "Nova potpora", "GRANT-EDIT": "Prikažite/uredite potporu", - "DMP-PROFILE-NEW": "Novi predložak Plana", - "DMP-PROFILE-EDIT": "Uredite predložak Plana", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Novi predložak za opis skupa podataka", "DATASET-PROFILES-EDIT": "Uredite predložak opisa skupa podataka", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Pregled objavljenih Planova", "DATASET-PUBLIC-EDIT": "Prikaz objavljenih skupova podataka", "DMP-PUBLIC-EDIT": "Prikaz objavljenih Planova", @@ -183,7 +191,8 @@ "SERBIAN": "Srpski", "PORTUGUESE": "Portugalski", "CROATIAN": "Hrvatski", - "POLISH": "Poljski" + "POLISH": "Poljski", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "Planovi", "MY-DMPS": "Moji Planovi", "DATASETS": "Opisi skupova podataka", - "DATASET": "Opis skupa podataka", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Istražite {{ APP_NAME_CAPS }}", "USERS": "Korisnici", "DATASETS-ADMIN": "Predlošci za opise skupova podataka", - "DMP-PROFILES": "Predlošci za Planove", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "O {{ APP_NAME }}u", "MY-DATASET-DESCRIPTIONS": "MOJI OPISI SKUPOVA PODATAKA", "DATASET-DESCRIPTION-WIZARD": "Čarobnjak za skupove podataka", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Čarobnjak za kreiranje Planova", "DATASET-TEMPLATES": "PREDLOŠCI ZA OPIS SKUPA PODATAKA", "TEMPLATE": "PREDLOŽAK", - "DMP-TEMPLATES": "PREDLOŠCI ZA PLANOVE", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "KORISNICI", "START-NEW-DMP": "Kreirajte novi Plan", "START-NEW-DMP-TXT": "Krenite od početka ili nastavite raditi u {{ APP_NAME }}u! Kreirajte novi plan ili uvezite postojeći", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Dodajte opis skupa podataka (Čarobnjak)", "ADD-EXPERT": "Novi Plan (Napredno)", "MY-DATASET-DESC": "Opis mog skupa podataka", - "MY-DATASETS": "Moji skupovi podataka", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Moje potpore", "HISTORY": "POVIJEST", "HISTORY-VISITED": "ZADNJI PUT POSJEĆENO", "HISTORY-EDITED": "ZADNJI PUT UNESENO", "PUBLIC": "OBJAVLJENO", "PUBLIC-DMPS": "Javno dostupni Planovi", - "PUBLIC-DESC": "Javno dostupni opisi skupova podataka", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "Korisnički račun", "ADMIN": "ADMINISTRATOR", - "DATASET-TEMPLATES": "Predlošci za opisivanje skupa podataka", - "DMP-TEMPLATES": "Predlošci za Planove", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Korisnici", "LANGUAGE-EDITOR": "Uređivanje jezika", "GUIDE-EDITOR": "Uređivanje uputa za korisnike", @@ -281,24 +291,28 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Novi API klijent", - "NEW-PROFILE": "Novi predložak za skupove podataka", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nova verzija", "NEW-PROFILE-CLONE": "Nova kopija" }, "FIELDS": { - "DATASET-TITLE": "Naziv predloška za skup podataka", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Opis", "ROLES": "Uloge" }, "STEPS": { "GENERAL-INFO": { "TITLE": "Opće informacije", - "DATASET-TEMPLATE-NAME": "Naziv predloška za skup podataka", - "DATASET-TEMPLATE-NAME-HINT": "Naziv koji se odnosi na predložak..", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Opis predloška", "DATASET-TEMPLATE-DESCRIPTION-HINT": "Kratki opis skupa podataka, njegov opseg i ciljevi.", - "DATASET-TEMPLATE-LANGUAGE": "Jezik predloška skupa podataka", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Izaberi jezik predloška", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Korisnici predloška", "DATASET-TEMPLATE-USERS-HINT": "Kako biste obavijestili korisnike, dodajte korisnike i spremite promjene.", "DATASET-TEMPLATE-REMOVE-USER": "Izbriši korisnika", @@ -314,7 +328,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Naziv poglavlja", - "PAGE-NAME-HINT": "Postavi naziv za poglavlje skupa podataka.", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Opis poglavlja", "PAGE-DESCRIPTION-HINT": "Napišite kratak opis onoga o čemu se radi u ovom poglavlju.", "ACTIONS": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Izvor", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opcija", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Izbor datuma", "FIELD-DATE-PICKER-PLACEHOLDER": "Polje za unos", "FIELD-DATE-PICKER-LABEL": "Oznaka", @@ -615,7 +633,7 @@ "FINALIZED": "Završeno", "PUBLISHED": "Objavljeno", "VERSION": "Verzija", - "CONTAINED-DATASETS": "Sadrži skupove podataka", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) sadrži informacije o tome kako su skupovi podataka prikupljeni i/ili generirani, obrađeni i analizirani (uz pomoću kojih alata, standarda, metodologija i sl.), gdje i kako su pohranjene sigurnosne kopije, gdje su podaci objavljeni i gdje se dugoročno čuvaju. Treba navesti i sve troškove nastale angažmanom suradnika koji su zaduženi za upravljanje podacima, kao i troškove osiguravanja infrastrukture za upravljanje podacima.", "TEXT-INFO-QUESTION": "Ako niste sigurni kako plan upravljanja podacima treba izgledati, pogledajte javno dostupne Planove i", "LINK-ZENODO": "LIBER zajednicu u Zenodu", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Pozovite autore", "INVITE-SHORT": "Pozovi", "ADD-DATASET": "Dodaj skup podataka u Plan", - "ADD-DATASET-DESCRIPTION": "Dodaj skup podataka", - "ADD-DATASET-SHORT": "Dodaj skup podataka", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Prikaži sve skupove podataka", "NEW-VERSION": "Nova verzija", "START-NEW-VERSION": "Započni novu verziju", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Preuzmi PDF", "DOWNLOAD-XML": "Preuzmi XML", "DOWNLOAD-DOCX": "Preuzmi DOCX", - "COPY-DATASET": "Kopiraj skup podataka", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Dopuni predložak", "VALIDATE": "Potvrdi", "UNDO-FINALIZATION-QUESTION": "Poništi zadnji korak?", @@ -794,7 +812,7 @@ "GRANT": "Potpora", "DMP-AUTHORS": "Autor/i Plana", "RESEARCHERS": "Istraživači", - "DATASETS-USED": "Pridruženi skupovi podataka", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Suradnici", "PUBLIC": "Javno", "PRIVATE": "Zatvoreno za javnost", @@ -826,10 +844,14 @@ "LOCKED-DIALOG": { "TITLE": "PUP je zaključan", "MESSAGE": "U ovom trenutku netko drugi uređuje informacije o skupu podataka. Ako želite pregledati zapis ili napraviti izmjenu, pričekajte i pokušajte ponovo kasnije." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autor/i skupa podataka", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "Traženi opis skupa podataka je obrisan", "FORBIDEN-DATASET": "Nemate dozvolu za pristup ovom opisu skupa podataka" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Skupovi podataka", - "DATASET-DESCRIPTION": "Skup podataka", - "SELECT-DATASETS-TO-CLONE": "Izaberite skupove podataka koje želite uključiti u Plan. Odabrane skupove podataka moći ćete uređivati.", - "SELECT-DATASETS-NONE": "Planu upravljanja podacima nisu pridruženi odgovarajući skupovi podataka.", + "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": "Skupovi podataka se opisuju prema unaprijed određenim predlošcima. U {{ APP_NAME }}u, Plan može sadržavati onoliko opisa koliko ima skupova podataka. Pretražite", "TEXT-INFO-REST": "za pregled skupova podataka opisanih u Planovima u {{ APP_NAME }}u", "LINK-PUBLIC-DATASETS": "Pretražite javno dostupne skupove podataka", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Još uvijek ništa nije dostupno." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Predlošci za opis skupa podataka", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Ime", "REFERNCE": "Referenca", @@ -941,9 +963,24 @@ "CLONE": "Napravi kopiju", "NEW-VERSION": "Nova verzija", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Sve verzije predložaka za skupove podataka", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Izbriši", - "CREATE-DATASET-TEMPLATE": "Kreirajte predložak za skup podataka" + "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 +999,21 @@ "UNSUCCESSFUL": "Došlo je do greške" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Novi predlošci planova", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Uredi" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Uređivanje", "EDIT-DMP": "Uređivanje Planova", "ADD-DATASET": "Dodavanje skupa podataka", - "EDIT-DATASET": "Uređivanje skupa podataka", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Napravi kopiju", "NEW-VERSION": "Nova verzija", "CREATE-DATASET": "Izrada skupa podataka", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Predlošci", "TEMPLATE": "Predlošcii za Planove", "DATASET-TEMPLATES": "Povezani predlošci skupova podataka", - "SELECT-TEMPLATE": "Odaberite predložak za opis Vašeg skupa podataka", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Predlošci Planova", "PROJECT": "Projekt", "GRANT": "Potpora", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Datum objave", "CONTACT": "Kontakt", "COST": "Troškovi", - "DATASETS": "Skupovi podataka" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Idi na potporu", @@ -1094,10 +1143,10 @@ "SUCCESSFUL-DOI": "Uspješno generiran DOI", "UNSUCCESSFUL-FINALIZE": "Plan nije dovršen" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Dostupni predlošci za skupove podataka", - "TEXT": "Odabrani profili skupova podataka:", - "OK": "U redu" + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", + "OK": "OK" }, "VISIBILITY": { "PUBLIC": "Javno dostupno", @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Osnovne informacije", "FUNDING-INFO": "Informacije o financiranju", "DATASET-SELECTION": "Odabir skupova podataka", - "DATASET-INFO": "Informacije o skupu podataka", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Informacije o licenciji", "DATASET": "Skup podataka", "PREVIOUS": "Prethodno", @@ -1138,7 +1187,7 @@ "INTRO": "Plan upravljanja podacima (eng. Data Management Plan) u {{ APP_NAME }}u sadrži osnovne informacije o istraživanju, kao što su svrha i ciljevi istraživanja, ali i informacije o uključenim istraživačima. Plan sadrži dokumentaciju skupova istraživačkih podataka s informacijama o provedenim aktivnostima i korištenim sredstvima prilikom upravljanja podacima.", "SECOND-INTRO": "Skupovi podataka se opisuju prema unaprijed definiranim predlošcima. U {{ APP_NAME }}u, Plan može sadržavati onoliko opisa koliko ima skupova podataka.", "FIND": "Ne pronalazite odgovarajući predložak?", - "HINT": "Odaberite predložak za opis Vaših skupova podataka. Možete odabrati više od jednog predloška." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Svaki Plan upravljanja podacima (eng. Data Management Plan) može sadržavati informacije o pripadajućoj licenciji koje predstavljaju koliko je otvoren kako biste mogli odrediti tko će imati pristup Vašim skupovima podataka i koliko dugo će podaci biti zatvoreni za javnost", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Predlošci planova", - "CREATE-DMP-TEMPLATE": "Kreiraj predložak za Plan", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Ime", "STATUS": "Status", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Objavljeno", "LAST-EDITED": "Posljednji put uređivano" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Uvoz", "UPLOAD-XML-FILE-TITLE": "Uvezite predložak za Plan upravljanja podacima", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Ključne riječi", "SELECT-TAGS": "Odaberite ključne riječi", - "LIKE": "Pretražite skupove podataka", - "DRAFT-LIKE": "Pretražite skice skupova podataka", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Odaberite potpore", "ROLE": "Uloga", "ORGANIZATION": "Ustanova", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Odaberite predloške za skupove podataka", "RELATED-DATASET-TEMPLATES": "Povezani predlošci za skupove podataka" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Pretraži", "ROLE": "Uloga", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Novi Plan upravljanja podacima", "EDIT": "Uredite", - "INTRO": "Nalazite se na sučelju za uređivanje Plana upravljanja podacima. Odgovorite na pitanja koja opisuju aktivnosti upravljanja Vašim podacima.", - "INTRO-TIP": "Kako biste izbjegli nejasne informacije o različitim vrstama podataka, predlažemo da za svaku vrstu podataka unesete novi Opis skupa podataka." + "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": "Naziv skupa podataka", - "TITLE": "Naziv skupa podataka", + "TITLE": "Title of Description", "DESCRIPTION": "Opis", "PROFILE": "Predložak", "URI": "URL", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Dodajte vanjsku URL poveznicu" }, "HINT": { - "DESCRIPTION": "Ukratko opišite kontekst i namjenu skupa podataka", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Kratko opis o", "TITLE-REST": "odnosi se na njegov opseg i ciljeve." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "Vidi više", "VIEW-LESS": "Vidi manje" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1370,7 +1432,7 @@ "ADMIN": "Administrator", "USER": "Korisnik", "MANAGER": "Upravitelj", - "DATASET-TEMPLATE-EDITOR": "Sučelje za uređivanje predloška za skup podataka" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLANOVI UPRAVLJANJA PODACIMA", "PERSONAL-USAGE": "Osobna upotreba", "PUBLIC-USAGE": "Javna upotreba", - "DATASET-DESCRIPTIONS": "Opisi skupova podataka", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Opisi skupova podataka", "PUBLIC-DMPS": "Javno dostupni Planovi", "PUBLIC-DATASETS": "Javno dostupni opisi skupova podataka", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": " (informacije koje ukazuju na procedure i sredstva korištena prilikom upravljanja podacima).", "SELECT-DMP": "Odaberite odgovarajući Plan za Vaš skup podataka", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Unesite opis skupa podataka", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Unesite opis skupa podataka", "ADD-DMP-DESCRIPTION": "Opišite Plan" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Odjava" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Potvrdi povezani korisnički račun", "MESSAGE": "Potvrdu za ovu radnju poslali smo Vam putem elektroničke pošte. Kada potvrdite, korisnički računi biti će povezani. Posljednji račun elektroničke pošte koji povežete biti će onaj koji sadrži sve podatke o Planu upravljanja podacima i aktivnostima u {{ APP_NAME }}u." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Postavke", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Nacrt", "FINALIZED": "Završeno", "DELETED": "Izbrisano" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index bf8762b7d..55b8e7b9a 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Nie udało się zalogować", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Usunięto", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Tego szablonu nie można usunąć, ponieważ są z nim powiązane zbiory danych", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Usunięto", "UNSUCCESSFUL-DELETE": "Nie udało się usunąć", "UNSUCCESSFUL-EMAIL-SEND": "Email nie został wysłany", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Nowy DMP (kreator)", "PLANS-NEW": "Nowy DMP (ekspert)", "DMP-NEW": "Nowy DMP", - "DATASETS": "Moje zbiory danych", - "EXPLORE": "Opublikowane zbiory danych", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Dodaj zbiór danych (kreator)", "GRANTS": "Moje dotacje", - "DMP-PROFILES": "Szablony DMP", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Szablony zbiorów danych", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Użytkownicy", "PROFILE": "Mój profil", "LOGIN": "Zaloguj", @@ -151,10 +156,13 @@ "DATASET-NEW": "Nowy zbiór danych", "GRANT-NEW": "Nowa dotacja", "GRANT-EDIT": "Wyświetl/edytuj dotację", - "DMP-PROFILE-NEW": "Nowy szablon DMP", - "DMP-PROFILE-EDIT": "Edytuj szablon DMP", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Nowy szablon zbioru danych", "DATASET-PROFILES-EDIT": "Edytuj szablon zbioru danych", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Podgląd opublikowanych DMP", "DATASET-PUBLIC-EDIT": "Wyświetl opublikowany zbiór danych", "DMP-PUBLIC-EDIT": "Wyświetl opublikowany DMP", @@ -183,7 +191,8 @@ "SERBIAN": "Serbski", "PORTUGUESE": "Portugalski", "CROATIAN": "Chorwacki", - "POLISH": "Polski" + "POLISH": "Polski", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "DMPs", "MY-DMPS": "Mój DMPs", "DATASETS": "Zbiory danych", - "DATASET": "Zbiór danych", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Poznaj {{ APP_NAME_CAPS }}", "USERS": "Użytkownicy", "DATASETS-ADMIN": "Szablony zbiorów danych", - "DMP-PROFILES": "Szablony DMP", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "O aplikacji", "MY-DATASET-DESCRIPTIONS": "MOJE ZBIORY DANYCH", "DATASET-DESCRIPTION-WIZARD": "Kreator zbioru danych", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Kreator DMP", "DATASET-TEMPLATES": "SZABLONY ZBIORU DANYCH", "TEMPLATE": "SZABLON", - "DMP-TEMPLATES": "SZABLON DMP", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "UŻYTKOWNICY", "START-NEW-DMP": "Uruchom nowy DMP", "START-NEW-DMP-TXT": "Rozpocznij od nowa lub kontynuuj pracę w {{ APP_NAME }}! Utwórz nowy DMP lub prześlij istniejący DMP do {{ APP_NAME }}", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Dodaj zbiór danych (kreator)", "ADD-EXPERT": "Nowy DMP (Expert)", "MY-DATASET-DESC": "Opis mojego zbioru danych", - "MY-DATASETS": "Moje zbiory danych", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Moje dotacje", "HISTORY": "HISTORIA", "HISTORY-VISITED": "OSTATNIO ODWIEDZANE", "HISTORY-EDITED": "OSTATNIO EDYTOWANE", "PUBLIC": "OPUBLIKOWANE", "PUBLIC-DMPS": "Publiczne DMPs", - "PUBLIC-DESC": "Publiczne opisy zbiorów danych", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "KONTO", "ADMIN": "ADMINISTRATOR", - "DATASET-TEMPLATES": "Szablony zbiorów danych", - "DMP-TEMPLATES": "Szablony DMP", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Użytkownicy", "LANGUAGE-EDITOR": "Edytor języka", "GUIDE-EDITOR": "Edytor podręcznika użytkownika", @@ -281,24 +291,28 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Nowy klient API", - "NEW-PROFILE": "Nowy szablon zbioru danych", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nowa wersja", "NEW-PROFILE-CLONE": "Nowy klon" }, "FIELDS": { - "DATASET-TITLE": "Nazwa szablonu zbioru danych", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Opis", "ROLES": "Role" }, "STEPS": { "GENERAL-INFO": { "TITLE": "Informacje ogólne", - "DATASET-TEMPLATE-NAME": "Nazwa szablonu zbioru danych", - "DATASET-TEMPLATE-NAME-HINT": "Tytuł określający szablon zbioru danych", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Opis", "DATASET-TEMPLATE-DESCRIPTION-HINT": "Krótki opis roli, zakresu i celów zbioru danych", - "DATASET-TEMPLATE-LANGUAGE": "Język szablonu zbioru danych", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Wybierz język", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Redaktorzy", "DATASET-TEMPLATE-USERS-HINT": "Dodaj redaktorów i zapisz zmiany, aby ich powiadomić.", "DATASET-TEMPLATE-REMOVE-USER": "Usuń redaktora", @@ -314,7 +328,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Nazwa rozdziału", - "PAGE-NAME-HINT": "Ustaw nazwę dla rozdziału w zbiorze danych", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Opis", "PAGE-DESCRIPTION-HINT": "Opisz krótko treść rozdziału", "ACTIONS": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Źródło", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "$Opcje główne$", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Wybierz datę", "FIELD-DATE-PICKER-PLACEHOLDER": "Wprowadź tekst zastępczy", "FIELD-DATE-PICKER-LABEL": "Etykieta", @@ -615,7 +633,7 @@ "FINALIZED": "Zakończone", "PUBLISHED": "Opublikowane", "VERSION": "Wersja", - "CONTAINED-DATASETS": "Zawarte zestawy danych", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "„Informacje w DMP pokazują, w jaki sposób zbiory danych zostały zebrane i/lub wygenerowane, w jaki sposób zostały przetworzone i przeanalizowane, tj. za pomocą jakich narzędzi, standardów, metodologii itp., ale także gdzie i w jaki sposób kopie zapasowe zbiorów danych są tworzone , opublikowane i zachowane, w tym wszelkie koszty związane z personelem zajmującym się przechowywaniem/zarządzaniem danymi lub koszty nabycia lub tworzenia usług zarządzania danymi.", "TEXT-INFO-QUESTION": "Nie wiesz, jak DMP wygląda w praktyce? Przeglądaj publiczne DMP i", "LINK-ZENODO": "Społeczność LIBER w Zenodo", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Zaproś autorów", "INVITE-SHORT": "Zaproś", "ADD-DATASET": "Dodaj zbiór danych do DMP", - "ADD-DATASET-DESCRIPTION": "Dodaj zbiór danych", - "ADD-DATASET-SHORT": "Dodaj zbiór danych", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Wyświetl na liście wszystkie zbiory danych DMP", "NEW-VERSION": "Nowa wersja", "START-NEW-VERSION": "Rozpocznij nową wersję", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Pobierz PDF", "DOWNLOAD-XML": "Pobierz XML", "DOWNLOAD-DOCX": "Pobierz DOCX", - "COPY-DATASET": "Kopiuj zbiór danych", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Aktualizuj szblon", "VALIDATE": "Sprawdź", "UNDO-FINALIZATION-QUESTION": "Cofnąć finalizację?", @@ -794,7 +812,7 @@ "GRANT": "Dotacja", "DMP-AUTHORS": "Autorzy DMP", "RESEARCHERS": "Naukowcy", - "DATASETS-USED": "Użyte zbiory danych", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Współpracownicy", "PUBLIC": "Publiczny", "PRIVATE": "Prywatny", @@ -826,10 +844,14 @@ "LOCKED-DIALOG": { "TITLE": "DMP jest zablokowany", "MESSAGE": "W tej chwili ktoś inny modyfikuje ten zbiór danych. Możesz przeglądać ten zbiór danych, ale nie możesz wprowadzać żadnych zmian. Jeśli chcesz go zmodyfikować, wróć później." - } + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." + } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autorzy zbioru danych", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "Żądany zbiór danych został usunięty", "FORBIDEN-DATASET": "Nie masz dostępu do tego zbioru danych" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Zbiory danych", - "DATASET-DESCRIPTION": "Zbiór danych", - "SELECT-DATASETS-TO-CLONE": "Wybierz zbiory danych do uwzględnienia w nowym DMP. Wybrane zbiory danych będą dostępne do edycji.", - "SELECT-DATASETS-NONE": "Niedostępne zbiory danych dla tego 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": "Zbiory danych są dokumentowane zgodnie ze wstępnie zdefiniowanymi szablonami, które ustalają zawartość opisów zbiorów danych. W {{ APP_NAME }} DMP może zawierać tyle opisów zbiorów danych, ile zbiorów danych dokumentuje. Przeglądaj", "TEXT-INFO-REST": " w celu zapoznania się z zbiorami danych opisanymi w {{ APP_NAME }} DMPs", "LINK-PUBLIC-DATASETS": "Publiczne zbiory danych", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Nic tu jeszcze nie ma" }, "DATASET-PROFILE-LISTING": { - "TITLE": "Szablon zbioru danych", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Nazwa", "REFERNCE": "Odniesienie", @@ -941,11 +963,26 @@ "CLONE": "Klonuj", "NEW-VERSION": "Nowa wersja", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Wszystkie wersje szablonów zbioru danych", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Usuń", - "CREATE-DATASET-TEMPLATE": "Utwórz szablon zbioru danych" + "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": { "TITLE": "Importuj zbiór danych", "UPLOAD-BUTTON": "Prześlij", @@ -962,10 +999,22 @@ "UNSUCCESSFUL": "Coś poszło nie tak" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Nowy szablon DMP", - "EDIT": "Edytuj" + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", + "EDIT": "Edytuj" }, "FIELDS": { "TITLE": "Pola", @@ -1024,7 +1073,7 @@ "EDIT": "Edytuj", "EDIT-DMP": "Edytuj DMP", "ADD-DATASET": "Dodawanie zbioru danych", - "EDIT-DATASET": "Edycja zbioru danych", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Klonuj", "NEW-VERSION": "Nowa wersja", "CREATE-DATASET": "Tworzenie zbioru danych", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Szablony", "TEMPLATE": "Szablony DMP", "DATASET-TEMPLATES": "Powiązane szablony zbiorów danych", - "SELECT-TEMPLATE": "Wybierz szablon, aby opisać swój zbiór danych", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Szablon DMP", "PROJECT": "Projekt", "GRANT": "Dotacja", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Data publikacji", "CONTACT": "Kontakt", "COST": "Koszty", - "DATASETS": "Zbiory danych" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Przejdź do dotacji DMP", @@ -1094,11 +1143,11 @@ "SUCCESSFUL-DOI": "Utworzono DOI", "UNSUCCESSFUL-FINALIZE": "Nieudana finalizacja DMP" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Dostępne szablony zbioru danych", - "TEXT": "Wybrane profile zbioru danych: ", - "OK": "OK" - }, + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", + "OK": "OK" + }, "VISIBILITY": { "PUBLIC": "Otwarty dostęp", "RESTRICTED": "Ograniczony dostęp" @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Główne informacje", "FUNDING-INFO": "Finansowanie", "DATASET-SELECTION": "Wybór zbioru danych", - "DATASET-INFO": "Informacje o zbiorze danych", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Licencja", "DATASET": "Zbiór danych", "PREVIOUS": "Poprzedni", @@ -1138,7 +1187,7 @@ "INTRO": "DMP w {{ APP_NAME }} składa się z kluczowych informacji o badaniach, takich jak zamysł, cele i zaangażowani naukowcy, ale także o dokumentacji zbiorów danych badawczych, która podkreśla podjęte kroki i środki zastosowane w ramach działań związanych z zarządzaniem danymi.", "SECOND-INTRO": "Zbiory danych są dokumentowane zgodnie ze wstępnie zdefiniowanymi szablonami, które ustalają zawartość opisów zbiorów danych. W {{ APP_NAME }} DMP może zawierać tyle opisów zestawów danych, ile zestawów danych dokumentuje.", "FIND": "Nie możesz znaleźć odpowiedniego?", - "HINT": "Wybierz szablon, aby opisać swoje zbiory danych. Możesz wybrać więcej niż jeden szablon." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Każdy DMP może zawierać określone informacje licencyjne dotyczące zakresu otwartości i dostępności w ten sposób możesz określić, kto może zobaczyć twój zestaw danych i jak długo te dane będą prywatne", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Szablony DMP", - "CREATE-DMP-TEMPLATE": "Utwórz szablon DMP", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Nazwa", "STATUS": "Status", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Opublikowany", "LAST-EDITED": "Ostatnio edytowany" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Import", "UPLOAD-XML-FILE-TITLE": "Importuj szablon planu zarządzania danymi", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Tagi", "SELECT-TAGS": "Wybierz tagi", - "LIKE": "Wyszukaj zbiory danych", - "DRAFT-LIKE": "Wyszukaj robocze zbiory danych", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Wybierz dotację", "ROLE": "Rola", "ORGANIZATION": "Organizacja", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Wybierz szablony zbioru danych", "RELATED-DATASET-TEMPLATES": "Szablony powiązanego zbioru danych" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Szukaj", "ROLE": "Rola", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Nowy plan zarządzania danymi", "EDIT": "Edytuj", - "INTRO": "Korzystasz z edytora zbioru danych. Odpowiedz tutaj na pytania opisujące twoje działania związane z zarządzaniem danymi.", - "INTRO-TIP": "Wskazówka: Dodaj nowe zbiory danych, aby opisać różne typy danych lub dane dyscyplinarne, aby uniknąć mieszania informacji." + "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": "Nazwa zbioru danych", - "TITLE": "Tytuł zbioru danych", + "TITLE": "Title of Description", "DESCRIPTION": "Opis", "PROFILE": "Szablon", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Podaj zewnętrzny link URL" }, "HINT": { - "DESCRIPTION": "Krótko opisz kontekst i cel zbioru danych", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Krótki opis tego, co ", "TITLE-REST": "dotyczy zakresu i celów." }, @@ -1315,7 +1373,11 @@ "VIEW-MORE": "Wyświetl więcej", "VIEW-LESS": "Wyświetl mniej" } - } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." + } }, "DATASET-CREATE-WIZARD": { "ACTIONS": { @@ -1370,7 +1432,7 @@ "ADMIN": "Administrator", "USER": "Użytkownik", "MANAGER": "Menedżer", - "DATASET-TEMPLATE-EDITOR": "Edytor szablonów zbioru danych" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLANY ZARZĄDZANIA DANYMI", "PERSONAL-USAGE": "Użytek osobisty", "PUBLIC-USAGE": "Użytek publiczny", - "DATASET-DESCRIPTIONS": "Zbiory danych", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Zbiory danych", "PUBLIC-DMPS": "Publiczne DMP", "PUBLIC-DATASETS": "Publiczne zbiory danych", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": ", które podkreślają podjęte kroki i środki stosowane w ramach działań związanych z zarządzaniem danymi.", "SELECT-DMP": "Wybierz DMP dla swojego zbioru danych", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Dodaj zbiór danych", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Dodaj zbiór danych", "ADD-DMP-DESCRIPTION": "Dodaj opis DMP" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Wyloguj" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Zweryfikuj połączone konto", "MESSAGE": "Wysłano wiadomość e-mail w celu weryfikacji tej akcji. Po zaakceptowaniu będzie można zobaczyć połączone konta. Ostatnie połączone konto e-mail będzie tym, które zawiera wszystkie twoje rejestry DMP i aktywność w {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ustawienia", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Projekt", "FINALIZED": "Sfinalizowano", "DELETED": "Usunięto" - } + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" + } } diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 2373b0288..76b6d876b 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Não foi possível iniciar a sessão", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Eliminado com sucesso", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Este modelo não pode ser eliminado porque existem Datasets associados", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Eliminado com sucesso", "UNSUCCESSFUL-DELETE": "Não eliminado", "UNSUCCESSFUL-EMAIL-SEND": "Falha no envio de email", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Novo PGD (Assistente)", "PLANS-NEW": "Novo PGD (Experiente)", "DMP-NEW": "Novo PGD", - "DATASETS": "Os meus Datasets", - "EXPLORE": "Datasets publicados", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Adicionar Dataset (Assistente)", "GRANTS": "Os meus Grants", - "DMP-PROFILES": "PGDs", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Datasets", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Utilizadores", "PROFILE": "O meu Perfil", "LOGIN": "Iniciar Sessão", @@ -151,10 +156,13 @@ "DATASET-NEW": "Novo Dataset", "GRANT-NEW": "Novo Grant", "GRANT-EDIT": "Ver/Editar Grant", - "DMP-PROFILE-NEW": "Novo PGD", - "DMP-PROFILE-EDIT": "Editar PGD", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Novo Dataset", "DATASET-PROFILES-EDIT": "Editar Dataset", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Visão geral do PGD publicado", "DATASET-PUBLIC-EDIT": "Ver Dataset Publicado", "DMP-PUBLIC-EDIT": "Ver PGD Publicado", @@ -183,7 +191,8 @@ "SERBIAN": "Sérvio", "PORTUGUESE": "Português", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "PGDs", "MY-DMPS": "Os meus PGDs", "DATASETS": "Datasets", - "DATASET": "Dataset", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Explorar o {{ APP_NAME_CAPS }}", "USERS": "Utilizadores", "DATASETS-ADMIN": "Datasets", - "DMP-PROFILES": "PGDs", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Sobre", "MY-DATASET-DESCRIPTIONS": "Os meus Datasets", "DATASET-DESCRIPTION-WIZARD": "Assistente de Dataset", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Assistente de PGD", "DATASET-TEMPLATES": "Datasets", "TEMPLATE": "Modelo", - "DMP-TEMPLATES": "PGDs", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "Utilizadores", "START-NEW-DMP": "Criar novo PGD", "START-NEW-DMP-TXT": "Crie um novo PGD ou importe um já pré-existente para o {{ APP_NAME }}", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Adicionar Dataset (Assistente)", "ADD-EXPERT": "Novo PGD (Experiente)", "MY-DATASET-DESC": "As minhas descrições de Datasets", - "MY-DATASETS": "Os meus Datasets", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Os meus Grants", "HISTORY": "HISTÓRICO", "HISTORY-VISITED": "VISITADOS RECENTEMENTE", "HISTORY-EDITED": "EDITADOS RECENTEMENTE", "PUBLIC": "PUBLICADOS", "PUBLIC-DMPS": "PGDs públicos", - "PUBLIC-DESC": "Datasets públicos", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "CONTA", "ADMIN": "Administrador", - "DATASET-TEMPLATES": "Datasets", - "DMP-TEMPLATES": "PGDs", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Utilizadores", "LANGUAGE-EDITOR": "Editor de idioma", "GUIDE-EDITOR": "Editor do Guia de Utilizador", @@ -281,24 +291,28 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Novo Cliente API", - "NEW-PROFILE": "Novo Dataset", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nova Versão de ", "NEW-PROFILE-CLONE": "Duplicação de " }, "FIELDS": { - "DATASET-TITLE": "Nome do Dataset", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Descrição", "ROLES": "Funções" }, "STEPS": { "GENERAL-INFO": { "TITLE": "Informação Geral", - "DATASET-TEMPLATE-NAME": "Nome do modelo de dados", - "DATASET-TEMPLATE-NAME-HINT": "Um nome que determine o modelo de dados.", + "DATASET-TEMPLATE-NAME": "Description template name", + "DATASET-TEMPLATE-NAME-HINT": "A title that determines the Description template.", "DATASET-TEMPLATE-DESCRIPTION": "Descrição", "DATASET-TEMPLATE-DESCRIPTION-HINT": "Uma breve descrição do que é o modelo de dados, o seu âmbito e objetivos.", - "DATASET-TEMPLATE-LANGUAGE": "Idioma do modelo de dados", + "DESCRIPTION-TEMPLATE-TYPE": "Description template type", + "DESCRIPTION-TEMPLATE-SELECT-TYPE": "Select a type", + "DATASET-TEMPLATE-LANGUAGE": "Description template language", "DATASET-TEMPLATE-SELECT-LANGUAGE": "Selecione o idioma", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", @@ -314,7 +328,7 @@ }, "PAGE-INFO": { "PAGE-NAME": "Nome do capítulo", - "PAGE-NAME-HINT": "Defina um nome para o capítulo do Dataset.", + "PAGE-NAME-HINT": "Set a name for the desciption chapter.", "PAGE-DESCRIPTION": "Descrição", "PAGE-DESCRIPTION-HINT": "Escreva uma breve descrição do que se trata neste capítulo.", "ACTIONS": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Fonte", "FIELD-AUTOCOMPLETE-URL": "URL", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opções de Raiz", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Escolha da Data", "FIELD-DATE-PICKER-PLACEHOLDER": "Sugestão de Preenchimento", "FIELD-DATE-PICKER-LABEL": "Etiqueta", @@ -615,7 +633,7 @@ "FINALIZED": "Concluído", "PUBLISHED": "Publicado", "VERSION": "Versão", - "CONTAINED-DATASETS": "Contém Datasets", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "A informação contida no Plano de Gestão de Dados (PGD) demonstra como os dados foram recolhidos e/ou gerados, como foram processados e analisados, que ferramentas, normas e metodologias utilizaram. Fornece também informação de onde e como os dados são alojados, publicados e preservados.", "TEXT-INFO-QUESTION": "Não tem a certeza de como um Plano de Gestão de Dados (PGD) é na prática? Pesquise “PGD Públicos” e", "LINK-ZENODO": "Comunidade LIBER no Zenodo", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Convidar Autores", "INVITE-SHORT": "Convidar", "ADD-DATASET": "Adicionar Dataset ao PGD", - "ADD-DATASET-DESCRIPTION": "Adicionar Dataset", - "ADD-DATASET-SHORT": "Adicionar Dataset", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Listar todos os Datasets do PGD", "NEW-VERSION": "Nova Versão", "START-NEW-VERSION": "Iniciar Nova Versão", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Exportar para PDF", "DOWNLOAD-XML": "Exportar para XML", "DOWNLOAD-DOCX": "Exportar para DOCX", - "COPY-DATASET": "Copiar o Dataset", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Atualizar o Modelo", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Desfazer a finalização??", @@ -799,7 +817,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "Autores do PGD", "RESEARCHERS": "Investigadores", - "DATASETS-USED": "Datasets usados", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Colaboradores", "PUBLIC": "Público", "PRIVATE": "Privado", @@ -831,10 +849,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autores do Dataset", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "O Dataset requerido foi eliminado", "FORBIDEN-DATASET": "Não está autorizado o acesso a este Dataset" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Datasets", - "DATASET-DESCRIPTION": "Dataset", - "SELECT-DATASETS-TO-CLONE": "Seleccionar quais os Datasets a incluir no novo PGD. Os Datasets selecionados serão editáveis.", - "SELECT-DATASETS-NONE": "Datasets não disponíveis para este PGD.", + "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": "Os Datasets no {{ APP_NAME }} são documentados segundo modelos pré-definidos, onde são registados os conteúdos e características de cada Dataset. Assim, um Plano de Gestão de Dados (PGD) pode conter tantos Datasets quanto os necessários. Pesquise ", "TEXT-INFO-REST": " para ver os Datasets descritos no PGD do {{ APP_NAME }}", "LINK-PUBLIC-DATASETS": "Datasets Públicos", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Sem informação" }, "DATASET-PROFILE-LISTING": { - "TITLE": "Datasets", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Nome", "REFERNCE": "Referência", @@ -941,9 +963,24 @@ "CLONE": "Duplicar", "NEW-VERSION": "Nova Versão", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Ver todas as versões do Dataset", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Eliminar", - "CREATE-DATASET-TEMPLATE": "Criar Modelo de Dados" + "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 +999,21 @@ "UNSUCCESSFUL": "Algo correu mal" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Novo PGD", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Editar" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Editar", "EDIT-DMP": "Editar PGD", "ADD-DATASET": "Adicionar Dataset", - "EDIT-DATASET": "Editar Dataset", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Duplicar", "NEW-VERSION": "Nova Versão", "CREATE-DATASET": "Criar Dataset", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Modelos", "TEMPLATE": "PGD", "DATASET-TEMPLATES": "Datasets relacionados", - "SELECT-TEMPLATE": "Selecione um modelo para descrever o seu Dataset", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "PGD", "PROJECT": "Projeto", "GRANT": "Grant", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Data de Publicação", "CONTACT": "Contacto", "COST": "Custos", - "DATASETS": "Datasets" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Ir para Grant", @@ -1094,9 +1143,9 @@ "SUCCESSFUL-DOI": "Criação de DOI com sucesso", "UNSUCCESSFUL-FINALIZE": "Finalização do PGD sem sucesso" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Modelos de Dados Disponíveis", - "TEXT": "Modelos de Dados selecionados: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Informação Geral", "FUNDING-INFO": "Informação sobre o Financiamento", "DATASET-SELECTION": "Seleção de Dataset", - "DATASET-INFO": "Informação sobre os Datasets", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Informação sobre a Licença", "DATASET": "Dataset", "PREVIOUS": "Anterior", @@ -1138,7 +1187,7 @@ "INTRO": "Um Plano de Gestão de Dados (PGD) no {{ APP_NAME }} inclui informação-chave sobre a investigação, nomeadamente a sua finalidade, objetivos e investigadores envolvidos. Inclui também informação sobre a documentação de Datasets da investigação, destacando as etapas seguidas e os meios utilizados nas atividades de gestão de dados.", "SECOND-INTRO": "Os dados devem ser documentados segundo modelos pré-definidos, onde são registados os conteúdos e características de cada Dataset. No {{ APP_NAME }} um Plano de Gestão de Dados (PGD) pode conter tantos Datasets quanto os necessários.", "FIND": "Não foi possível encontrar a informação pretendida?", - "HINT": "Selecione um modelo ou mais modelos para descrever os seus Datasets. A seleção de mais do que um modelo de dados, serve para que, caso pretenda, possa descrever os seus dados sob modelos diferentes consoante a instituição e/ou área temática a reportar. Poderá selecionar mais do que um modelo." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Cada Plano de Gestão de Dados (PGD) pode conter informações específicas sobre a licença, no que se refere à abertura e disponibilidade de dados. Deste modo, é possível definir quem pode ver os seus Datasets e por quanto tempo esses dados ficarão em acesso restrito.", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "PGDs", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Nome", "STATUS": "Estado", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Publicado", "LAST-EDITED": "Última edição" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Importar", "UPLOAD-XML-FILE-TITLE": "Importar Plano de Gestão de Dados", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Etiquetas", "SELECT-TAGS": "Selecionar Etiquetas", - "LIKE": "Procurar Datasets", - "DRAFT-LIKE": "Procurar Rascunho de Datasets", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Selecionar Grants", "ROLE": "Função", "ORGANIZATION": "Organização", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Selecionar Datasets", "RELATED-DATASET-TEMPLATES": "Datasets" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Procurar", "ROLE": "Função", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Novo Plano de Gestão de Dados", "EDIT": "Editar", - "INTRO": "Um Plano de Gestão de Dados (PGD) permite uma maior proximidade com o local onde os seus dados são gerados, analisados e armazenados. O {{ APP_NAME }} é uma ferramenta aberta, extensível e colaborativa que disponibiliza Planos de Gestão de Dados FAIR e Abertos.", - "INTRO-TIP": "Dica: Adicione novos modelos de dados para descrever diferentes tipos de dados ou área temática." + "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": "Designação do Dataset", - "TITLE": "Título do Dataset", + "TITLE": "Title of Description", "DESCRIPTION": "Descrição", "PROFILE": "Modelo", "URI": "URI", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Forneça uma ligação URL externa" }, "HINT": { - "DESCRIPTION": "Descrever brevemente o contexto e o objetivo", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Uma breve descrição do que o/a ", "TITLE-REST": "é sobre o seu âmbito e objetivos." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Selecione um PGD existente" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Administrador", "USER": "Utilizador", "MANAGER": "Gestor", - "DATASET-TEMPLATE-EDITOR": "Editor de Modelo de Dados" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLANOS DE GESTÃO DE DADOS", "PERSONAL-USAGE": "Uso Pessoal", "PUBLIC-USAGE": "Uso Público", - "DATASET-DESCRIPTIONS": "Datasets", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "", "PUBLIC-DMPS": "PGDs Públicos", "PUBLIC-DATASETS": "Datasets Públicos", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": "", "SELECT-DMP": "Selecione um PGD para o seu Dataset", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Adicione um Dataset", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Adicione um Dataset", "ADD-DMP-DESCRIPTION": "Adicione uma descrição ao PGD" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Terminar Sessão" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Definições", @@ -1745,7 +1808,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", @@ -1915,6 +1978,12 @@ "FINALIZED": "Concluído", "DELETED": "Eliminado" }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" + }, "This account has no Zenodo Token": "Selecione uma das seguintes opções para depositar o seu PGD:", "File format is not supported": "Ficheiro a importar deverá ser em formato .json", "You cannot Remove Datamanagement Plan with Datasets": "Não pode remover o Plano de Gestão de Dados porque contém pelo menos um modelo de dados associado", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 0c8415251..b2d441d03 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Neúspešné prihlásenie", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Úspešne vymazané", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Túto šablónu nie je možné odstrániť, pretože sú k nej priradené súbory dát", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Úspešne vymazané", "UNSUCCESSFUL-DELETE": "Neúspešne vymazané", "UNSUCCESSFUL-EMAIL-SEND": "Odoslanie emailu zlyhalo", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Nový DMP (Sprievodca)", "PLANS-NEW": "Nový DMP (Expert)", "DMP-NEW": "Nový DMP", - "DATASETS": "Moje súbory dát", - "EXPLORE": "Publikované súbory dát", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Pridať súbor dát (Sprievodca)", "GRANTS": "Moje granty", - "DMP-PROFILES": "DMP šablóny", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Šablóny súborov dát", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Používatelia", "PROFILE": "Môj profil", "LOGIN": "Prihlásenie", @@ -151,10 +156,13 @@ "DATASET-NEW": "Nový súbor dát", "GRANT-NEW": "Nový grant", "GRANT-EDIT": "Pozrieť/Editovať grant", - "DMP-PROFILE-NEW": "Nová DMP šablóna ", - "DMP-PROFILE-EDIT": "Editovať DMP šablónu", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Nový klon šablóny súboru dát", "DATASET-PROFILES-EDIT": "Editovať šablónu súboru dát", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Publikované DMP - prehľad", "DATASET-PUBLIC-EDIT": "Pozrieť publikované súbory dát", "DMP-PUBLIC-EDIT": "Pozrieť publikované DMP", @@ -183,7 +191,8 @@ "SERBIAN": "Serbian", "PORTUGUESE": "Portuguese", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "DMP", "MY-DMPS": "Moje DMP", "DATASETS": "Súbory dát", - "DATASET": "Súbor dát", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Preskúmať {{ APP_NAME_CAPS }}", "USERS": "Používatelia", "DATASETS-ADMIN": "Šablóny súborov dát", - "DMP-PROFILES": "DMP šablóny", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "O nástroji", "MY-DATASET-DESCRIPTIONS": "MOJE SÚBORY DÁT", "DATASET-DESCRIPTION-WIZARD": "Sprievodca pre Súbory dát", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Sprievodca pre DMP ", "DATASET-TEMPLATES": "ŠABLÓNY SÚBOROV DÁT", "TEMPLATE": "ŠABLÓNA", - "DMP-TEMPLATES": "DMP ŠABLÓNY", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "POUŽÍVATELIA", "START-NEW-DMP": "Začať nový DMP", "START-NEW-DMP-TXT": "Svoj DMP vytvoríte ľahko pomocou špeciálneho Sprievodcu. Obsahuje presný návod s podrobnými informáciami potrebnými na ľahké vytvorenie DMP.", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Pridať súbor dát (Sprievodca)", "ADD-EXPERT": "Nový DMP (Expert)", "MY-DATASET-DESC": "Moje typy súborov dát.", - "MY-DATASETS": "Moje súbory dát", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Moje granty", "HISTORY": "HISTÓRIA", "HISTORY-VISITED": "NAPOSLEDY NAVŠTÍVENÉ", "HISTORY-EDITED": "NAPOSLEDY UPRAVENÉ", "PUBLIC": "PUBLIKOVANÉ", "PUBLIC-DMPS": "Verejné DMP", - "PUBLIC-DESC": "Verejné súbory dát", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "ÚČET", "ADMIN": "ADMIN", - "DATASET-TEMPLATES": "Šablóny súborov dát", - "DMP-TEMPLATES": "DMP šablóny", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Používatelia", "LANGUAGE-EDITOR": "Úprava jazyka", "GUIDE-EDITOR": "Úprava používateľskej príručky", @@ -281,30 +291,34 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Nový API klient", - "NEW-PROFILE": "Nová šablóna súboru dát", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nová verzia", "NEW-PROFILE-CLONE": "Nový klon" }, "FIELDS": { - "DATASET-TITLE": "Názov šablóny súboru dát", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Opis", "ROLES": "Role" }, "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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,7 +328,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": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Source", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Date Picker", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder", "FIELD-DATE-PICKER-LABEL": "Label", @@ -615,7 +633,7 @@ "FINALIZED": "Dokončené", "PUBLISHED": "Publikované", "VERSION": "Verzia", - "CONTAINED-DATASETS": "Počet súborov dát", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Informácie v DMP ukazujú, ako boli súbory dát zhromaždené a/alebo vygenerované, ako boli spracované a analyzované, t.j. ktoré nástroje, štandardy a metódy a pod. sa použili. Ale tiež kde a ako sú súbory dát zálohované, publikované a uchovávané, vrátane nákladov na pracovníkov, ktorí sa venujú získavaniu a spravovaniu dát alebo nákladov na získanie a budovanie nástrojov a programov na manažment dát.", "TEXT-INFO-QUESTION": "Neviete ako vyzerá DMP v praxi? Prezrite si verejné DMP a", "LINK-ZENODO": "LIBER komunitu v Zenodo,", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Pozvať autorov", "INVITE-SHORT": "Pozvať", "ADD-DATASET": "Pridať súbor dát do DMP", - "ADD-DATASET-DESCRIPTION": "Pridať súboru dát", - "ADD-DATASET-SHORT": "Pridať súbor dát", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Uviesť všetky súbory dát DMP", "NEW-VERSION": "Nová verzia", "START-NEW-VERSION": "Začať novú verziu", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Stiahnuť PDF", "DOWNLOAD-XML": "Stiahnuť XML", "DOWNLOAD-DOCX": "Stiahnuť DOCX", - "COPY-DATASET": "Kopírovať súbor dát", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Aktualizovať šablónu", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +812,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "Autori DΜP", "RESEARCHERS": "Výskumníci", - "DATASETS-USED": "Použité súbory dát", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Spolupracovníci", "PUBLIC": "Verejné", "PRIVATE": "Neverejné", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autori súborov dát", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "Požadovaný DMP je vymazaný", "FORBIDEN-DATASET": "K tomuto DMP nemáte povolený prístup" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Súbory dát", - "DATASET-DESCRIPTION": "Súbor dát", - "SELECT-DATASETS-TO-CLONE": "Vyberte súbory dát, ktoré sa majú začleniť do nového DMP. Vybrané súbory dát bude možné editovať.", - "SELECT-DATASETS-NONE": "K tomuto DMP nie sú dostupné súbory dát.", + "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": "Súbory dát sú dokumentované podľa vopred definovaných šablón, ktoré určujú obsah daného typu súboru dát. V {{ APP_NAME }}e môže DMP obsahovať toľko typov súborov dát, koľko súborov dát dané DMP dokumentuje. Prezrieť", "TEXT-INFO-REST": " súbory dát začlené do DMP v {{ APP_NAME }}e", "LINK-PUBLIC-DATASETS": "Verejné súbory dát", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Zatiaľ prázdne." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Šablóny súborov dát", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Názov", "REFERNCE": "Odkaz", @@ -941,9 +963,24 @@ "CLONE": "Klonovať", "NEW-VERSION": "Nová verzia", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Všetky verzie šablóny súboru dát", + "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 +999,21 @@ "UNSUCCESSFUL": "Vyskytol sa problém" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Nová šablóna DMP", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Editovať" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Upraviť", "EDIT-DMP": "Úprava DMP", "ADD-DATASET": "Pridanie súboru dát", - "EDIT-DATASET": "Upravenie súboru dát", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Klonovať", "NEW-VERSION": "Nová verzia", "CREATE-DATASET": "Vytvorenie súboru dát", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Šablóny", "TEMPLATE": "DMP šablóna", "DATASET-TEMPLATES": "Súvisiace šablóny súborov dát", - "SELECT-TEMPLATE": "Vyberte šablónu, ktorá definuje váš súbor dát", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Šablóna DMP", "PROJECT": "Projekt", "GRANT": "Grant", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Dátum publikovania", "CONTACT": "Kontakt", "COST": "Náklady", - "DATASETS": "Súbory dát" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Prejsť na Grant DMP", @@ -1094,9 +1143,9 @@ "SUCCESSFUL-DOI": "Úspešné vytvorenie DOI", "UNSUCCESSFUL-FINALIZE": "Neúspešné dokončenie DMP" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Dostupné šablóny súborov dát", - "TEXT": "Zvolené profily súborov dát: ", + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", "OK": "OK" }, "VISIBILITY": { @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Hlavné informácie", "FUNDING-INFO": "Informácie o financovaní", "DATASET-SELECTION": "Výber súboru dát", - "DATASET-INFO": "Informácie o súbore dát", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Informácie o licenciách", "DATASET": "Súbor dát", "PREVIOUS": "Späť", @@ -1138,7 +1187,7 @@ "INTRO": "DMP v platforme {{ APP_NAME }} tvoria kľúčové informácie o výskume, ako sú napríklad účel, ciele a zapojení výskumníci, ale aj o dokumentácii výskumných súborov dát, hlavne informácie o typoch súborov dát, ktoré ukazujú postupnosť krokov a prostriedkov používaných v rámci manažmentu dát.", "SECOND-INTRO": "Súbory dát sa vytvárajú podľa vopred definovaných šablón, ktoré určujú obsah typu súboru údajov. DMP v {{ APP_NAME }}e obsahuje toľko typov súborov údajov, koľko je súborov dát v ňom vytvorených.", "FIND": "Nenašli ste správny súbor?", - "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": "Každý DMP obsahuje špecifické informácie o licencii, o tom nakoľko je otvorená a prístupná. Takto je možné určiť, kto môže vidieť váš súbor údajov a ako dlho budú údaje neverejné.", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Šablóny DMP", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Názov", "STATUS": "Stav", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Publikované", "LAST-EDITED": "Naposledy upravené" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Importovať", "UPLOAD-XML-FILE-TITLE": "Importovať šablónu Plánu manažmentu dát", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Tagy", "SELECT-TAGS": "Hľadať súbory dát", - "LIKE": "Search Datasets", - "DRAFT-LIKE": "Hľadať návrhy súborov dát", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Vybrať granty", "ROLE": "Rola", "ORGANIZATION": "Organizácia", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Vybrať šablóny súborov dát", "RELATED-DATASET-TEMPLATES": "Súvisiace šablóny súborov dát" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Hľadať", "ROLE": "Rola", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Nový Plán manažmentu dát", "EDIT": "Upraviť", - "INTRO": "Plán manažmentu dát (DMP, z angl. Data Management Plan) tvoria vaše plány manažmentu dát, ktoré sú bližšie miestu, kde sú vygenerované, analyzované a uložené. {{ APP_NAME }} je otvorený, rozširovateľný, kolaboratívny nástroj, ktorý podporuje plán manažmentu otvorených a FAIR dát (Open and FAIR Data Management Plans).", - "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": "Názov súboru údajov", - "TITLE": "Názov", + "TITLE": "Title of Description", "DESCRIPTION": "Opis", "PROFILE": "Šablóna", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Uviesť externý URL link" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Stručný opis toho, o čom je ", "TITLE-REST": " , opis rozsahu a cieľov." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Vybrať existujúci DMP." }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Admin", "USER": "Používateľ", "MANAGER": "Manažér", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLÁNY MANAŽMENTU DÁT", "PERSONAL-USAGE": "Osobné použitie", "PUBLIC-USAGE": "Verejné použitie", - "DATASET-DESCRIPTIONS": "Súbory dát", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Súbory dát", "PUBLIC-DMPS": "Verejné DMP", "PUBLIC-DATASETS": "Verejné súbory dát", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": "o typoch súborov dát, ktoré ukazujú postupnosť krokov a prostriedkov používaných v rámci manažmentu dát.", "SELECT-DMP": "Vybrať DMP pre svoj súbor dát", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Pridať súbor dát", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Pridať súbor dát", "ADD-DMP-DESCRIPTION": "Pridať opis DMP" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Odhlásiť sa" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Nastavenia", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Návrh", "FINALIZED": "Dokončené", "DELETED": "Deleted" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index 8904496f7..d09710536 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Neuspešno prijavljivanje", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Uspešno brisanje", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Ne možete da obrišete obrazac zato što je povezan sa skupom podataka", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Uspešno brisanje", "UNSUCCESSFUL-DELETE": "Neuspešno brisanje", "UNSUCCESSFUL-EMAIL-SEND": "Neuspešno slanje email-a", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Novi Plan (Čarobnjak)", "PLANS-NEW": "Novi Plan (Napredno)", "DMP-NEW": "Novi Plan", - "DATASETS": "Moji skupovi podataka", - "EXPLORE": "Objavljeni skupovi podataka", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Dodajte skup podataka (Čarobnjak)", "GRANTS": "Moji grantovi", - "DMP-PROFILES": "Obrasci za Planove", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Obrasci za skupove podataka", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Korisnici", "PROFILE": "Moj profil", "LOGIN": "Prijava", @@ -151,10 +156,13 @@ "DATASET-NEW": "Novi skup podataka", "GRANT-NEW": "Novi grant", "GRANT-EDIT": "Prikažite/uredite grant", - "DMP-PROFILE-NEW": "Novi obrazac Plana", - "DMP-PROFILE-EDIT": "Uredite obrazac Plana", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Novi obrazac za skup podataka", "DATASET-PROFILES-EDIT": "Uredite obrazac skupa podataka", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Pregled objavljenih Planova", "DATASET-PUBLIC-EDIT": "Prikaz objavljenih skupova podataka", "DMP-PUBLIC-EDIT": "Prikaz objavljenih Planova", @@ -183,7 +191,8 @@ "SERBIAN": "Serbian", "PORTUGUESE": "Portuguese", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "Planovi", "MY-DMPS": "Moji Planovi", "DATASETS": "Skupovi podataka", - "DATASET": "Skup podataka", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "Istražite {{ APP_NAME_CAPS }}", "USERS": "Korisnici", "DATASETS-ADMIN": "Obrasci za skupove podataka", - "DMP-PROFILES": "Obrasci za Planove", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Više o", "MY-DATASET-DESCRIPTIONS": "MOJI SKUPOVI PODATAKA", "DATASET-DESCRIPTION-WIZARD": "Čarobnjak za skupove podataka", @@ -233,7 +242,7 @@ "DMP-WIZARD": "Čarobnjak za kreiranje Planova", "DATASET-TEMPLATES": "OBRASCI ZA SKUPOVE PODATAKA", "TEMPLATE": "OBRAZAC", - "DMP-TEMPLATES": "OBRASCI ZA PLANOVE", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "KORISNICI", "START-NEW-DMP": "Započnite kreiranje novog Plana", "START-NEW-DMP-TXT": "Krenite ispočetka ili nastavite da radite u {{ APP_NAME }}u! Kreirajte novi plan ili uvezite postojeći u {{ APP_NAME }}", @@ -259,18 +268,19 @@ "QUICK-WIZARD-DATASET": "Dodajte skup podataka (Čarobnjak)", "ADD-EXPERT": "Novi Plan (Napredno)", "MY-DATASET-DESC": "Opis mog skupa podataka", - "MY-DATASETS": "Moji skupovi podataka", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Moji grantovi", "HISTORY": "ISTORIJA", "HISTORY-VISITED": "POSLEDNJA POSETA", "HISTORY-EDITED": "POSLEDNJI UNOS", "PUBLIC": "OBJAVLJENO", "PUBLIC-DMPS": "Javno dostupni Planovi", - "PUBLIC-DESC": "Javno dostupni skupovi podataka", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "NALOG", "ADMIN": "ADMINISTRATOR", - "DATASET-TEMPLATES": "Obrasci za skupove podataka", - "DMP-TEMPLATES": "Obrasci za Planove", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Korisnici", "LANGUAGE-EDITOR": "Uređivanje jezika", "GUIDE-EDITOR": "Uređivanje vodiča za korisnike", @@ -281,30 +291,34 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Nov API klijent", - "NEW-PROFILE": "Nov obrazac za skupove podataka", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Nova verzija", "NEW-PROFILE-CLONE": "Nova kopija" }, "FIELDS": { - "DATASET-TITLE": "Naziv obrasca za skup podataka", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Opis", "ROLES": "Uloge" }, "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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,7 +328,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": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Izvor", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Opcija", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Izbor datuma", "FIELD-DATE-PICKER-PLACEHOLDER": "Polje za unos", "FIELD-DATE-PICKER-LABEL": "Oznaka", @@ -615,7 +633,7 @@ "FINALIZED": "Završeno", "PUBLISHED": "Objavljeno", "VERSION": "Verzija", - "CONTAINED-DATASETS": "Sadrži skupove podataka", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) sadrži informacije o tome kako su skupovi podataka prikupljeni i/ili generisani, obrađeni i analizirani (uz pomoću kojih alata, standarda, metodologija i sl), gde i kako su pohranjene sigurnosne kopije, gde su podaci objavljeni i gde se dugoročno čuvaju. Treba navesti i sve troškove angažovanja saradnika koji su zaduženi za upravljanje podacima, kao i troškove obezbeđivanja servisa za upravljanje podacima.", "TEXT-INFO-QUESTION": "Ako niste sigurni kako plan upravljanja podacima treba da izgleda, pogledajte javno dostupne Planove i", "LINK-ZENODO": "LIBER zajednicu u Zenodu", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Pozovite autore", "INVITE-SHORT": "Pozovite", "ADD-DATASET": "Dodajte skup podataka u Plan", - "ADD-DATASET-DESCRIPTION": "Dodajte skup podataka", - "ADD-DATASET-SHORT": "Dodajte skup podataka", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Prikažite sve skupove podataka", "NEW-VERSION": "Nova verzija", "START-NEW-VERSION": "Započnite novu verziju", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "Preuzmite PDF", "DOWNLOAD-XML": "Preuzmite XML", "DOWNLOAD-DOCX": "Preuzmite DOCX", - "COPY-DATASET": "Kopirajte skup podataka", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Ažurirajte obrazac", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +812,7 @@ "GRANT": "Grant", "DMP-AUTHORS": "Autori Plana", "RESEARCHERS": "Istraživači", - "DATASETS-USED": "Skupovi podataka koji se koriste", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Saradnici", "PUBLIC": "Javno", "PRIVATE": "Zatvoreno za javnost", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autori skupa podataka", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "Traženi skup podataka je obrisan", "FORBIDEN-DATASET": "Nije Vam dozvoljeno da pristupite ovom skupu podataka" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Skupovi podataka", - "DATASET-DESCRIPTION": "Skup podataka", - "SELECT-DATASETS-TO-CLONE": "Izaberite skupove podataka koje želite da uključite u Plan. Odabrane skupove podataka moći ćete da uređujete.", - "SELECT-DATASETS-NONE": "Ovi skupovi podataka nisu dostupni za odabrani plan upravljanja podacima.", + "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": "Skupovi podataka se opisuju prema predefinisanim obrascima. U {{ APP_NAME }}u, plan može da sadrži onoliko opisa koliko ima skupova podataka. Pretražite", "TEXT-INFO-REST": "za pregled skupova podataka opisanih u planovima u {{ APP_NAME }}u", "LINK-PUBLIC-DATASETS": "javno dostupne skupove podataka", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Još uvek ništa nije dostupno." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Obrasci za skup podataka", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "Ime", "REFERNCE": "Referenca", @@ -941,9 +963,24 @@ "CLONE": "Napravite kopiju", "NEW-VERSION": "Nova verzija", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Sve verzije obrazaca za skupove podataka", + "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 +999,21 @@ "UNSUCCESSFUL": "Došlo je do greške" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Novi obrasci za Planove", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Uredite" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Uredite", "EDIT-DMP": "Uređivanje Planova", "ADD-DATASET": "Dodavanje skupa podataka", - "EDIT-DATASET": "Uređivanje skupa podataka", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Napravite kopiju", "NEW-VERSION": "Nova verzija", "CREATE-DATASET": "Kreiranje skupa podataka", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Obrasci", "TEMPLATE": "Obrasci za Planove", "DATASET-TEMPLATES": "Povezani obrasci skupova podataka", - "SELECT-TEMPLATE": "Odaberite obrazac da opišete Vaš skup podataka", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "Obrasci za Planove", "PROJECT": "Projekat", "GRANT": "Grant", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Datum objavljivanja", "CONTACT": "Kontakt", "COST": "Troškovi", - "DATASETS": "Skupovi podataka" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "Pređite na grant", @@ -1094,10 +1143,10 @@ "SUCCESSFUL-DOI": "Uspešno registrovan DOI", "UNSUCCESSFUL-FINALIZE": "Plan nije dovršen" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Dostupni obrasci za skupove podataka", - "TEXT": "Odabrani profili skupova podataka:", - "OK": "U redu" + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", + "OK": "OK" }, "VISIBILITY": { "PUBLIC": "Javno dostupno", @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Osnovne informacije", "FUNDING-INFO": "Informacije o finansiranju", "DATASET-SELECTION": "Odabir skupova podataka", - "DATASET-INFO": "Informacije o skupu podataka", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Informacije o licenci", "DATASET": "Skup podataka", "PREVIOUS": "Prethodno", @@ -1138,7 +1187,7 @@ "INTRO": "Plan upravljanja podacima (eng. Data Management Plan) u {{ APP_NAME }}u sadrži osnovne informacije o istraživanju, kao što su svrha i ciljevi istraživanja, ali i informacije o angažovanim istraživačima. Plan sadrži i informacije o skupovima istraživačkih podataka koje ukazuju na procedure primenjene u upravljanju podacima.", "SECOND-INTRO": "Skupovi podataka se opisuju prema predefinisanim obrascima. U {{ APP_NAME }}u, plan može da sadrži onoliko opisa koliko ima skupova podataka.", "FIND": "Niste mogli da pronađete odgovarajući?", - "HINT": "Odaberite obrazac za Vaše skupove podataka. Možete odabrati više od jednog obrasca." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Svaki plan upravljanja podacima (eng. Data Management Plan) sadrži informaciju o pripadajućoj licenci koja govori o tome koliko je Plan otvoren i dostupan, pa na taj način možete da odredite ko može da ima pristup Vašem skupu podataka i koliko dugo će podaci biti zatvoreni za javnost", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Obrasci za Planove", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "Ime", "STATUS": "Status", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Objavljeno", "LAST-EDITED": "Poslednji put izmenjeno" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "Uvezite", "UPLOAD-XML-FILE-TITLE": "Uvezite obrazac za plan upravljanja podacima", @@ -1218,8 +1272,8 @@ "NONE": "", "TAGS": "Ključna oznaka", "SELECT-TAGS": "Odaberi ključnu oznaku", - "LIKE": "Pretražite skupove podataka", - "DRAFT-LIKE": "Pretražite nacrte skupova podataka", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Odaberite grantove", "ROLE": "Uloga", "ORGANIZATION": "Institucija", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Odaberite obrasce za skupove podataka", "RELATED-DATASET-TEMPLATES": "Povezani obrasci za skupove podataka" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Pretražite", "ROLE": "Uloga", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Novi plan upravljanja podacima", "EDIT": "Uredite", - "INTRO": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) se sastoji od Vaših planova za upravljanje podacima i sadrži informacije kako su nastali, kako su analizirani i na koji način su sačuvani podaci. {{ APP_NAME }} je otvoren kolaboracioni alat sa mogućnošću nadogradnje koji podržava otvorene i FAIR principe za upravljanje podacima.", - "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": "Naziv skupa podataka", - "TITLE": "Naslov skupa podataka", + "TITLE": "Title of Description", "DESCRIPTION": "Opis", "PROFILE": "Obrazac", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Dodajte spoljni URL link" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Kratko uputstvo o", "TITLE-REST": "radi se o njegovoj nameni i ciljevima." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Odaberite postojeći Plan" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Administrator", "USER": "Korisnik", "MANAGER": "Menadžer", - "DATASET-TEMPLATE-EDITOR": "Dataset Template Editor" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "PLANOVI UPRAVLJANJA PODACIMA", "PERSONAL-USAGE": "Lična upotreba", "PUBLIC-USAGE": "Javna upotreba", - "DATASET-DESCRIPTIONS": "Skupovi podataka", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Skupovi podataka", "PUBLIC-DMPS": "Javno dostupni Planovi", "PUBLIC-DATASETS": "Javno dostupni skupovi podataka", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": ", koje ukazuju na procedure primenjene u upravljanju podacima.", "SELECT-DMP": "Odaberite odgovarajući Plan za Vaš skup podataka", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Dodajte skup podataka", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Dodajte skup podataka", "ADD-DMP-DESCRIPTION": "Dodajte opis Plana" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Odjavite se" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Podešavanja", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Radna verzija", "FINALIZED": "Završeno", "DELETED": "Deleted" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index 6e360736f..f5f74aad1 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -28,6 +28,10 @@ "UNSUCCESSFUL-LOGIN": "Başarısız Giriş", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Silme Başarılı", "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Veri seti Tanımları ilişkilendirildiği için bu şablon silinemez", + "SUCCESSFUL-DMP-BLUEPRINT-DELETE": "Successful Delete", + "UNSUCCESSFUL-DMP-BLUEPRINT-DELETE": "This blueprint can not deleted, because DMPs 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": "Başarılı Silme", "UNSUCCESSFUL-DELETE": "Başarısız Silme", "UNSUCCESSFUL-EMAIL-SEND": "E-posta gönderilemedi", @@ -133,12 +137,13 @@ "QUICK-WIZARD": "Yeni VYP (Sihirbaz)", "PLANS-NEW": "Yeni VYP (Uzman)", "DMP-NEW": "Yeni VYP", - "DATASETS": "Veri Setlerim", - "EXPLORE": "Yayınlanmış Veri Setleri", + "DESCRIPTIONS": "My Descriptions", + "EXPLORE": "Published Descriptions", "DATASETCREATEWIZARD": "Veri Seti Ekle (Sihirbaz)", "GRANTS": "Hibelerim", - "DMP-PROFILES": "VYP Şablonları", + "DMP-BLUEPRINTS": "DMP Blueprints", "DATASET-PROFILES": "Veri Seti Şablonları", + "DESCRIPTION-TYPES": "Description Types", "USERS": "Kullanıcılar", "PROFILE": "Profilim", "LOGIN": "Giriş", @@ -151,10 +156,13 @@ "DATASET-NEW": "Yeni Veri Seti", "GRANT-NEW": "Yeni Hibe", "GRANT-EDIT": "Hibe Görüntüle/Düzenle", - "DMP-PROFILE-NEW": "Yeni VYP Şablonu", - "DMP-PROFILE-EDIT": "VYP Şablonu Düzenle", + "DMP-BLUEPRINT-NEW": "New DMP Blueprint", + "DMP-BLUEPRINT-CLONE": "New Clone of DMP Blueprint", + "DMP-BLUEPRINT-EDIT": "Edit DMP Blueprint", "DATASET-PROFILES-NEW": "Yeni Veri Seti Şablonu", "DATASET-PROFILES-EDIT": "Veri Seti Şablonu Düzenle", + "DESCRIPTION-TYPE-NEW": "New Description Type", + "DESCRIPTION-TYPE-EDIT": "Edit Description Type", "EXPLORE-PLANS-OVERVIEW": "Yayınlanmış VYP Genel Bakış", "DATASET-PUBLIC-EDIT": "Yayınlanan Veri Seti Görüntüle", "DMP-PUBLIC-EDIT": "Yayınlanmış VYP Görüntüle", @@ -183,7 +191,8 @@ "SERBIAN": "Sırpça", "PORTUGUESE": "Portekizce", "CROATIAN": "Croatian", - "POLISH": "Polish" + "POLISH": "Polish", + "BASQUE": "Basque" } }, "COOKIE": { @@ -219,11 +228,11 @@ "DMPS": "VYP'ları", "MY-DMPS": "VYP'larım", "DATASETS": "Veri Setleri", - "DATASET": "Veri Seti", + "DESCRIPTION": "Description", "PUBLIC-DATASETS": "{{ APP_NAME_CAPS }}'u Keşfet", "USERS": "Kullanıcılar", "DATASETS-ADMIN": "Veri Seti Şablonları", - "DMP-PROFILES": "VYP Şablonları", + "DMP-BLUEPRINTS": "DMP Blueprints", "ABOUT": "Hakkında", "MY-DATASET-DESCRIPTIONS": "Veri Setlerim", "DATASET-DESCRIPTION-WIZARD": "Veri Seti Sihirbazı", @@ -233,7 +242,7 @@ "DMP-WIZARD": "VYP Sihirbazı", "DATASET-TEMPLATES": "VERİ SETİ ŞABLONLARI", "TEMPLATE": "ŞABLON", - "DMP-TEMPLATES": "VYP ŞABLONLARI", + "DMP-BLUEPRINTS-CAPS": "DMP BLUEPRINTS", "USERS-BREADCRUMB": "KULLANICILAR", "START-NEW-DMP": "Yeni bir VYP yaz", "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 +268,19 @@ "QUICK-WIZARD-DATASET": "Veri Seti ekle (Sihirbaz)", "ADD-EXPERT": "Yeni VYP (Uzman)", "MY-DATASET-DESC": "Veri Seti Tanımlamalarım", - "MY-DATASETS": "Veri Setlerim", + "MY-DESCRIPTIONS": "My Descriptions", "MY-GRANTS": "Hibelerim", "HISTORY": "TARİHÇE", "HISTORY-VISITED": "SON ZİYARET", "HISTORY-EDITED": "SON DÜZELTME", "PUBLIC": "YAYINLANDI", "PUBLIC-DMPS": "Yayınlanmış VYP'ları", - "PUBLIC-DESC": "Yayınlanmış Veri Seti Tanımları", + "PUBLIC-DESC": "Public Descriptions", "ACCOUNT": "HESAP", "ADMIN": "ADMIN", - "DATASET-TEMPLATES": "Veri Seti Şablonları", - "DMP-TEMPLATES": "VYP Şablonları", + "DESCRIPTION-TEMPLATES": "Description Templates", + "DESCRIPTION-TEMPLATE-TYPES": "Description Types", + "DMP-BLUEPRINTS": "DMP Blueprints", "USERS": "Kullanıcılar", "LANGUAGE-EDITOR": "Dil Editörü", "GUIDE-EDITOR": "Kullanıcı Rehberi Editörü", @@ -281,30 +291,34 @@ "DATASET-PROFILE-EDITOR": { "TITLE": { "NEW": "Yeni API İstemci", - "NEW-PROFILE": "Yeni Veri Seti Şablonu", + "NEW-PROFILE": "New Description Template", "NEW-PROFILE-VERSION": "Yeni Sürümü ", "NEW-PROFILE-CLONE": "Yeni Kopyası " }, "FIELDS": { - "DATASET-TITLE": "Veri Seti Şablonu İsmi", + "DATASET-TITLE": "Description Template Name", "DATASET-DESCRIPTION": "Tanım", "ROLES": "Görev" }, "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", + "DATASET-TEMPLATE-DESCRIPTION-HINT": "A brief description of what the Description is about, it's scope and objectives.", + "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", + "DESCRIPTION-TEMPLATE-PREFILLING": "Prefilling", + "DESCRIPTION-TEMPLATE-ENABLE-PREFILLING": "Enable prefilling", "DATASET-TEMPLATE-USERS": "Editors", "DATASET-TEMPLATE-USERS-HINT": "Add editors and save changes to notify them.", "DATASET-TEMPLATE-REMOVE-USER": "Remove Editor", "DATASET-TEMPLATE-NO-USERS-YET": "... No editors yet", "DATASET-TEMPLATE-VALIDATE-AND-ADD-USER": "Validate and Add Editor", - "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Dataset template description", + "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Template description", "UNTITLED": "Untitled", "QUESTION": "Question", "TEMPLATE-OUTLINE": "Template outline", @@ -314,7 +328,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": { @@ -446,6 +460,10 @@ "FIELD-AUTOCOMPLETE-SOURCE": "Kaynak", "FIELD-AUTOCOMPLETE-URL": "Url", "FIELD-AUTOCOMPLETE-OPTIONS-ROOT": "Options Root", + "FIELD-AUTOCOMPLETE-HAS-AUTH": "Has Authentication", + "FIELD-AUTOCOMPLETE-AUTH-METHOD": "Method", + "FIELD-AUTOCOMPLETE-AUTH-BODY": "Request Body", + "FIELD-AUTOCOMPLETE-AUTH-TYPE": "Authentication Type", "FIELD-DATE-PICKER-TITLE": "Tarih Seçici", "FIELD-DATE-PICKER-PLACEHOLDER": "Input Placeholder Text", "FIELD-DATE-PICKER-LABEL": "Etiket", @@ -615,7 +633,7 @@ "FINALIZED": "Kesinleşmiş", "PUBLISHED": "Yayınlanmış", "VERSION": "Sürüm", - "CONTAINED-DATASETS": "Veri Seti İçeren", + "CONTAINED-DESCRIPTIONS": "Contained Descriptions", "TEXT-INFO": "Bir VYP'deki bilgiler, veri setlerinin nasıl toplandığını ve / veya üretildiğini, nasıl işlendiğini, analiz edildiğini ve hangi araçları, standartları, metodolojileri v.b kullandığnı gösterir. Aynı zamanda veri setlerinin nerede ve nasıl yedeklendiğini, yayınlandığını, korunduğunu ve tüm bu faaliyetler için ayrılmış veri yönetimi hizmetlerini edinme veya oluşturma maliyetleri dahil olmak üzere tüm maliyetleri gösterir.", "TEXT-INFO-QUESTION": "VYP'nin pratikte nasıl göründüğünden emin değil misiniz? Açık Erişim VYP'lere göz atın ve", "LINK-ZENODO": "Zenodo'daki LIBER topluluğu", @@ -642,8 +660,8 @@ "INVITE-AUTHORS": "Yazarları Davet Et", "INVITE-SHORT": "Davet Et", "ADD-DATASET": "VYP'na Veri Seti Ekle", - "ADD-DATASET-DESCRIPTION": "Veri Seti Ekle", - "ADD-DATASET-SHORT": "Veri Seti Ekle", + "ADD-DESCRIPTION-SHORT": "Add Description", + "ADD-DESCRIPTION-FOR-SECTION": "Add Description", "DATASETS": "Tüm VYP Veri Seti Tanımlarını Listele", "NEW-VERSION": "Yeni Sürüm", "START-NEW-VERSION": "Yeni Sürümü Başlat", @@ -745,7 +763,7 @@ "DOWNLOAD-PDF": "PDF'i İndir", "DOWNLOAD-XML": "XML İndir", "DOWNLOAD-DOCX": "DOCX İndir", - "COPY-DATASET": "Veri Seti Tanımını Kopyala", + "COPY-DESCRIPTION": "Copy Description", "UPDATE-DATASET-PROFILE": "Şablonu Güncelle", "VALIDATE":"Validate", "UNDO-FINALIZATION-QUESTION" :"Undo finalization?", @@ -794,7 +812,7 @@ "GRANT": "Hibe", "DMP-AUTHORS": "VYP Yazarı", "RESEARCHERS": "Araştırmacılar", - "DATASETS-USED": "Veri Seti Kullanıcısı", + "DESCRIPTIONS-USED": "Descriptions used", "COLLABORATORS": "Ortaklar", "PUBLIC": "Açık Erişimli", "PRIVATE": "Gizli", @@ -826,10 +844,14 @@ "LOCKED-DIALOG":{ "TITLE": "DMP is locked", "MESSAGE":"Somebody else is modifying the DMP at this moment. If you would like to modify or view it, please come back later." + }, + "MIN-DESCRIPTIONS-DIALOG": { + "TITLE": "Min({{minMultiplicity}}) datasets needed using this template.", + "MESSAGE": "Add dataset." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Veri Seti Tanımları Yazarı", + "DESCRIPTION-AUTHORS": "Description authors", "ERROR": { "DELETED-DATASET": "Seçili Veri Seti silindi", "FORBIDEN-DATASET": "Bu veri setine erişim izniniz yok" @@ -846,9 +868,9 @@ }, "DATASET-LISTING": { "TITLE": "Veri seti Tanımları", - "DATASET-DESCRIPTION": "Veri Seti", - "SELECT-DATASETS-TO-CLONE": "Yeni VYP'na dahil edilecek Veri setini seçin. Seçilen Veri setleri düzenlenebilir.", - "SELECT-DATASETS-NONE": "Bu VYP için Veri Seti Tanımları mevcut değildir.", + "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": "Veri setleri, veri seti açıklamalarının içeriğini belirleyen önceden tanımlanmış şablonları takiben belgelenir. {{ APP_NAME }}'ta bir VYP, belgelediği veri setleri kadar veri seti açıklaması içerebilir. Gözat ", "TEXT-INFO-REST": " {{ APP_NAME }} VYP'lerde açıklanan veri setlerine gözat", "LINK-PUBLIC-DATASETS": "Açık Erişimli Veri Seti Tanımları", @@ -913,7 +935,7 @@ "EMPTY-LIST": "Burada Henüz Bir Şey Yok." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Veri Seti Şablonu", + "TITLE": "Description Templates", "COLUMNS": { "NAME": "İsim", "REFERNCE": "İlgili", @@ -941,9 +963,24 @@ "CLONE": "Çoğalt", "NEW-VERSION": "Yeni Sürüm", "NEW-VERSION-FROM-FILE": "New Version from File", - "VIEW-VERSIONS": "Tüm Veri Seti Tanımı Şablon Sürümleri", + "VIEW-VERSIONS": "All Description Template Versions", "DELETE": "Sil", - "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 +999,21 @@ "UNSUCCESSFUL": "Bir şeyler yanlış gitti" } }, + "DESCRIPTION-TYPE-EDITOR": { + "NEW": "New Description Type", + "FIELDS": { + "LABEL": "Name" + }, + "ACTIONS": { + "SAVE": "Save", + "FINALIZE": "Finalize", + "CANCEL": "Cancel" + } + }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Yeni VYP Şablonu", + "NEW": "New DMP Blueprint", + "NEW-PROFILE-CLONE": "New Clone Of ", "EDIT": "Düzenle" }, "FIELDS": { @@ -1024,7 +1073,7 @@ "EDIT": "Düzenle", "EDIT-DMP": "VYP'yi düzenleme", "ADD-DATASET": "Veri Seti ekle", - "EDIT-DATASET": "Veri Seti düzenle", + "EDIT-DESCRIPTION": "Editing Description", "CLONE-DMP": "Çoğalt", "NEW-VERSION": "Yeni Sürüm", "CREATE-DATASET": "Veri Seti Oluştur", @@ -1044,7 +1093,7 @@ "TEMPLATES": "Şablonlar", "TEMPLATE": "VYP Şablonu", "DATASET-TEMPLATES": "İlgili Veri Seti Şablonları", - "SELECT-TEMPLATE": "Veri S etini açıklamak için bir şablon seç", + "SELECT-TEMPLATE": "Select a template to describe your descriptions", "PROFILE": "VYP Şablonu", "PROJECT": "Proje", "GRANT": "Hibe", @@ -1065,7 +1114,7 @@ "PUBLICATION": "Yayın Tarihi", "CONTACT": "İletişim", "COST": "Maliyet", - "DATASETS": "Veri Setleri" + "DESCRIPTIONS": "Descriptions" }, "ACTIONS": { "GO-TO-GRANT": "VYP Hibesine Git", @@ -1094,10 +1143,10 @@ "SUCCESSFUL-DOI": "Başarılı DOI oluşumu", "UNSUCCESSFUL-FINALIZE": "Başarısız VYP bitirme" }, - "DATASET-TEMPLATE-LIST": { - "TITLE": "Kullanılabilir Veri Seti Şablonları", - "TEXT": "Veri Seti Profili seçildi: ", - "OK": "Tamam" + "DESCRIPTION-TEMPLATE-LIST": { + "TITLE": "Available Description Templates", + "TEXT": "Descriptions selected: ", + "OK": "OK" }, "VISIBILITY": { "PUBLIC": "Açık Erişimli", @@ -1108,7 +1157,7 @@ "MAIN-INFO": "Genel Bilgi", "FUNDING-INFO": "Fon Bilgisi", "DATASET-SELECTION": "Veri Seti Seçeneği", - "DATASET-INFO": "Veri Seti Bilgisi", + "DESCRIPTION-INFO": "Description info", "LICENSE-INFO": "Lisans Bilgisi", "DATASET": "Veri Seti", "PREVIOUS": "Önceki", @@ -1138,7 +1187,7 @@ "INTRO": "{{ APP_NAME }}'taki bir VYP, araştırma veri setlerinin dokümantasyonu, yani, takip edilen adımları ve veri yönetimi faaliyetlerinde kullanılan araçları vurgulayan veri seti açıklamaları gibi araştırmayla ilgili amaç, hedefler ve araştırmacılar gibi önemli bilgilerden oluşur.", "SECOND-INTRO": "Veri setleri, veri seti açıklamalarının içeriğini belirleyen önceden tanımlanmış şablonları takiben belgelenir. {{ APP_NAME }}'ta bir VYP, belgelediği veri setleri kadar çok veri seti açıklaması içerebilir.", "FIND": "Uygun bir tane bulamadınız mı?", - "HINT": "Veri setini açıklamak için bir şablon seç. Birden fazla şablon seçebilirsin." + "HINT": "Select a template to describe your descriptions. You may select more than one template." }, "LICENSE-INFO": { "INTRO": "Her VYP, ne kadar açık ve kullanılabilir olduğu konusunda belirli lisans bilgileri içerebilir, bu şekilde veri setini kimin görebileceğini ve bu verilerin ne kadar süreyle gizli kalacağını belirleyebilirsin", @@ -1160,8 +1209,8 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "VYP Şablonları", - "CREATE-DMP-TEMPLATE": "Create DMP Template", + "TITLE": "DMP Blueprints", + "CREATE-DMP-BLUEPRINT": "Create DMP Blueprint", "COLUMNS": { "NAME": "İsim", "STATUS": "Durum", @@ -1169,6 +1218,11 @@ "PUBLISHED": "Yayınlandı", "LAST-EDITED": "Son Düzenleme" }, + "ACTIONS": { + "CLONE": "Clone", + "DOWNLOAD-XML":"Download XML", + "DELETE": "Delete" + }, "UPLOAD": { "UPLOAD-XML": "İçeri Aktar", "UPLOAD-XML-FILE-TITLE": "Veri Yönetim Planı Şablonu İçeri Aktar", @@ -1218,8 +1272,8 @@ "NONE": "-", "TAGS": "Etiketler", "SELECT-TAGS": "Etiket Seç", - "LIKE": "Veri Setleri Arama", - "DRAFT-LIKE": "Taslak Veri Setleri Ara", + "LIKE": "Search Descriptions", + "DRAFT-LIKE": "Search Draft Descriptions", "SELECT-GRANTS": "Hibe Seçimi", "ROLE": "Görev", "ORGANIZATION": "Kuruluş", @@ -1243,6 +1297,10 @@ "SELECT-DATASET-TEMPLATES": "Veri Seti Şablonu Seçin", "RELATED-DATASET-TEMPLATES": "İlgili Veri Seti Şablonları" }, + "BLUEPRINT": { + "LIKE": "Search", + "STATUS": "Status" + }, "USERS": { "LABEL": "Arama", "ROLE": "Görev", @@ -1255,12 +1313,12 @@ "TITLE": { "NEW": "Yeni Veri Yönetim Planı", "EDIT": "Düzenle", - "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": "Veri Setinin Adı", - "TITLE": "Veri Setinin Başlığı", + "TITLE": "Title of Description", "DESCRIPTION": "Tanım", "PROFILE": "Şablon", "URI": "Uri", @@ -1298,7 +1356,7 @@ "EXTERNAL-LINK": "Dışarıdan bir URL bağlantısı sağla" }, "HINT": { - "DESCRIPTION": "Briefly describe the context and purpose of the Dataset", + "DESCRIPTION": "Briefly describe the context and purpose of the Description", "TITLE": "Ne olduğuna dair kısa bir açıklama ", "TITLE-REST": " Kapsam ve hedeflerle ilgili." }, @@ -1315,6 +1373,10 @@ "VIEW-MORE": "View more", "VIEW-LESS": "View less" } + }, + "MAX-DESCRIPTION-DIALOG": { + "TITLE": "Max datasets using this template.", + "MESSAGE": "Select another profile." } }, "DATASET-CREATE-WIZARD": { @@ -1328,13 +1390,13 @@ "PLACEHOLDER": "Mevcut olan bir VYP seçin" }, "PREFILL-STEP": { - "TITLE": "Initialize your Dataset", + "TITLE": "Initialize your Description", "PREFILL": "Prefill", "OR": "OR", - "HINT": "Select the dataset from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", + "HINT": "Select an entry from Zenodo to automatically retrieve answers to some questions in your template or start by answering the questions manually.", "MANUALLY": "Manually", - "PROFILE": "Dataset Template", - "PREFILLED-DATASET": "Prefilled Dataset", + "PROFILE": "Description Template", + "PREFILLED-DATASET": "Prefilled Description", "SEARCH": "Start typing to search for a dataset or software", "NEXT": "Next" } @@ -1370,7 +1432,7 @@ "ADMIN": "Admin", "USER": "Kullanıcı", "MANAGER": "Yönetici", - "DATASET-TEMPLATE-EDITOR": "Veri Seti Şablon Düzenleyicisi" + "DESCRIPTION-TEMPLATE-EDITOR": "Description Template Editor" }, "DMP-PROFILE-FIELD": { "DATA-TYPE": { @@ -1648,7 +1710,7 @@ "DATA-MANAGEMENT-PLANS": "VERİ YÖNETİM PLANLARI", "PERSONAL-USAGE": "Kişisel Kullanım", "PUBLIC-USAGE": "Genel Kullanım", - "DATASET-DESCRIPTIONS": "Veri Setleri", + "DESCRIPTIONS": "Descriptions", "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Veri Setleri", "PUBLIC-DMPS": "Herkese açık VYP'ler", "PUBLIC-DATASETS": "Herkese açık Veri Setleri", @@ -1661,7 +1723,7 @@ "DMP-ABOUT-END": ", Veri yönetimi faaliyetlerinde izlenen adımları ve kullanılan araçları vurgulayan", "SELECT-DMP": "Veri Setiniz için bir VYP seçin", "ACTIONS": { - "ADD-DATASET-DESCRIPTION": "Veri Seti Ekle", + "ADD-DESCRIPTION": "Add Description", "ADD-DATASET": "Veri Seti Ekle", "ADD-DMP-DESCRIPTION": "VYP Tanımı Ekle" }, @@ -1687,18 +1749,19 @@ "LOG-OUT": "Çıkış Yap" }, "USER-PROFILE": { + "MERGING-SUCCESS": "Linking of the two profiles was successful.", "MERGING-EMAILS-DIALOG": { "TITLE": "Verify linked account", "MESSAGE": "An email to verify this action has been sent to you. Once accepted, you will be able to see your accounts merged. The last email account that you merge will be the one containing all of your DMP records and activity in {{ APP_NAME }}." }, "UNLINK-ACCOUNT": { "TITLE": "Verify account to be unlinked", - "MESSAGE": "An email to verify this action has been sent to you. Once accepted, {{accountToBeUnlinked}} will be unlinked." + "MESSAGE": "An email to verify this action has been sent to your main account. Once accepted, {{accountToBeUnlinked}} will be no longer connected to your current ARGOS profile." }, "UNLINK-ACCOUNT-DIALOG": { "MESSAGE": "By clicking \"Confirm\", you accept the transfer of your ARGOS activity performed from this account to your main ARGOS account, which is the one that is listed first. By logging in again with the unlinked account, you will be able to start your ARGOS experience from scratch, in an empty dashboard.", "CONFIRM": "Confirm", - "CANCEL": "Cancel" + "CANCEL": "Cancel" }, "SETTINGS": { "TITLE": "Ayarlar", @@ -1745,7 +1808,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", @@ -1914,5 +1977,11 @@ "DRAFT": "Taslak", "FINALIZED": "Tamamlandı", "DELETED": "Silindi" + }, + "BLUEPRINT-STATUS": { + "NONE": "None", + "DRAFT": "Draft", + "FINALIZED": "Finalized", + "DELETED": "Deleted" } } diff --git a/dmp-frontend/src/assets/images/new-releases-logo.png b/dmp-frontend/src/assets/images/new-releases-logo.png new file mode 100644 index 000000000..7c5e9da2e Binary files /dev/null and b/dmp-frontend/src/assets/images/new-releases-logo.png differ diff --git a/dmp-frontend/src/assets/resources/skipDisable.json b/dmp-frontend/src/assets/resources/skipDisable.json index b0d92f82e..3a0850e64 100644 --- a/dmp-frontend/src/assets/resources/skipDisable.json +++ b/dmp-frontend/src/assets/resources/skipDisable.json @@ -8,9 +8,6 @@ "FieldSetEditorModel.extendedDescription", "FieldSetEditorModel.additionalInformation", "TextAreaFieldDataEditorModel.label", - "FreeTextFieldDataEditorModel.label", - "WordListFieldDataEditorModel.label", - "FieldDataOptionEditorModel.label", "FieldSetEditorModel.schematics", "FieldSetEditorModel.export" ] diff --git a/dmp-frontend/src/assets/scss/core/_type.scss b/dmp-frontend/src/assets/scss/core/_type.scss index a46c698be..c65d55b04 100644 --- a/dmp-frontend/src/assets/scss/core/_type.scss +++ b/dmp-frontend/src/assets/scss/core/_type.scss @@ -90,3 +90,13 @@ h2.title{ .text-gray{ color: $gray-color !important; } + +blockquote { + margin-left: 1rem; + border-left: .2em solid #dfe2e5; + padding-left: .5rem; +} + +.highlight { + background-color: lightgoldenrodyellow; +} diff --git a/dmp-frontend/src/assets/splash/about/contributors.html b/dmp-frontend/src/assets/splash/about/contributors.html index e42f65946..fc5e0d98e 100644 --- a/dmp-frontend/src/assets/splash/about/contributors.html +++ b/dmp-frontend/src/assets/splash/about/contributors.html @@ -88,6 +88,7 @@

    Consorcio Madroño

    Lanko López, Juan Corrales Correyero, Fernando González Ballesteros

    +

    Mondragon Unibertsitatea Library (in Basque)

    diff --git a/repo-jars/dataverse.json b/repo-jars/dataverse.json index 473d94515..680018a1c 100644 --- a/repo-jars/dataverse.json +++ b/repo-jars/dataverse.json @@ -1,11 +1,13 @@ -{ - "depositType": 0, - "repositoryId": "Dataverse", - "apiToken": "", - "repositoryUrl": "https://demo.dataverse.org/api/", - "repositoryRecordUrl": "https://demo.dataverse.org/dataset.xhtml?persistentId=doi:", - "server": "https://demo.dataverse.org", - "parentDataverseAlias": "test1000" - "parentDataverseAlias": "test1000", - "hasLogo": false -} \ No newline at end of file +[ + { + "depositType": 0, + "repositoryId": "Dataverse", + "apiToken": "", + "repositoryUrl": "https://demo.dataverse.org/api/", + "repositoryRecordUrl": "https://demo.dataverse.org/dataset.xhtml?persistentId=doi:", + "server": "https://demo.dataverse.org", + "parentDataverseAlias": "test1000", + "hasLogo": true, + "logo": "dataverse.png" + } +] \ No newline at end of file diff --git a/repo-jars/zenodo.json b/repo-jars/zenodo.json index cd77e1ed4..3d5e3916c 100644 --- a/repo-jars/zenodo.json +++ b/repo-jars/zenodo.json @@ -1,14 +1,20 @@ -{ - "depositType": 2, - "repositoryId": "Zenodo", - "accessToken": "", - "repositoryUrl": "https://sandbox.zenodo.org/api/", - "repositoryAuthorizationUrl": "https://sandbox.zenodo.org/oauth/authorize", - "repositoryRecordUrl": "https://sandbox.zenodo.org/record/", - "repositoryAccessTokenUrl": "https://sandbox.zenodo.org/oauth/token", - "repositoryClientId": "", - "repositoryClientSecret": "", - "redirectUri": "http://localhost:4200/login/external/zenodo" - "redirectUri": "http://localhost:4200/login/external/zenodo", - "hasLogo": true -} \ No newline at end of file +[ + { + "depositType": 2, + "repositoryId": "Zenodo", + "accessToken": "", + "repositoryUrl": "https://sandbox.zenodo.org/api/", + "repositoryAuthorizationUrl": "https://sandbox.zenodo.org/oauth/authorize", + "repositoryRecordUrl": "https://sandbox.zenodo.org/record/", + "repositoryAccessTokenUrl": "https://sandbox.zenodo.org/oauth/token", + "repositoryClientId": "", + "repositoryClientSecret": "", + "redirectUri": "http://localhost:4200/login/external/zenodo", + "hasLogo": true, + "logo": "zenodo.jpg", + "doiFunder": "DOI_Funder.json", + "community": "argos", + "affiliation": "ARGOS", + "domain": "https://argos.openaire.eu/" + } +] \ No newline at end of file