diff --git a/dmp-backend/Dockerfile.CI b/dmp-backend/Dockerfile.CI index 866a3a692..5747c9969 100644 --- a/dmp-backend/Dockerfile.CI +++ b/dmp-backend/Dockerfile.CI @@ -12,4 +12,4 @@ RUN mvn package FROM adoptopenjdk/openjdk11:alpine-jre WORKDIR /app COPY --from=MAVEN_BUILD /build/web/target/web-1.0-SNAPSHOT.jar /app/app.jar -ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dspring.profiles.active=${PROF}", "-Dspring.config.additional-location=/files/config/", "-jar","/app/app.jar"] +ENTRYPOINT ["java", "-Djava.security.egd=file:/dev/./urandom", "-Dspring.profiles.active=${PROF}", "-Dspring.config.additional-location=/files/config/", "-cp", "/app/app.jar", "-Dloader.path=/files/repo-jars", "org.springframework.boot.loader.PropertiesLauncher"] 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 ca33c0830..ac8ce47d7 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 @@ -87,7 +87,7 @@ public class DMPDaoImpl extends DatabaseAccess implements DMPDao { } if (criteria.hasDoi()) { - query.where((builder, root) -> builder.not(builder.isNull(root.get("doi")))); + query.where((builder, root) -> builder.not(builder.isNull(root.join("dois").get("id")))); } query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue())); return query; diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java index 5df4bdf88..d996ea95e 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetDaoImpl.java @@ -80,7 +80,7 @@ public class DatasetDaoImpl extends DatabaseAccess implements DatasetDa query.where((builder, root) -> root.get("profile").get("id").in(criteria.getDatasetTemplates())); if (criteria.hasDoi()) { - query.where((builder, root) -> builder.not(builder.isNull(root.get("dmp").get("doi")))); + query.where((builder, root) -> builder.not(builder.isNull(root.join("dmp").join("dois").get("id")))); } query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.DELETED.getValue())); query.where((builder, root) -> builder.notEqual(root.get("status"), Dataset.Status.CANCELED.getValue())); diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDao.java new file mode 100644 index 000000000..ebc6aad1a --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDao.java @@ -0,0 +1,10 @@ +package eu.eudat.data.dao.entities; + +import eu.eudat.data.dao.DatabaseAccessLayer; +import eu.eudat.data.entities.EntityDoi; + +import java.util.UUID; + +public interface EntityDoiDao extends DatabaseAccessLayer { + EntityDoi findFromDoi(String doi); +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDaoImpl.java new file mode 100644 index 000000000..4eaf59b87 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/EntityDoiDaoImpl.java @@ -0,0 +1,56 @@ +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.EntityDoi; +import eu.eudat.queryable.QueryableList; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +@Component("EntityDoiDao") +public class EntityDoiDaoImpl extends DatabaseAccess implements EntityDoiDao { + + @Autowired + public EntityDoiDaoImpl(DatabaseService databaseService){ + super(databaseService); + } + + + @Override + public EntityDoi createOrUpdate(EntityDoi item) { + return this.getDatabaseService().createOrUpdate(item, EntityDoi.class); + } + + @Override + public CompletableFuture createOrUpdateAsync(EntityDoi item) { + return CompletableFuture.supplyAsync(() -> this.createOrUpdate(item)); + } + + @Override + public EntityDoi find(UUID id) { + return this.getDatabaseService().getQueryable(EntityDoi.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); + } + + @Override + public EntityDoi findFromDoi(String doi) { + return this.getDatabaseService().getQueryable(EntityDoi.class).where((builder, root) -> builder.equal(root.get("doi"), doi)).getSingle(); + } + + @Override + public EntityDoi find(UUID id, String hint) { + return null; + } + + @Override + public void delete(EntityDoi item) { + this.getDatabaseService().delete(item); + } + + @Override + public QueryableList asQueryable() { + return this.getDatabaseService().getQueryable(EntityDoi.class); + } +} diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDao.java index 868a58e71..c334b63d4 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDao.java @@ -3,7 +3,9 @@ package eu.eudat.data.dao.entities; import eu.eudat.data.dao.DatabaseAccessLayer; import eu.eudat.data.entities.FileUpload; +import java.util.List; import java.util.UUID; public interface FileUploadDao extends DatabaseAccessLayer { + List getFileUploads(UUID entityId); } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDaoImpl.java index d50780bc5..47cc10066 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/FileUploadDaoImpl.java @@ -7,6 +7,7 @@ import eu.eudat.queryable.QueryableList; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; +import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -33,6 +34,11 @@ public class FileUploadDaoImpl extends DatabaseAccess implements Fil return getDatabaseService().getQueryable(FileUpload.class).where((builder, root) -> builder.equal(root.get("id"), id)).getSingle(); } + @Override + public List getFileUploads(UUID entityId) { + return this.getDatabaseService().getQueryable(FileUpload.class).where((builder, root) -> builder.equal(root.get("entityId"), entityId)).toList(); + } + @Override public FileUpload find(UUID id, String hint) { return null; 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 b4f212210..cbd796ca2 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 @@ -181,8 +181,8 @@ public class DMP implements DataEntity { @Convert(converter = DateToUTCConverter.class) private Date publishedAt; - @Column(name = "\"DOI\"") - private String doi; + @OneToMany(mappedBy = "entityId", fetch = FetchType.LAZY) + private Set dois; @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "\"Project\"") @@ -339,12 +339,12 @@ public class DMP implements DataEntity { this.publishedAt = publishedAt; } - public String getDoi() { - return doi; - } - public void setDoi(String doi) { - this.doi = doi; - } + public Set getDois() { + return dois; + } + public void setDois(Set dois) { + this.dois = dois; + } public Project getProject() { return project; @@ -380,7 +380,7 @@ public class DMP implements DataEntity { if (entity.getStatus().equals(DMPStatus.FINALISED.getValue())) this.setFinalizedAt(new Date()); if (entity.isPublic) this.setPublishedAt(new Date()); if (entity.getUsers() != null) this.users = entity.getUsers(); - if (entity.getDoi() != null && entity.getDoi().trim().isEmpty()) this.doi = entity.doi; + this.dois = entity.getDois(); this.extraProperties = entity.getExtraProperties(); } diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/entities/EntityDoi.java b/dmp-backend/data/src/main/java/eu/eudat/data/entities/EntityDoi.java new file mode 100644 index 000000000..a0b86c6c5 --- /dev/null +++ b/dmp-backend/data/src/main/java/eu/eudat/data/entities/EntityDoi.java @@ -0,0 +1,121 @@ +package eu.eudat.data.entities; + +import eu.eudat.data.converters.DateToUTCConverter; +import eu.eudat.data.entities.helpers.EntityBinder; +import eu.eudat.queryable.queryableentity.DataEntity; +import org.hibernate.annotations.Type; + +import javax.persistence.*; +import java.util.Arrays; +import java.util.Date; +import java.util.List; +import java.util.UUID; +import java.util.stream.Collectors; + +@Entity +@Table(name = "\"EntityDoi\"") +public class EntityDoi implements DataEntity { + public enum EntityType { + DMP + } + + @Id + @Column(name = "\"ID\"", updatable = false, nullable = false, columnDefinition = "BINARY(16)") + private UUID id; + + @Enumerated(EnumType.STRING) + @Type(type = "eu.eudat.configurations.typedefinition.PostgreSQLEnumType") + @Column(name = "\"EntityType\"", nullable = false) + private EntityType entityType; + + @Column(name = "\"RepositoryId\"", nullable = false) + private String repositoryId; + + @Column(name = "\"Doi\"", nullable = false) + private String doi; + + @Column(name = "\"CreatedAt\"", nullable = false) + @Convert(converter = DateToUTCConverter.class) + private Date createdAt; + + @Column(name = "\"UpdatedAt\"", nullable = false) + @Convert(converter = DateToUTCConverter.class) + private Date updatedAt; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "\"EntityId\"", nullable = false) + private DMP entityId; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public EntityType getEntityType() { + return entityType; + } + public void setEntityType(EntityType entityType) { + this.entityType = entityType; + } + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDoi() { + return doi; + } + public void setDoi(String doi) { + this.doi = doi; + } + + public Date getCreatedAt() { + return createdAt; + } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public DMP getEntityId() { + return entityId; + } + public void setEntityId(DMP entityId) { + this.entityId = entityId; + } + + @Override + public void update(EntityDoi doi) { + this.entityType = doi.getEntityType(); + this.repositoryId = doi.getRepositoryId(); + this.doi = doi.getDoi(); + this.createdAt = doi.getCreatedAt(); + this.updatedAt = doi.getUpdatedAt(); + this.entityId = doi.getEntityId(); + } + + @Override + public UUID getKeys() { + return this.id; + } + + @Override + public EntityDoi buildFromTuple(List tuple, List fields, String base) { + String currentBase = base.isEmpty() ? "" : base + "."; + if (fields.contains(currentBase + "id")) this.id = EntityBinder.fromTuple(tuple, currentBase + "id"); + if (fields.contains(currentBase + "entityId")) + this.entityId = tuple.stream().map(x -> new DMP().buildFromTuple(Arrays.asList(x), fields , base.isEmpty() ? "entityId" : base + "." + "entityId")).collect(Collectors.toList()).get(0); + 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 a7ca04c6a..8d5129521 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 @@ -57,7 +57,7 @@ public class Dmp implements ElasticEntity { private Date modified; private Date finalizedAt; private Date publishedAt; - private String doi; + private List dois; public UUID getId() { return id; @@ -203,12 +203,12 @@ public class Dmp implements ElasticEntity { this.publishedAt = publishedAt; } - public String getDoi() { - return doi; + public List getDois() { + return dois; } - public void setDoi(String doi) { - this.doi = doi; + public void setDois(List dois) { + this.dois = dois; } @Override @@ -280,7 +280,17 @@ public class Dmp implements ElasticEntity { builder.field(MapKey.MODIFIED.getName(), this.modified); builder.field(MapKey.FINALIZEDAT.getName(), this.finalizedAt); builder.field(MapKey.PUBLISHEDAT.getName(), this.publishedAt); - builder.field(MapKey.DOI.getName(), this.doi); + if (this.dois != null && !this.dois.isEmpty()) { + builder.startArray(MapKey.DOIS.getName()); + this.dois.forEach(doi -> { + try { + doi.toElasticEntity(builder); + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + }); + builder.endArray(); + } builder.endObject(); return builder; } @@ -329,8 +339,8 @@ public class Dmp implements ElasticEntity { if (fields.get(MapKey.PUBLISHEDAT.getName()) != null) { this.publishedAt = Date.from(Instant.parse(fields.get(MapKey.PUBLISHEDAT.getName()).toString())); } - if (fields.get(MapKey.DOI.getName()) != null) { - this.doi = fields.get(MapKey.DOI.getName()).toString(); + if (fields.get(MapKey.DOIS.getName()) != null) { + this.dois = ((List>) fields.get(MapKey.DOIS.getName())).stream().map(map -> new Doi().fromElasticEntity(map)).collect(Collectors.toList()); } } return this; @@ -355,7 +365,7 @@ public class Dmp implements ElasticEntity { MODIFIED ("modified"), FINALIZEDAT ("finalizedAt"), PUBLISHEDAT ("publishedAt"), - DOI ("doi"); + DOIS ("dois"); private final String name; diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Doi.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Doi.java new file mode 100644 index 000000000..0b990a437 --- /dev/null +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/entities/Doi.java @@ -0,0 +1,65 @@ +package eu.eudat.elastic.entities; + +import org.elasticsearch.common.xcontent.XContentBuilder; + +import java.io.IOException; +import java.util.Map; +import java.util.UUID; + +public class Doi implements ElasticEntity{ + private UUID id; + private String repositoryId; + private String doi; + private UUID dmp; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDoi() { + return doi; + } + public void setDoi(String doi) { + this.doi = doi; + } + + public UUID getDmp() { + return dmp; + } + public void setDmp(UUID dmp) { + this.dmp = dmp; + } + + @Override + public XContentBuilder toElasticEntity(XContentBuilder builder) throws IOException { + builder.startObject(); + builder.field("id", this.id.toString()); + builder.field("repositoryId", this.repositoryId); + builder.field("doi", this.doi); + builder.field("dmp", this.dmp.toString()); + builder.endObject(); + return builder; + } + + @Override + public Doi fromElasticEntity(Map fields) { + if (fields == null || fields.isEmpty()) { + return null; + } + this.id = UUID.fromString((String) fields.get("id")); + this.repositoryId = (String) fields.get("repositoryId"); + this.doi = (String) fields.get("doi"); + this.dmp = UUID.fromString((String) fields.get("dmp")); + return this; + } +} diff --git a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java index 11c7d1bca..68e329396 100644 --- a/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java +++ b/dmp-backend/elastic/src/main/java/eu/eudat/elastic/repository/ElasticRepository.java @@ -30,6 +30,7 @@ public abstract class ElasticRepositoryjar + + intellij-properties-launcher + + + + org.springframework.boot + spring-boot-loader + 2.5.2 + + + + production diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index ff1544df4..8d9e4047b 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -26,13 +26,16 @@ queryable 1.0-SNAPSHOT - eu.eudat elastic 1.0.0-SNAPSHOT - + + gr.cite.opendmp + repositorydepositbase + 1.0.1 + @@ -221,6 +224,39 @@ spring-boot-maven-plugin 1.5.9.RELEASE + + org.apache.maven.plugins + maven-jar-plugin + 2.4 + + + + true + eu.eudat.EuDatApplication + dependency-jars/ + + + + + + org.apache.maven.plugins + maven-dependency-plugin + 2.5.1 + + + copy-dependencies + package + + copy-dependencies + + + + ${project.build.directory}/dependency-jars/ + + + + + diff --git a/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java b/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java index 31e87ddf5..5ed228762 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java +++ b/dmp-backend/web/src/main/java/eu/eudat/EuDatApplication.java @@ -8,7 +8,7 @@ import org.springframework.boot.builder.SpringApplicationBuilder; import org.springframework.boot.web.servlet.support.SpringBootServletInitializer; import org.springframework.scheduling.annotation.EnableAsync; -@SpringBootApplication +@SpringBootApplication(scanBasePackages = {"eu.eudat", "eu.eudat.depositinterface"}) @EnableAsync public class EuDatApplication extends SpringBootServletInitializer { private static final Logger logger = LoggerFactory.getLogger(EuDatApplication.class); diff --git a/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java index 49f7de4b4..70690ff62 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/configurations/ElasticSearchConfiguration.java @@ -4,6 +4,7 @@ import org.apache.http.HttpHost; import org.apache.http.auth.AuthScope; import org.apache.http.auth.UsernamePasswordCredentials; import org.apache.http.client.CredentialsProvider; +import org.apache.http.conn.ssl.NoopHostnameVerifier; import org.apache.http.conn.ssl.TrustSelfSignedStrategy; import org.apache.http.impl.client.BasicCredentialsProvider; import org.apache.http.impl.nio.conn.PoolingNHttpClientConnectionManager; @@ -72,29 +73,34 @@ public class ElasticSearchConfiguration { RestHighLevelClient client; if(this.environment.getProperty("elasticsearch.usingssl", Boolean.class)){ - Path caCertificatePath = Paths.get(this.environment.getProperty("elasticsearch.certPath")); - CertificateFactory factory = - CertificateFactory.getInstance("X.509"); - Certificate trustedCa; - try (InputStream is = Files.newInputStream(caCertificatePath)) { - trustedCa = factory.generateCertificate(is); - } - KeyStore trustStore = KeyStore.getInstance("pkcs12"); - trustStore.load(null, null); - trustStore.setCertificateEntry("ca", trustedCa); - - TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); - tmf.init(trustStore); - - SSLContext sslContext = SSLContext.getInstance("TLS"); - sslContext.init(null, tmf.getTrustManagers(), null); +// Path caCertificatePath = Paths.get(this.environment.getProperty("elasticsearch.certPath")); +// CertificateFactory factory = +// CertificateFactory.getInstance("X.509"); +// Certificate trustedCa; +// try (InputStream is = Files.newInputStream(caCertificatePath)) { +// trustedCa = factory.generateCertificate(is); +// } +// KeyStore trustStore = KeyStore.getInstance("pkcs12"); +// trustStore.load(null, null); +// trustStore.setCertificateEntry("ca", trustedCa); +// +// TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); +// tmf.init(trustStore); +// +// SSLContext sslContext = SSLContext.getInstance("TLS"); +// sslContext.init(null, tmf.getTrustManagers(), null); + SSLContextBuilder sslBuilder = SSLContexts.custom() + .loadTrustMaterial(null, (x509Certificates, s) -> true); + final SSLContext sslContext = sslBuilder.build(); client = new RestHighLevelClient( RestClient.builder( new HttpHost(this.environment.getProperty("elasticsearch.host"), Integer.parseInt(this.environment.getProperty("elasticsearch.port")), "https")) .setHttpClientConfigCallback(httpClientBuilder -> httpClientBuilder - .setDefaultCredentialsProvider(credentialsProvider).setSSLContext(sslContext))); + .setDefaultCredentialsProvider(credentialsProvider).setSSLHostnameVerifier(NoopHostnameVerifier.INSTANCE).setSSLContext(sslContext)) + .setRequestConfigCallback(requestConfigBuilder -> requestConfigBuilder.setConnectTimeout(5000).setSocketTimeout(120000)) + ); } else { client = new RestHighLevelClient( diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java new file mode 100644 index 000000000..c0cf489d1 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DepositController.java @@ -0,0 +1,84 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.managers.DepositManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.doi.DepositCode; +import eu.eudat.models.data.doi.DepositRequest; +import eu.eudat.models.data.doi.Doi; +import eu.eudat.models.data.doi.RepositoryConfig; +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.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.util.List; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/deposit/"}) +public class DepositController extends BaseController { + private static final Logger logger = LoggerFactory.getLogger(DepositController.class); + + private DepositManager depositManager; + + @Autowired + public DepositController(ApiContext apiContext, DepositManager depositManager){ + super(apiContext); + this.depositManager = depositManager; + } + + @RequestMapping(method = RequestMethod.GET, value = {"/repos"}) + public @ResponseBody + ResponseEntity>> getAvailableRepos(@ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { + List ids = this.depositManager.getAvailableRepos(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.NO_MESSAGE).payload(ids)); + } + + @RequestMapping(method = RequestMethod.POST, value = {"/getAccessToken"}) + public @ResponseBody + ResponseEntity> getAccessToken(@RequestBody DepositCode depositCode, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + String accessToken = this.depositManager.authenticate(depositCode.getRepositoryId(), depositCode.getCode()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(accessToken)); + } + + @RequestMapping(method = RequestMethod.POST, value = {"/createDoi"}) + public @ResponseBody + ResponseEntity> createDoi(@RequestBody DepositRequest depositRequest, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { + try { + Doi doi = this.depositManager.deposit(depositRequest, principal); + if(doi != null){ + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully created DOI for Data Datamanagement Plan in question.").payload(doi)); + } + else{ + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create DOI for the Data Management Plan")); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create DOI for the Data Management Plan: " + e.getMessage())); + } + } + + @RequestMapping(method = RequestMethod.GET, value = {"/logo/{repositoryId}"}) + public @ResponseBody + ResponseEntity> getLogo(@PathVariable("repositoryId") String repositoryId, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { + try { + String encodedLogo = this.depositManager.getRepositoryLogo(repositoryId); + if(encodedLogo != null){ + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully loaded " + repositoryId + "'s logo.").payload(encodedLogo)); + } + else{ + return ResponseEntity.status(HttpStatus.NOT_FOUND).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(repositoryId + " has no logo").payload(null)); + } + } catch (Exception e) { + logger.error(e.getMessage(), e); + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to load " + repositoryId + "'s logo: " + e.getMessage())); + } + } +} 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 f492e2a9d..25ab0217a 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 @@ -15,6 +15,8 @@ import eu.eudat.data.enumeration.notification.NotifyState; import eu.eudat.data.query.items.table.dataset.DatasetTableRequest; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.data.query.items.table.dmp.DataManagementPlanTableRequest; +import eu.eudat.depositinterface.models.DMPDepositModel; +import eu.eudat.depositinterface.repository.RepositoryDeposit; import eu.eudat.elastic.criteria.DmpCriteria; import eu.eudat.elastic.entities.Collaborator; import eu.eudat.elastic.entities.Dmp; @@ -29,6 +31,7 @@ import eu.eudat.logic.builders.entity.UserInfoBuilder; import eu.eudat.logic.mapper.elastic.DmpMapper; import eu.eudat.logic.mapper.elastic.criteria.DmpCriteriaMapper; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; +import eu.eudat.logic.security.repositorydeposit.mapper.DMPToDepositMapper; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.forms.VisibilityRuleService; import eu.eudat.logic.services.forms.VisibilityRuleServiceImpl; @@ -45,6 +48,8 @@ import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; import eu.eudat.models.data.datasetwizard.DatasetsToBeFinalized; 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; @@ -57,11 +62,10 @@ import eu.eudat.models.data.project.ProjectDMPEditorModel; import eu.eudat.models.data.security.Principal; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.models.data.userinfo.UserListingModel; -import eu.eudat.models.deposit.zenodo.ZenodoDeposit; -import eu.eudat.models.deposit.zenodo.mapper.DMPToZenodoMapper; import eu.eudat.queryable.QueryableList; import eu.eudat.types.Authorities; import eu.eudat.types.MetricNames; +import org.apache.commons.io.IOUtils; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.apache.poi.xwpf.usermodel.XWPFParagraph; import org.apache.poi.xwpf.usermodel.XWPFRun; @@ -70,11 +74,8 @@ import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; -import org.springframework.core.io.FileSystemResource; import org.springframework.http.*; import org.springframework.stereotype.Component; -import org.springframework.web.client.HttpClientErrorException; -import org.springframework.web.client.HttpServerErrorException; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; @@ -86,6 +87,7 @@ 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; @@ -93,6 +95,8 @@ import java.util.*; import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; import java.util.stream.Stream; +import java.util.zip.ZipEntry; +import java.util.zip.ZipOutputStream; @Component public class DataManagementPlanManager { @@ -114,9 +118,11 @@ public class DataManagementPlanManager { private UserManager userManager; private final MetricsManager metricsManager; private final ConfigLoader configLoader; + private List repositoriesDeposit; @Autowired - public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, MetricsManager metricsManager, ConfigLoader configLoader) { + public DataManagementPlanManager(ApiContext apiContext, DatasetManager datasetManager, Environment environment, RDAManager rdaManager, UserManager userManager, + MetricsManager metricsManager, ConfigLoader configLoader, List repositoriesDeposit) { this.apiContext = apiContext; this.datasetManager = datasetManager; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); @@ -126,6 +132,7 @@ public class DataManagementPlanManager { this.metricsManager = metricsManager; this.configLoader = configLoader; this.objectMapper = new ObjectMapper(); + this.repositoriesDeposit = repositoriesDeposit; } /* @@ -749,7 +756,7 @@ public class DataManagementPlanManager { metricsManager.decreaseValue(MetricNames.DMP, 1, MetricNames.DRAFT); break; case 1: - if (oldDmp.getDoi() != null) { + if (oldDmp.getDois() != null && !oldDmp.getDois().isEmpty()) { metricsManager.decreaseValue(MetricNames.DMP, 1, MetricNames.DOIED); } if (oldDmp.isPublic()) { @@ -1057,9 +1064,9 @@ public class DataManagementPlanManager { }); UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); sendNotification(dmp, user, NotificationType.DMP_PUBLISH); - if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) { - this.createZenodoDoi(dmp.getId(), principal, true); - } +// if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { +// this.createZenodoDoi(dmp.getId(), principal, true); +// } } @Transactional @@ -1151,6 +1158,10 @@ public class DataManagementPlanManager { throw new Exception("User does not have the privilege to do this action."); if (dmp.getStatus().equals(DMP.DMPStatus.ACTIVE.getValue())) throw new Exception("DMP is already Active"); + if (dmp.isPublic()) + throw new Exception("DMP is publicly available"); + if (!dmp.getDois().isEmpty()) + throw new Exception("DMP is deposited"); dmp.setStatus(DMP.DMPStatus.ACTIVE.getValue()); apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); UUID dmpId = dmp.getId(); @@ -2006,23 +2017,28 @@ public class DataManagementPlanManager { * DOI Generation * */ - private String getPreviousDOI(UUID groupId, UUID selfId) { + private String getPreviousDOI(UUID groupId, UUID selfId, String repositoryId) { DataManagementPlanCriteria criteria = new DataManagementPlanCriteria(); List groupIds = new ArrayList<>(); groupIds.add(groupId); criteria.setGroupIds(groupIds); criteria.setAllVersions(true); List dmps = this.databaseRepository.getDmpDao().getWithCriteria(criteria).toList(); - String doi = null; + dmps.sort((DMP d1, DMP d2) -> d2.getVersion() - d1.getVersion()); for (DMP dmp: dmps) { if (!dmp.getId().equals(selfId)) { - if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) { - doi = dmp.getDoi(); + if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { + for (Iterator it = dmp.getDois().iterator(); it.hasNext(); ) { + EntityDoi entityDoi = it.next(); + if(entityDoi.getRepositoryId().equals(repositoryId)){ + return entityDoi.getDoi(); + } + } } } } - return doi; + return null; } private String getUnpublishedDOI(String DOI, String token, Integer version) { @@ -2064,6 +2080,22 @@ public class DataManagementPlanManager { /*if (dmp.getDoi() != null) throw new Exception("DMP already has a DOI");*/ + FileEnvelope file = getWordDocument(id.toString(), principal, configLoader); + String name = file.getFilename().substring(0, file.getFilename().length() - 5); + File pdfFile = PDFUtils.convertToPDF(file, environment); + String fileName = name + ".pdf"; + ResponseEntity jsonFile; + try { + jsonFile = getRDAJsonDocument(id.toString(), principal); + } catch (Exception e) { + throw e; + } + String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), "Zenodo"); + + File supportingFilesZip = this.createSupportingFilesZip(dmp); + + DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, supportingFilesZip, previousDOI); + String zenodoToken = ""; try { if (this.userManager.isDOITokenValid(principal)) { @@ -2072,136 +2104,126 @@ public class DataManagementPlanManager { } catch (NonValidTokenException e) { zenodoToken = this.environment.getProperty("zenodo.access_token"); } - // First step, post call to Zenodo, to create the entry. - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - headers.setContentType(MediaType.APPLICATION_JSON); - ZenodoDeposit deposit = DMPToZenodoMapper.fromDMP(dmp, environment, configLoader); - //if (Objects.requireNonNull(environment.getProperty("spring.profiles.active")).contains("devel")) { - String json = objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(deposit); - logger.info(json); - //} - HttpEntity request = new HttpEntity<>(deposit, headers); - Map createResponse; - LinkedHashMap links; - String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId()); - String unpublishedUrl = null; - String publishUrl; - String finalDoi; - try { - if (previousDOI == null) { - String createUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?access_token=" + zenodoToken; - createResponse = restTemplate.postForEntity(createUrl, request, Map.class).getBody(); - links = (LinkedHashMap) createResponse.get("links"); - finalDoi = (String) createResponse.get("conceptdoi"); - } else { - unpublishedUrl = this.getUnpublishedDOI(previousDOI, zenodoToken, dmp.getVersion()); - if (unpublishedUrl == null) { - //It requires more than one step to create a new version - //First, get the deposit related to the concept DOI - String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; - ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); - createResponse = listResponses.getBody()[0]; - links = (LinkedHashMap) createResponse.get("links"); - //Second, make the new version (not in the links?) - String newVersionUrl = links.get("self") + "/actions/newversion" + "?access_token=" + zenodoToken; - createResponse = restTemplate.postForObject(newVersionUrl, null, Map.class); - links = (LinkedHashMap) createResponse.get("links"); - //Third, get the new deposit - String latestDraftUrl = links.get("latest_draft") + "?access_token=" + zenodoToken; - createResponse = restTemplate.getForObject(latestDraftUrl, Map.class); - links = (LinkedHashMap) createResponse.get("links"); - finalDoi = (String) createResponse.get("conceptdoi"); - //At this point it might fail to perform the next requests so enclose them with try catch - try { - //Forth, update the new deposit's metadata - String updateUrl = links.get("self") + "?access_token=" + zenodoToken; - restTemplate.put(updateUrl, request); - //And finally remove pre-existing files from it - String fileListUrl = links.get("self") + "/files" + "?access_token=" + zenodoToken; - ResponseEntity fileListResponse = restTemplate.getForEntity(fileListUrl, Map[].class); - for (Map file : fileListResponse.getBody()) { - String fileDeleteUrl = links.get("self") + "/files/" + file.get("id") + "?access_token=" + zenodoToken; - restTemplate.delete(fileDeleteUrl); - } - } catch (Exception e) { - //In case the last two steps fail delete the latest Deposit it in order to create a new one (only one at a time is allowed) - restTemplate.delete(latestDraftUrl); - throw e; - } - } - else { - String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + previousDOI + "\"&access_token=" + zenodoToken; - ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); - createResponse = listResponses.getBody()[0]; - links = (LinkedHashMap) createResponse.get("links"); + String finalDoi = null; + for(RepositoryDeposit repo: this.repositoriesDeposit) { //temp + if(repo.getConfiguration().getRepositoryId().equals("Zenodo")) { + finalDoi = repo.deposit(dmpDepositModel, zenodoToken); + if (finalDoi != null) { + EntityDoi doiEntity = new EntityDoi(); + doiEntity.setId(UUID.randomUUID()); + doiEntity.setEntityType(EntityDoi.EntityType.DMP); + doiEntity.setDoi(finalDoi); + doiEntity.setRepositoryId("Zenodo"); + Date now = new Date(); + doiEntity.setCreatedAt(now); + doiEntity.setUpdatedAt(now); + doiEntity.setEntityId(dmp); + apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity); + + dmp.getDois().add(doiEntity); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); } } - - if (!update) { - if (unpublishedUrl == null) { - // Second step, add the file to the entry. - FileEnvelope file = getWordDocument(id.toString(), principal, configLoader); - String name = file.getFilename().substring(0, file.getFilename().length() - 5); - File pdfFile = PDFUtils.convertToPDF(file, environment); - String fileName = name + ".pdf"; - FileSystemResource fileSystemResource = new FileSystemResource(pdfFile); - HttpEntity addFileMapRequest = new HttpEntity<>(fileSystemResource, null); - - String addFileUrl = links.get("bucket") + "/" + fileName + "?access_token=" + zenodoToken; - restTemplate.put(addFileUrl, addFileMapRequest); - Files.deleteIfExists(file.getFile().toPath()); - - ResponseEntity jsonFile; - try { - jsonFile = getRDAJsonDocument(id.toString(), principal); - } catch (Exception e) { - throw e; - } - UUID jsonFileUUID = UUID.randomUUID(); - File tempJsonFile = new File(this.environment.getProperty("temp.temp") + jsonFileUUID.toString() + ".json"); - try (FileOutputStream jsonFos = new FileOutputStream(tempJsonFile)) { - jsonFos.write(jsonFile.getBody()); - jsonFos.flush(); - } - fileSystemResource = new FileSystemResource(tempJsonFile); - HttpHeaders jsonHeaders = new HttpHeaders(); - jsonHeaders.add(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_OCTET_STREAM_VALUE); - addFileMapRequest = new HttpEntity<>(fileSystemResource, jsonHeaders); - String jsonFileName = jsonFile.getHeaders().get("Content-Disposition").get(0).substring(jsonFile.getHeaders().get("Content-Disposition").get(0).lastIndexOf('=') + 1); - addFileUrl = links.get("bucket") + "/" + jsonFileName + "?access_token=" + zenodoToken; - restTemplate.put(addFileUrl, addFileMapRequest); - Files.deleteIfExists(tempJsonFile.toPath()); - - - // Third post call to Zenodo to publish the entry and return the DOI. - publishUrl = links.get("publish") + "?access_token=" + zenodoToken; - } else { - publishUrl = unpublishedUrl + "?access_token=" + zenodoToken; - } -// if (dmp.isPublic()) { - Map publishResponce = restTemplate.postForObject(publishUrl, "", Map.class); - finalDoi = (String) publishResponce.get("conceptdoi"); -// } - } else { - Map editResponce = restTemplate.postForObject(links.get("edit") + "?access_token=" + zenodoToken, "", Map.class); - restTemplate.put(links.get("self") + "?access_token=" + zenodoToken, request); - Map publishResponce = restTemplate.postForObject(links.get("publish") + "?access_token=" + zenodoToken, "", Map.class); - finalDoi = (String) publishResponce.get("conceptdoi"); - } - - if (finalDoi != null) { - dmp.setDoi(finalDoi); - apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); - } - return finalDoi; - } catch (HttpClientErrorException | HttpServerErrorException ex) { - //ObjectMapper ob = new ObjectMapper(); - Map parsedException = objectMapper.readValue(ex.getResponseBodyAsString(), HashMap.class); - throw new IOException(parsedException.get("message"), ex); } + if(supportingFilesZip != null) { + Files.deleteIfExists(supportingFilesZip.toPath()); + } + Files.deleteIfExists(pdfFile.toPath()); + Files.deleteIfExists(file.getFile().toPath()); + + return finalDoi; + } + + public Doi createDoi(DepositRequest depositRequest, Principal principal) throws Exception { + DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(UUID.fromString(depositRequest.getDmpId())); + if (!isUserOwnerOfDmp(dmp, principal)) + throw new Exception("User is not authorized to invoke this action"); + if (!dmp.getStatus().equals(DMP.DMPStatus.FINALISED.getValue())) + throw new Exception("DMP is not finalized"); + /*if (dmp.getDoi() != null) + throw new Exception("DMP already has a DOI");*/ + + FileEnvelope file = getWordDocument(depositRequest.getDmpId(), principal, configLoader); + String name = file.getFilename().substring(0, file.getFilename().length() - 5).replaceAll("[^a-zA-Z0-9_+ ]", "").replace(" ", "_").replace(",", "_"); + File pdfFile = PDFUtils.convertToPDF(file, environment); + String fileName = name + ".pdf"; + ResponseEntity jsonFile; + try { + jsonFile = getRDAJsonDocument(depositRequest.getDmpId(), principal); + } catch (Exception e) { + throw e; + } + String previousDOI = this.getPreviousDOI(dmp.getGroupId(), dmp.getId(), depositRequest.getRepositoryId()); + + File supportingFilesZip = this.createSupportingFilesZip(dmp); + + DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfFile, fileName, jsonFile, 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; + } + }).orElse(null); + Doi doiModel = null; + if (finalDoi != null) { + + EntityDoi doiEntity = new EntityDoi(); + doiEntity.setId(UUID.randomUUID()); + doiEntity.setEntityType(EntityDoi.EntityType.DMP); + doiEntity.setDoi(finalDoi); + doiEntity.setRepositoryId(depositRequest.getRepositoryId()); + Date now = new Date(); + doiEntity.setCreatedAt(now); + doiEntity.setUpdatedAt(now); + doiEntity.setEntityId(dmp); + apiContext.getOperationsContext().getDatabaseRepository().getEntityDoiDao().createOrUpdate(doiEntity); + + dmp.getDois().add(doiEntity); + apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().createOrUpdate(dmp); + + doiModel = new Doi().fromDataModel(doiEntity); + + } + if(supportingFilesZip != null) { + Files.deleteIfExists(supportingFilesZip.toPath()); + } + Files.deleteIfExists(pdfFile.toPath()); + Files.deleteIfExists(file.getFile().toPath()); + + return doiModel; + } + + private File createSupportingFilesZip(DMP dmp) throws IOException { + FileOutputStream fout = new FileOutputStream(this.environment.getProperty("temp.temp") + "supportingFiles.zip"); + ZipOutputStream zout = new ZipOutputStream(fout); + + boolean hasFileUploaded = false; + Set datasets = dmp.getDataset(); + for (Dataset dataset : datasets) { + List files = this.apiContext.getOperationsContext().getDatabaseRepository().getFileUploadDao().getFileUploads(dataset.getId()); + for (FileUpload f : files) { + if(!f.getIsDeleted()){ + File exportFile = new File(this.environment.getProperty("file.storage") + f.getId()); + String filename = f.getName().replace(" ", "_").replace(",", "_"); + byte[] content = Files.readAllBytes(exportFile.toPath()); + ZipEntry ze = new ZipEntry(filename); + zout.putNextEntry(ze); + zout.write(content, 0, content.length); + zout.closeEntry(); + hasFileUploaded = true; + } + } + } + zout.close(); + if(!hasFileUploaded){ + Files.deleteIfExists(new File(this.environment.getProperty("temp.temp") + "supportingFiles.zip").toPath()); + } + return hasFileUploaded ? new File(this.environment.getProperty("temp.temp") + "supportingFiles.zip") : null; } /* 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 new file mode 100644 index 000000000..df71d4f65 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DepositManager.java @@ -0,0 +1,58 @@ +package eu.eudat.logic.managers; + +import eu.eudat.depositinterface.repository.RepositoryDeposit; +import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; +import eu.eudat.models.data.doi.DepositRequest; +import eu.eudat.models.data.doi.Doi; +import eu.eudat.models.data.doi.RepositoryConfig; +import eu.eudat.models.data.security.Principal; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.Optional; + +@Component +public class DepositManager { + private static final Logger logger = LoggerFactory.getLogger(DepositManager.class); + + private List repositories; + private DataManagementPlanManager dataManagementPlanManager; + + @Autowired + public DepositManager(List repositories, DataManagementPlanManager dataManagementPlanManager){ + this.repositories = repositories; + this.dataManagementPlanManager = dataManagementPlanManager; + } + + public List getAvailableRepos() { + List reposConfigModel = new ArrayList<>(); + for (RepositoryDeposit r: this.repositories) { + RepositoryConfig repoModel = new RepositoryConfig(); + RepositoryDepositConfiguration repoConf = r.getConfiguration(); + if(repoConf != null) { + reposConfigModel.add(repoModel.toModel(repoConf)); + } + } + 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); + } + + public Doi deposit(DepositRequest depositRequest, Principal principal) throws Exception { + return this.dataManagementPlanManager.createDoi(depositRequest, principal); + } + + 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); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DOIFunder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DOIFunder.java deleted file mode 100644 index 68803e021..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DOIFunder.java +++ /dev/null @@ -1,27 +0,0 @@ -package eu.eudat.logic.proxy.config; - -import com.fasterxml.jackson.annotation.JsonProperty; - -public class DOIFunder { - - @JsonProperty("Funder") - private String funder; - @JsonProperty("DOI") - private String DOI; - - public String getFunder() { - return funder; - } - - public void setFunder(String funder) { - this.funder = funder; - } - - public String getDOI() { - return DOI; - } - - public void setDOI(String DOI) { - this.DOI = DOI; - } -} 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 08dc4062c..175442eda 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 @@ -1,6 +1,5 @@ package eu.eudat.logic.proxy.config.configloaders; -import eu.eudat.logic.proxy.config.DOIFunder; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -15,5 +14,4 @@ public interface ConfigLoader { XWPFDocument getDatasetDocument(); ConfigurableProviders getConfigurableProviders(); Map getKeyToSourceMap(); - List getDOIFunders(); } 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 a1d65877c..36c6d3ac3 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 @@ -2,7 +2,6 @@ package eu.eudat.logic.proxy.config.configloaders; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; -import eu.eudat.logic.proxy.config.DOIFunder; import eu.eudat.logic.proxy.config.ExternalUrls; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -41,7 +40,6 @@ public class DefaultConfigLoader implements ConfigLoader { private XWPFDocument datasetDocument; private ConfigurableProviders configurableProviders; private Map keyToSourceMap; - private List doiFunders = new ArrayList<>(); @Autowired private Environment environment; @@ -207,18 +205,6 @@ public class DefaultConfigLoader implements ConfigLoader { return keyToSourceMap; } - @Override - public List getDOIFunders() { - if (doiFunders == null || doiFunders.isEmpty()) { - try { - List> tempdoiFunders = mapper.readValue(getStreamFromPath(environment.getProperty("configuration.doi_funder")), List.class); - doiFunders = tempdoiFunders.stream().map(map -> mapper.convertValue(map, DOIFunder.class) ).collect(Collectors.toList()); - } catch (IOException e) { - logger.error(e.getLocalizedMessage(), e); - } - } - return doiFunders; - } private Document getXmlDocumentFromFilePath(String filePath) { InputStream is = 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 new file mode 100644 index 000000000..2997f534c --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java @@ -0,0 +1,74 @@ +package eu.eudat.logic.security.repositorydeposit.mapper; + +import eu.eudat.data.entities.*; +import eu.eudat.depositinterface.models.*; +import org.springframework.http.ResponseEntity; + +import java.io.File; +import java.util.stream.Collectors; + +public class DMPToDepositMapper { + + public static DMPDepositModel fromDMP(DMP entity, File pdfFile, String fileName, ResponseEntity jsonFile, File supportingFilesZip, String previousDOI) { + DMPDepositModel deposit = new DMPDepositModel(); + deposit.setId(entity.getId()); + deposit.setVersion(entity.getVersion()); + deposit.setLabel(entity.getLabel()); + deposit.setDescription(entity.getDescription()); + deposit.setPublic(entity.isPublic()); + 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())); + + deposit.setPdfFile(pdfFile); + deposit.setPdfFileName(fileName); + deposit.setRdaJson(jsonFile); + deposit.setSupportingFilesZip(supportingFilesZip); + deposit.setPreviousDOI(previousDOI); + + deposit.setExtraProperties(entity.getExtraProperties()); + return deposit; + } + + private static UserDMPDepositModel fromUserDMP(UserDMP entity){ + UserDMPDepositModel deposit = new UserDMPDepositModel(); + deposit.setUser(fromUserInfo(entity.getUser())); + deposit.setRole(entity.getRole()); + return deposit; + } + + private static UserInfoDepositModel fromUserInfo(UserInfo entity){ + UserInfoDepositModel deposit = new UserInfoDepositModel(); + deposit.setName(entity.getName()); + deposit.setEmail(entity.getEmail()); + return deposit; + } + + private static OrganisationDepositModel fromOrganisation(Organisation entity){ + OrganisationDepositModel deposit = new OrganisationDepositModel(); + deposit.setLabel(entity.getLabel()); + return deposit; + } + + private static ResearcherDepositModel fromResearcher(Researcher entity){ + ResearcherDepositModel deposit = new ResearcherDepositModel(); + deposit.setLabel(entity.getLabel()); + deposit.setReference(entity.getReference()); + return deposit; + } + + private static GrantDepositModel fromGrant(Grant entity){ + GrantDepositModel deposit = new GrantDepositModel(); + deposit.setId(entity.getId()); + deposit.setReference(entity.getReference()); + deposit.setFunder(fromFunder(entity.getFunder())); + return deposit; + } + + private static FunderDepositModel fromFunder(Funder entity){ + FunderDepositModel deposit = new FunderDepositModel(); + deposit.setLabel(entity.getLabel()); + return deposit; + } +} 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 67225a76d..99e088a1c 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 @@ -60,5 +60,7 @@ public interface DatabaseRepository { FileUploadDao getFileUploadDao(); + EntityDoiDao getEntityDoiDao(); + 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 7228b5b2f..2e2dd4c63 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 @@ -39,6 +39,7 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { private LockDao lockDao; private NotificationDao notificationDao; private FileUploadDao fileUploadDao; + private EntityDoiDao entityDoiDao; private EntityManager entityManager; @@ -317,6 +318,15 @@ public class DatabaseRepositoryImpl implements DatabaseRepository { this.fileUploadDao = fileUploadDao; } + @Override + public EntityDoiDao getEntityDoiDao() { + return entityDoiDao; + } + + @Autowired + public void setEntityDoiDao(EntityDoiDao entityDoiDao) { + this.entityDoiDao = entityDoiDao; + } public void detachEntity(T entity) { this.entityManager.detach(entity); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/HtmlToWorldBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/HtmlToWorldBuilder.java index 8cc6368bb..5badc0f67 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/HtmlToWorldBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/word/HtmlToWorldBuilder.java @@ -25,6 +25,14 @@ public class HtmlToWorldBuilder implements NodeVisitor { private BigInteger numberingLevel; private XmlCursor cursor; + public static HtmlToWorldBuilder convertInTable(XWPFTableCell document, Document htmlDocument, float indentation) { + XWPFParagraph paragraph = document.addParagraph(); + paragraph.setIndentFromLeft(Math.round(400 * indentation)); + HtmlToWorldBuilder htmlToWorldBuilder = new HtmlToWorldBuilder(paragraph, indentation, null); + NodeTraversor.traverse(htmlToWorldBuilder, htmlDocument); + return htmlToWorldBuilder; + } + public static HtmlToWorldBuilder convert(XWPFDocument document, Document htmlDocument, float indentation) { XWPFParagraph paragraph = document.createParagraph(); paragraph.setIndentFromLeft(Math.round(400 * indentation)); 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 0d34203a3..a325194b9 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 @@ -65,6 +65,7 @@ public class WordBuilder { ).collect(Collectors.toMap(objects -> (String)objects[0], o -> (Integer)o[1])); private Map> options = new HashMap<>(); + private Map> optionsInTable = new HashMap<>(); private CTAbstractNum cTAbstractNum; private BigInteger numId; private Integer indent; @@ -78,6 +79,42 @@ public class WordBuilder { this.imageCount = 0; this.mapper = new ObjectMapper(); this.buildOptions(environment); + this.buildOptionsInTable(environment); + } + + private void buildOptionsInTable(Environment environment) { + this.optionsInTable.put(ParagraphStyle.TEXT, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.addParagraph(); + XWPFRun run = paragraph.createRun(); + if (item != null) + run.setText("" + item); + run.setFontSize(11); + return paragraph; + }); + this.optionsInTable.put(ParagraphStyle.HTML, (mainDocumentPart, item) -> { + Document htmlDoc = Jsoup.parse(((String)item).replaceAll("\n", "
")); + HtmlToWorldBuilder htmlToWorldBuilder = HtmlToWorldBuilder.convertInTable(mainDocumentPart, htmlDoc, 0); + return htmlToWorldBuilder.getParagraph(); + }); + this.optionsInTable.put(ParagraphStyle.TITLE, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.addParagraph(); + paragraph.setStyle("Title"); + paragraph.setAlignment(ParagraphAlignment.CENTER); + XWPFRun run = paragraph.createRun(); + run.setText((String)item); + run.setBold(true); + run.setFontSize(14); + return paragraph; + }); + this.optionsInTable.put(ParagraphStyle.IMAGE, (mainDocumentPart, item) -> { + XWPFParagraph paragraph = mainDocumentPart.addParagraph(); + XWPFRun run = paragraph.createRun(); + if (item != null) + run.setText(((Map)item).get("name")); + run.setFontSize(11); + run.setItalic(true); + return paragraph; + }); } private void buildOptions(Environment environment) { @@ -91,7 +128,6 @@ public class WordBuilder { }); this.options.put(ParagraphStyle.HTML, (mainDocumentPart, item) -> { Document htmlDoc = Jsoup.parse(((String)item).replaceAll("\n", "
")); -// HtmlToWorldBuilder htmlToWorldBuilder = HtmlToWorldBuilder.convert(mainDocumentPart, htmlDoc, indent > 0 ? (indent/2.0F) * 0.8F : 0.8F); HtmlToWorldBuilder htmlToWorldBuilder = HtmlToWorldBuilder.convert(mainDocumentPart, htmlDoc, this.indent); return htmlToWorldBuilder.getParagraph(); }); @@ -287,6 +323,7 @@ public class WordBuilder { if (createListing) this.addListing(mainDocumentPart, indent, true, true); boolean hasValue = false; boolean returnedValue = false; + for (FieldSet compositeField: compositeFields) { if (visibilityRuleService.isElementVisible(compositeField.getId()) && hasVisibleFields(compositeField, visibilityRuleService)) { char c = 'a'; @@ -299,14 +336,30 @@ public class WordBuilder { // CTDecimalNumber number = paragraph.getCTP().getPPr().getNumPr().addNewIlvl(); // number.setVal(BigInteger.valueOf(indent)); paragraphPos = mainDocumentPart.getPosOfParagraph(paragraph); - if(compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()){ + if(!compositeField.getMultiplicity().getTableView() && compositeField.getMultiplicityItems() != null && !compositeField.getMultiplicityItems().isEmpty()){ XWPFParagraph paragraphInner = addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.TEXT, numId, indent); paragraphPosInner = mainDocumentPart.getPosOfParagraph(paragraphInner); hasMultiplicityItems = true; multiplicityItems++; } } - hasValue = createFields(compositeField.getFields(), mainDocumentPart, indent, createListing, visibilityRuleService, hasMultiplicityItems); + XWPFTable tbl = null; + XWPFTableRow row = null; + int numOfRows = 0; + if(compositeField.getMultiplicity().getTableView()) { + tbl = mainDocumentPart.createTable(); + tbl.setTableAlignment(TableRowAlign.CENTER); + mainDocumentPart.createParagraph(); + createHeadersInTable(compositeField.getFields(), tbl, visibilityRuleService); + numOfRows = tbl.getRows().size(); + row = tbl.createRow(); + } + if(compositeField.getMultiplicity().getTableView()) { + hasValue = createFieldsInTable(compositeField.getFields(), row, indent, createListing, visibilityRuleService, hasMultiplicityItems, numOfRows); + numOfRows++; + } else { + hasValue = createFields(compositeField.getFields(), mainDocumentPart, indent, createListing, visibilityRuleService, hasMultiplicityItems); + } if(hasValue){ returnedValue = true; } else if(paragraphPosInner > -1){ @@ -318,7 +371,7 @@ public class WordBuilder { List
list = compositeField.getMultiplicityItems().stream().sorted(Comparator.comparingInt(FieldSet::getOrdinal)).collect(Collectors.toList()); for (FieldSet multiplicityFieldset : list) { paragraphPosInner = -1; - if(!createListing){ + if(!compositeField.getMultiplicity().getTableView() && !createListing){ c++; // addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.HEADER6, numId); XWPFParagraph paragraphInner = addParagraphContent(c + ". ", mainDocumentPart, ParagraphStyle.TEXT, numId, indent); @@ -327,7 +380,14 @@ public class WordBuilder { multiplicityItems++; } // hasValue = createFields(multiplicityFieldset.getFields(), mainDocumentPart, 3, createListing, visibilityRuleService, hasMultiplicityItems); - boolean hasValueInner = createFields(multiplicityFieldset.getFields(), mainDocumentPart, indent, createListing, visibilityRuleService, hasMultiplicityItems); + boolean hasValueInner = false; + if(compositeField.getMultiplicity().getTableView()) { + row = tbl.createRow(); + hasValueInner = createFieldsInTable(multiplicityFieldset.getFields(), row, indent, createListing, visibilityRuleService, hasMultiplicityItems, numOfRows); + numOfRows++; + } else { + hasValueInner = createFields(multiplicityFieldset.getFields(), mainDocumentPart, indent, createListing, visibilityRuleService, hasMultiplicityItems); + } // if(hasValue){ if(hasValueInner){ hasValue = true; @@ -355,9 +415,159 @@ public class WordBuilder { } } } + return returnedValue; } + private void createHeadersInTable(List fields, XWPFTable table, VisibilityRuleService visibilityRuleService) { + boolean atLeastOneHeader = false; + List tempFields = fields.stream().sorted(Comparator.comparingInt(Field::getOrdinal)).collect(Collectors.toList()); + int index = 0; + XWPFTableRow row = table.getRow(0); + for (Field field: tempFields) { + if (visibilityRuleService.isElementVisible(field.getId()) && field.getExport()) { + XWPFTableCell cell; + if(index == 0) { + cell = row.getCell(0); + } else { + cell = row.createCell(); + } + cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.valueOf("CENTER")); + String label = ((FieldData) field.getData()).getLabel(); + if(label != null && label != "") { + XWPFParagraph paragraph = cell.getParagraphs().get(0); + paragraph.setIndentationFirstLine(50); + XWPFRun run = paragraph.createRun(); + run.setText(label); + run.setBold(true); + run.setFontSize(12); + paragraph.setAlignment(ParagraphAlignment.CENTER); + paragraph.setSpacingBefore(100); + + atLeastOneHeader = true; + } + } + index++; + } + + if(!atLeastOneHeader) { + table.removeRow(0); + } + } + + private Boolean createFieldsInTable(List fields, XWPFTableRow mainDocumentPart, Integer indent, Boolean createListing, VisibilityRuleService visibilityRuleService, boolean hasMultiplicityItems, int numOfRows) { + int numOfCells = 0; + boolean hasValue = false; + List tempFields = fields.stream().sorted(Comparator.comparingInt(Field::getOrdinal)).collect(Collectors.toList()); + for (Field field: tempFields) { + if (visibilityRuleService.isElementVisible(field.getId()) && field.getExport()) { + if (!createListing) { + try { + if(field.getViewStyle().getRenderStyle().equals("upload")){ + boolean isImage = false; + for(UploadData.Option type: ((UploadData)field.getData()).getTypes()){ + String fileFormat = type.getValue(); + if(IMAGE_TYPE_MAP.containsKey(fileFormat)){ + isImage = true; + break; + } + } + if(isImage){ + if (field.getValue() != null && !field.getValue().toString().isEmpty()) { + XWPFParagraph paragraph = addCellContent(mapper.convertValue(field.getValue(), Map.class), mainDocumentPart, ParagraphStyle.IMAGE, numId, 0, numOfRows, numOfCells, 0); + if (paragraph != null) { + hasValue = true; + } + if(hasMultiplicityItems){ + hasMultiplicityItems = false; + } + } + } + } + else if (field.getValue() != null && !field.getValue().toString().isEmpty()) { + this.indent = indent; + String format = this.formatter(field); + if (field.getViewStyle().getRenderStyle().equals("tags")) { + format = getCommaSeparatedFormatsFromJson(format, "name"); + } 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; + int numOfValuesInCell = 0; + 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){ + XWPFParagraph paragraph = mainDocumentPart.getCell(mainDocumentPart.getTableCells().size()).addParagraph(); + paragraph.createRun().setText(format); + if(orcidResearcher){ + XWPFHyperlinkRun run = paragraph.createHyperlinkRun("https://orcid.org/" + orcId); + run.setText(orcId); + run.setUnderline(UnderlinePatterns.SINGLE); + run.setColor("0000FF"); + paragraph.createRun().setText(")"); + } + hasMultiplicityItems = false; + } + else{ + XWPFParagraph paragraph = addCellContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent, numOfRows, numOfCells, numOfValuesInCell); + numOfValuesInCell++; + 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) { + hasValue = true; + } + } + format = null; + } + } + else if(values.size() == 1){ + format = values.get(0); + } + } + } + if(hasMultiplicityItems && format != null){ + XWPFParagraph paragraph = mainDocumentPart.getCell(mainDocumentPart.getTableCells().size()).addParagraph(); + paragraph.createRun().setText(format); + hasMultiplicityItems = false; + hasValue = true; + } + else{ + XWPFParagraph paragraph = addCellContent(format, mainDocumentPart, field.getViewStyle().getRenderStyle().equals("richTextarea") ? ParagraphStyle.HTML : ParagraphStyle.TEXT, numId, indent, numOfRows, numOfCells, 0); + if (paragraph != null) { + hasValue = true; + } + } + } + } catch (IOException e) { + logger.error(e.getMessage(), e); + } + } + numOfCells++; + } + } + return hasValue; + } + 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; @@ -491,6 +701,36 @@ public class WordBuilder { } } + public XWPFParagraph addCellContent(Object content, XWPFTableRow mainDocumentPart, ParagraphStyle style, BigInteger numId, int indent, int numOfRows, int numOfCells, int numOfValuesInCell) { + if (content != null) { + if (content instanceof String && ((String)content).isEmpty()) { + return null; + } + this.indent = indent; + XWPFTableCell cell; + if(numOfRows > 0 || numOfValuesInCell > 0) { + cell = mainDocumentPart.getCell(numOfCells); + } else { + cell = mainDocumentPart.createCell(); + } + cell.setVerticalAlignment(XWPFTableCell.XWPFVertAlign.valueOf("CENTER")); + if(numOfValuesInCell == 0) { + cell.removeParagraph(0); + } + + XWPFParagraph paragraph = this.optionsInTable.get(style).apply(cell, content); + if (paragraph != null) { + paragraph.setAlignment(ParagraphAlignment.CENTER); + paragraph.setSpacingBefore(100); + if (numId != null) { + paragraph.setNumID(numId); + } + return paragraph; + } + } + return null; + } + public XWPFParagraph addParagraphContent(Object content, XWPFDocument mainDocumentPart, ParagraphStyle style, BigInteger numId, int indent) { // this.indent = 0; if (content != null) { @@ -796,9 +1036,8 @@ public class WordBuilder { r.setText(text, 0); } if(text.contains("{ARGOS.DMP.DOI}")){ - String doi = dmpEntity.getDoi(); - if(doi != null) - text = text.replace("{ARGOS.DMP.DOI}", 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); 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 cce37ad56..2cf12e68d 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 @@ -121,6 +121,7 @@ public class ExportXmlBuilderDatasetProfile { multiplicity.setAttribute("max", "" + field.getMultiplicity().getMax()); multiplicity.setAttribute("min", "" + field.getMultiplicity().getMin()); multiplicity.setAttribute("placeholder", field.getMultiplicity().getPlaceholder()); + multiplicity.setAttribute("tableView", String.valueOf(field.getMultiplicity().getTableView())); composite.appendChild(multiplicity); } if (field.getTitle() != null && !field.getTitle().isEmpty()) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Multiplicity.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Multiplicity.java index 4a54bf6ec..13c01c684 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Multiplicity.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Multiplicity.java @@ -9,6 +9,7 @@ public class Multiplicity { private int max; private int min; private String placeholder; + private boolean tableView; @XmlAttribute(name = "max") public int getMax() { @@ -37,11 +38,21 @@ public class Multiplicity { this.placeholder = placeholder; } + @XmlAttribute(name = "tableView") + public boolean getTableView() { + return tableView; + } + + public void setTableView(boolean tableView) { + this.tableView = tableView; + } + public eu.eudat.models.data.components.commons.Multiplicity toAdminCompositeModelSection() { eu.eudat.models.data.components.commons.Multiplicity multiplicityEntity = new eu.eudat.models.data.components.commons.Multiplicity(); multiplicityEntity.setMax(max); multiplicityEntity.setMin(min); multiplicityEntity.setPlaceholder(placeholder); + multiplicityEntity.setTableView(tableView); return multiplicityEntity; } } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/Multiplicity.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/Multiplicity.java index c4b69ce19..2ad99dec3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/Multiplicity.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/components/commons/Multiplicity.java @@ -5,6 +5,7 @@ public class Multiplicity { private int min; private int max; private String placeholder; + private boolean tableView; public int getMin() { return min; @@ -29,4 +30,12 @@ public class Multiplicity { public void setPlaceholder(String placeholder) { this.placeholder = placeholder; } + + public boolean getTableView() { + return tableView; + } + + public void setTableView(boolean tableView) { + this.tableView = tableView; + } } 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 cc2dcd4fb..6c4018f81 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 @@ -4,6 +4,7 @@ import eu.eudat.data.entities.*; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; import eu.eudat.models.data.datasetwizard.DatasetWizardModel; +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.funder.Funder; @@ -40,7 +41,7 @@ public class DataManagementPlan implements DataModel { private List dynamicFields; private Map properties; private List users; - private String doi; + private List dois; private Project project; private Funder funder; private Boolean isPublic; @@ -194,11 +195,11 @@ public class DataManagementPlan implements DataModel { this.users = users; } - public String getDoi() { - return doi; + public List getDois() { + return dois; } - public void setDoi(String doi) { - this.doi = doi; + public void setDois(List dois) { + this.dois = dois; } public Project getProject() { @@ -280,7 +281,7 @@ public class DataManagementPlan implements DataModel { this.status = entity.getStatus(); 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.doi = entity.getDoi(); + this.dois = entity.getDois() != null ? entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()): new ArrayList<>(); if (entity.getProject() != null) { this.project = new Project(); @@ -376,7 +377,7 @@ public class DataManagementPlan implements DataModel { this.status = entity.getStatus(); 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.doi = entity.getDoi(); + 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.getProject() != null) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java new file mode 100644 index 000000000..a567dc9da --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositCode.java @@ -0,0 +1,21 @@ +package eu.eudat.models.data.doi; + +public class DepositCode { + + private String repositoryId; + private String code; + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getCode() { + return code; + } + public void setCode(String code) { + this.code = code; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java new file mode 100644 index 000000000..b6ee1f4a3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/DepositRequest.java @@ -0,0 +1,29 @@ +package eu.eudat.models.data.doi; + +public class DepositRequest { + + private String repositoryId; + private String dmpId; + private String accessToken; + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDmpId() { + return dmpId; + } + public void setDmpId(String dmpId) { + this.dmpId = dmpId; + } + + public String getAccessToken() { + return accessToken; + } + public void setAccessToken(String accessToken) { + this.accessToken = accessToken; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java new file mode 100644 index 000000000..9a877dc4d --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/Doi.java @@ -0,0 +1,85 @@ +package eu.eudat.models.data.doi; + +import eu.eudat.data.entities.EntityDoi; +import eu.eudat.models.DataModel; +import eu.eudat.models.data.dmp.DataManagementPlan; + +import java.util.Date; +import java.util.UUID; + +public class Doi implements DataModel { + private UUID id; + private String repositoryId; + private String doi; + private Date createdAt; + private Date updatedAt; + private DataManagementPlan dmp; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDoi() { + return doi; + } + public void setDoi(String doi) { + this.doi = doi; + } + + public Date getCreatedAt() { + return createdAt; + } + public void setCreatedAt(Date createdAt) { + this.createdAt = createdAt; + } + + public Date getUpdatedAt() { + return updatedAt; + } + public void setUpdatedAt(Date updatedAt) { + this.updatedAt = updatedAt; + } + + public DataManagementPlan getDmp() { + return dmp; + } + public void setDmp(DataManagementPlan dmp) { + this.dmp = dmp; + } + + @Override + public Doi fromDataModel(EntityDoi entity) { + this.id = entity.getId(); + this.repositoryId = entity.getRepositoryId(); + this.doi = entity.getDoi(); + this.createdAt = entity.getCreatedAt(); + this.updatedAt = entity.getUpdatedAt(); + return this; + } + + @Override + public EntityDoi toDataModel() throws Exception { + EntityDoi entityDoi = new EntityDoi(); + entityDoi.setId(this.id); + entityDoi.setRepositoryId(this.repositoryId); + entityDoi.setDoi(this.doi); + entityDoi.setCreatedAt(this.createdAt); + entityDoi.setUpdatedAt(this.updatedAt); + return entityDoi; + } + + @Override + public String getHint() { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java new file mode 100644 index 000000000..1c45346a0 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/doi/RepositoryConfig.java @@ -0,0 +1,74 @@ +package eu.eudat.models.data.doi; + +import eu.eudat.depositinterface.repository.RepositoryDepositConfiguration; + +public class RepositoryConfig { + + private int depositType; + private String repositoryId; + private String repositoryAuthorizationUrl; + private String repositoryRecordUrl; + private String repositoryClientId; + private String redirectUri; + private boolean hasLogo; + + public int getDepositType() { + return depositType; + } + public void setDepositType(int depositType) { + this.depositType = depositType; + } + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getRepositoryAuthorizationUrl() { + return repositoryAuthorizationUrl; + } + public void setRepositoryAuthorizationUrl(String repositoryAuthorizationUrl) { + this.repositoryAuthorizationUrl = repositoryAuthorizationUrl; + } + + public String getRepositoryRecordUrl() { + return repositoryRecordUrl; + } + public void setRepositoryRecordUrl(String repositoryRecordUrl) { + this.repositoryRecordUrl = repositoryRecordUrl; + } + + public String getRepositoryClientId() { + return repositoryClientId; + } + public void setRepositoryClientId(String repositoryClientId) { + this.repositoryClientId = repositoryClientId; + } + + public String getRedirectUri() { + return redirectUri; + } + public void setRedirectUri(String redirectUri) { + this.redirectUri = redirectUri; + } + + public boolean isHasLogo() { + return hasLogo; + } + public void setHasLogo(boolean hasLogo) { + this.hasLogo = hasLogo; + } + + public RepositoryConfig toModel(RepositoryDepositConfiguration r){ + this.setDepositType(r.getDepositType()); + this.setRepositoryId(r.getRepositoryId()); + this.setRepositoryAuthorizationUrl(r.getRepositoryAuthorizationUrl()); + this.setRepositoryRecordUrl(r.getRepositoryRecordUrl()); + this.setRepositoryClientId(r.getRepositoryClientId()); + this.setRedirectUri(r.getRedirectUri()); + this.setHasLogo(r.isHasLogo()); + return this; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/FieldSet.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/FieldSet.java index 716e18f9f..250541c30 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/FieldSet.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/entities/xmlmodels/datasetprofiledefinition/FieldSet.java @@ -122,6 +122,7 @@ public class FieldSet implements DatabaseViewStyleDefinition, XmlSerializable dois; public String getId() { @@ -164,11 +165,11 @@ public class DataManagementPlanOverviewModel implements DataModel getDois() { + return dois; } - public void setDoi(String doi) { - this.doi = doi; + public void setDois(List dois) { + this.dois = dois; } @Override @@ -180,6 +181,9 @@ public class DataManagementPlanOverviewModel implements DataModel new Researcher().fromDataModel(item)).collect(Collectors.toList()); } + if(entity.getDois() != null){ + this.dois = entity.getDois().stream().map(item -> new Doi().fromDataModel(item)).collect(Collectors.toList()); + } return this; } @@ -208,7 +212,7 @@ public class DataManagementPlanOverviewModel implements DataModel new Doi().fromDataModel(item)).collect(Collectors.toList()); return this; } 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 47147fc4e..9d3cccf23 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 @@ -1,9 +1,6 @@ package eu.eudat.models.data.rda; -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.Dataset; -import eu.eudat.data.entities.UserDMP; -import eu.eudat.data.entities.UserInfo; +import eu.eudat.data.entities.*; import eu.eudat.logic.managers.DatasetManager; import eu.eudat.models.data.security.Principal; @@ -146,8 +143,17 @@ public class DmpRDAExportModel { dmpRda.dataset.add(new DatasetRDAExportModel().fromDataModel(dataset, datasetManager, principal)); } dmpRda.description = entity.getDescription().replace("\n", " "); - if (entity.getDoi() != null) { - dmpRda.dmp_id = new IdRDAExportModel(entity.getDoi(), "zenodo"); + if (entity.getDois() != null && !entity.getDois().isEmpty()) { + boolean zenodoDoi = false; + for(EntityDoi doi: entity.getDois()){ + if(doi.getRepositoryId().equals("Zenodo")){ + dmpRda.dmp_id = new IdRDAExportModel(doi.getDoi(), "zenodo"); + zenodoDoi = true; + } + } + if(!zenodoDoi){ + dmpRda.dmp_id = new IdRDAExportModel(entity.getId().toString(), "other"); + } } else { dmpRda.dmp_id = new IdRDAExportModel(entity.getId().toString(), "other"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoAccessRight.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoAccessRight.java deleted file mode 100644 index b143338fc..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoAccessRight.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonValue; - -public enum ZenodoAccessRight { - RESTRICTED("restricted"), EMBARGOED("embargoed"), OPEN("open"); - - private final String value; - - ZenodoAccessRight(String value) { - this.value = value; - } - - @JsonValue - public String getValue() { - return value; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoComunity.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoComunity.java deleted file mode 100644 index f644d3144..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoComunity.java +++ /dev/null @@ -1,19 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoComunity { - - private String identifier; - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoContributor.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoContributor.java deleted file mode 100644 index 55ca86ed7..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoContributor.java +++ /dev/null @@ -1,45 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoContributor { - private String name; - private String type; - private String affiliation; - private String orcid; - - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public String getType() { - return type; - } - - public void setType(String type) { - this.type = type; - } - - public String getAffiliation() { - return affiliation; - } - - public void setAffiliation(String affiliation) { - this.affiliation = affiliation; - } - - public String getOrcid() { - return orcid; - } - - public void setOrcid(String orcid) { - this.orcid = orcid; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDeposit.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDeposit.java deleted file mode 100644 index c80a167c9..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDeposit.java +++ /dev/null @@ -1,19 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoDeposit { - - private ZenodoDepositMetadata metadata; - - public ZenodoDepositMetadata getMetadata() { - return metadata; - } - - public void setMetadata(ZenodoDepositMetadata metadata) { - this.metadata = metadata; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDepositMetadata.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDepositMetadata.java deleted file mode 100644 index 014239f69..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoDepositMetadata.java +++ /dev/null @@ -1,159 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; -import com.fasterxml.jackson.annotation.JsonProperty; - -import java.time.Instant; -import java.util.List; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoDepositMetadata { - - private String title; - - @JsonProperty("upload_type") - private String uploadType; - - @JsonProperty("publication_type") - private String publicationType; - - private String description; - - private String version; - - private List communities; - - @JsonProperty("access_right") - private ZenodoAccessRight accessRight; - - @JsonProperty("access_conditions") - private String accessConditions; - - @JsonProperty("embargo_date") - private String embargoDate; - - private String license; - - @JsonProperty("related_identifiers") - private List relatedIdentifiers; - - private List contributors; - - private List grants; - - private List creators; - - public String getTitle() { - return title; - } - - public void setTitle(String title) { - this.title = title; - } - - public String getUploadType() { - return uploadType; - } - - public void setUploadType(String uploadType) { - this.uploadType = uploadType; - } - - public String getPublicationType() { - return publicationType; - } - - public void setPublicationType(String publicationType) { - this.publicationType = publicationType; - } - - public String getDescription() { - return description; - } - - public void setDescription(String description) { - this.description = description; - } - - public String getVersion() { - return version; - } - - public void setVersion(String version) { - this.version = version; - } - - public List getCommunities() { - return communities; - } - - public void setCommunities(List communities) { - this.communities = communities; - } - - public ZenodoAccessRight getAccessRight() { - return accessRight; - } - - public void setAccessRight(ZenodoAccessRight accessRight) { - this.accessRight = accessRight; - } - - public String getAccessConditions() { - return accessConditions; - } - - public void setAccessConditions(String accessConditions) { - this.accessConditions = accessConditions; - } - - public String getEmbargoDate() { - return embargoDate; - } - - public void setEmbargoDate(String embargoDate) { - this.embargoDate = embargoDate; - } - - public String getLicense() { - return license; - } - - public void setLicense(String license) { - this.license = license; - } - - public List getRelatedIdentifiers() { - return relatedIdentifiers; - } - - public void setRelatedIdentifiers(List relatedIdentifiers) { - this.relatedIdentifiers = relatedIdentifiers; - } - - public List getContributors() { - return contributors; - } - - public void setContributors(List contributors) { - this.contributors = contributors; - } - - public List getGrants() { - return grants; - } - - public void setGrants(List grants) { - this.grants = grants; - } - - public List getCreators() { - return creators; - } - - public void setCreators(List creators) { - this.creators = creators; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoGrant.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoGrant.java deleted file mode 100644 index 292322a30..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoGrant.java +++ /dev/null @@ -1,18 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoGrant { - private String id; - - public String getId() { - return id; - } - - public void setId(String id) { - this.id = id; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoRelator.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoRelator.java deleted file mode 100644 index e5389602e..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/ZenodoRelator.java +++ /dev/null @@ -1,28 +0,0 @@ -package eu.eudat.models.deposit.zenodo; - -import com.fasterxml.jackson.annotation.JsonIgnoreProperties; -import com.fasterxml.jackson.annotation.JsonInclude; - -@JsonIgnoreProperties(ignoreUnknown = true) -@JsonInclude(JsonInclude.Include.NON_NULL) -public class ZenodoRelator { - - private String identifier; - private String relation; - - public String getIdentifier() { - return identifier; - } - - public void setIdentifier(String identifier) { - this.identifier = identifier; - } - - public String getRelation() { - return relation; - } - - public void setRelation(String relation) { - this.relation = relation; - } -} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/mapper/DMPToZenodoMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/mapper/DMPToZenodoMapper.java deleted file mode 100644 index f4a399f49..000000000 --- a/dmp-backend/web/src/main/java/eu/eudat/models/deposit/zenodo/mapper/DMPToZenodoMapper.java +++ /dev/null @@ -1,115 +0,0 @@ -package eu.eudat.models.deposit.zenodo.mapper; - -import eu.eudat.data.entities.DMP; -import eu.eudat.data.entities.Organisation; -import eu.eudat.data.entities.UserDMP; -import eu.eudat.logic.proxy.config.DOIFunder; -import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; -import eu.eudat.models.deposit.zenodo.*; -import org.springframework.core.env.Environment; - -import java.time.Instant; -import java.util.*; -import java.util.stream.Collectors; - -public class DMPToZenodoMapper { - - public static ZenodoDeposit fromDMP(DMP dmp, Environment environment, ConfigLoader configLoader) { - Map extraProperties = dmp.getExtraProperties() != null ? new org.json.JSONObject(dmp.getExtraProperties()).toMap() : new HashMap<>(); - ZenodoDeposit deposit = new ZenodoDeposit(); - deposit.setMetadata(new ZenodoDepositMetadata()); - deposit.getMetadata().setTitle(dmp.getLabel()); - deposit.getMetadata().setUploadType("publication"); - deposit.getMetadata().setPublicationType("datamanagementplan"); - deposit.getMetadata().setDescription((dmp.getDescription() != null && !dmp.getDescription().isEmpty() ? dmp.getDescription() : "

")); - deposit.getMetadata().setVersion(dmp.getVersion().toString()); - ZenodoComunity community = new ZenodoComunity(); - community.setIdentifier(environment.getProperty("zenodo.community")); - deposit.getMetadata().setCommunities(Collections.singletonList(community)); - if (extraProperties.get("visible") == null) { - deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED); - deposit.getMetadata().setAccessConditions(""); - } else { - if (((Boolean) extraProperties.get("visible"))) { - Instant publicationDate = Instant.parse(extraProperties.get("publicDate").toString()); - if (publicationDate.isBefore(Instant.now())) { - deposit.getMetadata().setAccessRight(ZenodoAccessRight.OPEN); - } else { - deposit.getMetadata().setAccessRight(ZenodoAccessRight.EMBARGOED); - deposit.getMetadata().setEmbargoDate(publicationDate.toString()); - } - - if (extraProperties.get("license") != null) { - deposit.getMetadata().setLicense(((Map) extraProperties.get("license")).get("pid").toString()); - } - } else { - deposit.getMetadata().setAccessRight(ZenodoAccessRight.RESTRICTED); - deposit.getMetadata().setAccessConditions(""); - } - } - if (dmp.isPublic()) { - ZenodoRelator relator = new ZenodoRelator(); - relator.setIdentifier((environment.getProperty("dmp.domain") + "/external/zenodo/" + dmp.getId().toString())); - relator.setRelation("isIdenticalTo"); - deposit.getMetadata().setRelatedIdentifiers(Collections.singletonList(relator)); - } - deposit.getMetadata().setContributors(new LinkedList<>()); - List contributors = dmp.getUsers().stream().map(userDMP -> { - ZenodoContributor contributor = new ZenodoContributor(); - contributor.setName(userDMP.getUser().getName()); - contributor.setType("ProjectMember"); - if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) { - contributor.setAffiliation(dmp.getOrganisations() - .stream().map(Organisation::getLabel).collect(Collectors.joining(", "))); - } else { - contributor.setAffiliation(environment.getProperty("zenodo.affiliation")); - } - return contributor; - }).collect(Collectors.toList()); - - List researchers = dmp.getResearchers().stream().map(researcher -> { - ZenodoContributor contributor = new ZenodoContributor(); - contributor.setName(researcher.getLabel()); - contributor.setType("Researcher"); - String referenceHead = researcher.getReference().split(":")[0]; - String referenceTail = researcher.getReference().replace(referenceHead + ":", ""); - contributor.setAffiliation(referenceHead); - if (referenceHead.equalsIgnoreCase("ORCID")) { - contributor.setOrcid(referenceTail); - } - return contributor; - }).collect(Collectors.toList()); - - deposit.getMetadata().getContributors().addAll(contributors); - deposit.getMetadata().getContributors().addAll(researchers); - - if (dmp.getGrant().getReference() == null) { - dmp.getGrant().setReference("dmp:" + dmp.getGrant().getId()); - } - String grantReferenceHead = dmp.getGrant().getReference().split(":")[0]; - if (grantReferenceHead.equals("openaire")) { - String grantReferenceTail = dmp.getGrant().getReference().split(":")[3]; - DOIFunder doiFunder = configLoader.getDOIFunders().stream() - .filter(doiFunder1 -> dmp.getGrant().getFunder().getLabel().contains(doiFunder1.getFunder()) || doiFunder1.getFunder().contains(dmp.getGrant().getFunder().getLabel())) - .findFirst().orElse(null); - if (doiFunder != null) { - String finalId = doiFunder.getDOI() + "::" + grantReferenceTail; - ZenodoGrant grant = new ZenodoGrant(); - grant.setId(finalId); - deposit.getMetadata().setGrants(Collections.singletonList(grant)); - } - } - ZenodoContributor creator = new ZenodoContributor(); - creator.setName(dmp.getUsers().stream().filter(userDMP -> userDMP.getRole().equals(UserDMP.UserDMPRoles.OWNER.getValue())).findFirst().get().getUser().getName()); - if (dmp.getOrganisations() != null && !dmp.getOrganisations().isEmpty()) { - creator.setAffiliation(dmp.getOrganisations() - .stream().map(Organisation::getLabel).collect(Collectors.joining(", "))); - } else { - creator.setAffiliation(environment.getProperty("zenodo.affiliation")); - } - deposit.getMetadata().setCreators(Collections.singletonList(creator)); - - return deposit; - } -} - 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 539367e10..66ceff6c3 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 @@ -47,8 +47,12 @@ public class DmpRDAMapper { } } Dmp rda = new Dmp(); - if (dmp.getDoi() != null && !dmp.getDoi().isEmpty()) { - rda.setDmpId(DmpIdRDAMapper.toRDA(dmp.getDoi())); + if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { + for(EntityDoi doi: dmp.getDois()){ + if(doi.getRepositoryId().equals("Zenodo")){ + rda.setDmpId(DmpIdRDAMapper.toRDA(doi.getDoi())); + } + } } else { rda.setDmpId(DmpIdRDAMapper.toRDA(dmp.getId())); } @@ -105,7 +109,10 @@ public class DmpRDAMapper { DMP entity = new DMP(); entity.setLabel(rda.getTitle()); if (rda.getDmpId().getType() == DmpId.Type.DOI) { - entity.setDoi(rda.getDmpId().getIdentifier()); + 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())); diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/doi/DoiPublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/doi/DoiPublicModel.java new file mode 100644 index 000000000..4b8c5dbae --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/doi/DoiPublicModel.java @@ -0,0 +1,61 @@ +package eu.eudat.publicapi.models.doi; + +import eu.eudat.data.entities.EntityDoi; +import eu.eudat.logic.utilities.helpers.LabelGenerator; +import eu.eudat.models.DataModel; + +import java.util.UUID; + +public class DoiPublicModel implements DataModel, LabelGenerator { + private UUID id; + private String repositoryId; + private String doi; + + public UUID getId() { + return id; + } + public void setId(UUID id) { + this.id = id; + } + + public String getRepositoryId() { + return repositoryId; + } + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } + + public String getDoi() { + return doi; + } + public void setDoi(String doi) { + this.doi = doi; + } + + @Override + public DoiPublicModel fromDataModel(EntityDoi entity) { + this.id = entity.getId(); + this.repositoryId = entity.getRepositoryId(); + this.doi = entity.getDoi(); + return this; + } + + @Override + public EntityDoi toDataModel() throws Exception { + EntityDoi entity = new EntityDoi(); + entity.setId(this.getId()); + entity.setRepositoryId(this.getRepositoryId()); + entity.setDoi(this.getDoi()); + return entity; + } + + @Override + public String generateLabel() { + return this.getDoi(); + } + + @Override + public String getHint() { + return null; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java index 6b5040371..41c7b40cd 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/overviewmodels/DataManagementPlanPublicModel.java @@ -7,6 +7,7 @@ import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.models.DataModel; import eu.eudat.models.data.user.composite.PagedDatasetProfile; import eu.eudat.publicapi.models.associatedprofile.AssociatedProfilePublicModel; +import eu.eudat.publicapi.models.doi.DoiPublicModel; import eu.eudat.publicapi.models.grant.GrantPublicOverviewModel; import eu.eudat.publicapi.models.organisation.OrganizationPublicModel; import eu.eudat.publicapi.models.researcher.ResearcherPublicModel; @@ -35,7 +36,7 @@ public class DataManagementPlanPublicModel implements DataModel users; private String description; private Date publishedAt; - private String doi; + private List dois; public String getId() { @@ -150,11 +151,11 @@ public class DataManagementPlanPublicModel implements DataModel getDois() { + return dois; } - public void setDoi(String doi) { - this.doi = doi; + public void setDois(List dois) { + this.dois = dois; } @Override @@ -198,7 +199,7 @@ public class DataManagementPlanPublicModel implements DataModel new DoiPublicModel().fromDataModel(item)).collect(Collectors.toList()); return this; } diff --git a/dmp-db-scema/main/dmp-dump.sql b/dmp-db-scema/main/dmp-dump.sql index 1a63a0774..470447770 100644 --- a/dmp-db-scema/main/dmp-dump.sql +++ b/dmp-db-scema/main/dmp-dump.sql @@ -926,6 +926,27 @@ CREATE TABLE public."FileUpload" ALTER TABLE public."FileUpload" OWNER TO :POSTGRES_USER; +-- +-- Name: EntityDoi; Type: TABLE; Schema: public; Owner: :POSTGRES_USER +-- + +CREATE TYPE DoiEntityType AS ENUM ('DMP'); + +CREATE TABLE public."EntityDoi" +( + "ID" uuid NOT NULL, + "EntityType" DoiEntityType NOT NULL, + "RepositoryId" character varying(150) NOT NULL, + "Doi" character varying(50) NOt NULL, + "CreatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL, + "UpdatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL, + "EntityId" uuid NOT NULL, + CONSTRAINT "Doi_pkey" PRIMARY KEY ("ID"), + CONSTRAINT fk_doi_entityId FOREIGN KEY ("EntityId") REFERENCES public."DMP"("ID") +); + +ALTER TABLE public."EntityDoi" OWNER TO :POSTGRES_USER; + -- -- Name: Content Content_pkey; Type: CONSTRAINT; Schema: public; Owner: :POSTGRES_USER -- diff --git a/dmp-db-scema/updates/00.00.010_Add_EntityDoi_table.sql b/dmp-db-scema/updates/00.00.010_Add_EntityDoi_table.sql new file mode 100644 index 000000000..d92e9d1d8 --- /dev/null +++ b/dmp-db-scema/updates/00.00.010_Add_EntityDoi_table.sql @@ -0,0 +1,26 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.010'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +CREATE TYPE DoiEntityType AS ENUM ('DMP'); + +CREATE TABLE public."EntityDoi" +( + "ID" uuid NOT NULL, + "EntityType" DoiEntityType NOT NULL, + "RepositoryId" character varying(150) NOT NULL, + "Doi" character varying(50) NOt NULL, + "CreatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL, + "UpdatedAt" timestamp(6) with time zone DEFAULT now() NOT NULL, + "EntityId" uuid NOT NULL, + CONSTRAINT "Doi_pkey" PRIMARY KEY ("ID"), + CONSTRAINT fk_doi_entityId FOREIGN KEY ("EntityId") REFERENCES public."DMP"("ID") +); + +/*ALTER TABLE public."EntityDoi" OWNER TO :POSTGRES_USER;*/ + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.010', '2022-10-27 10:50:00.000000+02', now(), 'Add Doi Table for depositions'); + +END$$; \ No newline at end of file diff --git a/dmp-db-scema/updates/00.00.011.Migrate_data_from_dmp_doi_to_entitydoi.sql b/dmp-db-scema/updates/00.00.011.Migrate_data_from_dmp_doi_to_entitydoi.sql new file mode 100644 index 000000000..6189fe51a --- /dev/null +++ b/dmp-db-scema/updates/00.00.011.Migrate_data_from_dmp_doi_to_entitydoi.sql @@ -0,0 +1,14 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.011'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +INSERT INTO public."EntityDoi" ("ID", "EntityType", "RepositoryId", "Doi", "CreatedAt", "UpdatedAt", "EntityId") +SELECT uuid_generate_v4(), 'DMP', 'Zenodo', public."DMP"."DOI", now(), now(), public."DMP"."ID" +FROM public."DMP" +WHERE public."DMP"."DOI" IS NOT NULL; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.011', '2022-10-27 10:50:00.000000+02', now(), 'Migrate DMP.DOI to EntityDoi table'); + +END$$; \ No newline at end of file diff --git a/dmp-db-scema/updates/00.00.012.Delete_doi_from_dmp_table.sql b/dmp-db-scema/updates/00.00.012.Delete_doi_from_dmp_table.sql new file mode 100644 index 000000000..0a57ff8ab --- /dev/null +++ b/dmp-db-scema/updates/00.00.012.Delete_doi_from_dmp_table.sql @@ -0,0 +1,11 @@ +DO $$DECLARE + this_version CONSTANT varchar := '00.00.012'; +BEGIN + PERFORM * FROM "DBVersion" WHERE version = this_version; + IF FOUND THEN RETURN; END IF; + +ALTER TABLE public."DMP" DROP COLUMN "DOI"; + +INSERT INTO public."DBVersion" VALUES ('DMPDB', '00.00.012', '2022-10-27 10:50:00.000000+02', now(), 'Delete doi column from dmp table'); + +END$$; \ No newline at end of file diff --git a/dmp-frontend/src/app/core/common/enum/deposit-configuration-status.ts b/dmp-frontend/src/app/core/common/enum/deposit-configuration-status.ts new file mode 100644 index 000000000..fc5787572 --- /dev/null +++ b/dmp-frontend/src/app/core/common/enum/deposit-configuration-status.ts @@ -0,0 +1,5 @@ +export enum DepositConfigurationStatus { + System = 0, + User = 1, + BothSystemAndUser = 2 +} \ 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 6f81f1095..b36cf42f8 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -46,6 +46,7 @@ import { CollectionUtils } from './services/utilities/collection-utils.service'; import { TypeUtils } from './services/utilities/type-utils.service'; import { SpecialAuthGuard } from './special-auth-guard.service'; import {PrefillingService} from "@app/core/services/prefilling.service"; +import { DepositRepositoriesService } from './services/deposit-repositories/deposit-repositories.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -89,6 +90,7 @@ export class CoreServiceModule { FunderService, GrantFileUploadService, DmpService, + DepositRepositoriesService, DmpProfileService, ExternalSourcesService, ExternalSourcesConfigurationService, diff --git a/dmp-frontend/src/app/core/formatting.module.ts b/dmp-frontend/src/app/core/formatting.module.ts index afa46884f..cac6237cb 100644 --- a/dmp-frontend/src/app/core/formatting.module.ts +++ b/dmp-frontend/src/app/core/formatting.module.ts @@ -7,6 +7,8 @@ import { TimezoneInfoDisplayPipe } from './pipes/timezone-info-display.pipe'; import { EnumUtils } from './services/utilities/enum-utils.service'; 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"; // // @@ -21,7 +23,9 @@ import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe DateFormatPipe, DateTimeFormatPipe, DateTimeCultureFormatPipe, - JsonParserPipe + JsonParserPipe, + FieldValuePipe, + ColumnClassPipe ], exports: [ NgForLimitPipe, @@ -29,7 +33,9 @@ import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe DateFormatPipe, DateTimeFormatPipe, DateTimeCultureFormatPipe, - JsonParserPipe + JsonParserPipe, + FieldValuePipe, + ColumnClassPipe ], providers: [ EnumUtils, @@ -39,7 +45,9 @@ import { DateTimeCultureFormatPipe } from './pipes/date-time-culture-format.pipe DateFormatPipe, DateTimeFormatPipe, DateTimeCultureFormatPipe, - JsonParserPipe + JsonParserPipe, + FieldValuePipe, + ColumnClassPipe ] }) 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 02c91c68d..01890e243 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 @@ -45,6 +45,7 @@ export interface Multiplicity { min: number; max: number; placeholder: string; + tableView: boolean; } export interface Field { diff --git a/dmp-frontend/src/app/core/model/dataset-profile-definition/multiplicity.ts b/dmp-frontend/src/app/core/model/dataset-profile-definition/multiplicity.ts index 08d874f22..65af94550 100644 --- a/dmp-frontend/src/app/core/model/dataset-profile-definition/multiplicity.ts +++ b/dmp-frontend/src/app/core/model/dataset-profile-definition/multiplicity.ts @@ -4,5 +4,6 @@ export interface Multiplicity { min: number; max: number; placeholder: string; + tableView: boolean; } diff --git a/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts b/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts new file mode 100644 index 000000000..fe92ddd5b --- /dev/null +++ b/dmp-frontend/src/app/core/model/deposit/deposit-configuration.ts @@ -0,0 +1,11 @@ +import { DepositConfigurationStatus } from "@app/core/common/enum/deposit-configuration-status"; + +export class DepositConfigurationModel { + depositType: DepositConfigurationStatus; + repositoryId: string; + repositoryAuthorizationUrl: string; + repositoryRecordUrl: string; + repositoryClientId: string; + redirectUri: string; + hasLogo: boolean; +} diff --git a/dmp-frontend/src/app/core/model/deposit/deposit-request.ts b/dmp-frontend/src/app/core/model/deposit/deposit-request.ts new file mode 100644 index 000000000..10ee13980 --- /dev/null +++ b/dmp-frontend/src/app/core/model/deposit/deposit-request.ts @@ -0,0 +1,10 @@ +export class DepositRequest { + repositoryId: string; + dmpId: string; + accessToken: string; +} + +export class DepositCode { + repositoryId: string; + code: string; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/model/dmp/dmp-overview.ts b/dmp-frontend/src/app/core/model/dmp/dmp-overview.ts index da5802817..a5171ad61 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp-overview.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp-overview.ts @@ -4,6 +4,7 @@ import { DmpAssociatedProfileModel } from "../dmp-profile/dmp-associated-profile import { ResearcherModel } from "../researcher/researcher"; import { GrantOverviewModel } from "../grant/grant-overview"; import { DatasetOverviewModel } from "../dataset/dataset-overview"; +import { DoiModel } from "../doi/doi"; export interface DmpOverviewModel { id: string; @@ -26,4 +27,5 @@ export interface DmpOverviewModel { finalizedAt: Date; publishedAt: Date; doi: string; + dois: DoiModel[]; } diff --git a/dmp-frontend/src/app/core/model/doi/doi.ts b/dmp-frontend/src/app/core/model/doi/doi.ts new file mode 100644 index 000000000..c72ba0023 --- /dev/null +++ b/dmp-frontend/src/app/core/model/doi/doi.ts @@ -0,0 +1,7 @@ +export interface DoiModel { + id: string; + repositoryId: string; + doi: string; + createdAt: Date; + updatedAt: Date; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/pipes/column-class.pipe.ts b/dmp-frontend/src/app/core/pipes/column-class.pipe.ts new file mode 100644 index 000000000..d51bccd28 --- /dev/null +++ b/dmp-frontend/src/app/core/pipes/column-class.pipe.ts @@ -0,0 +1,11 @@ +import {Pipe, PipeTransform} from "@angular/core"; + +@Pipe({ + name: 'columnClass' +}) +export class ColumnClassPipe implements PipeTransform{ + + transform(value: number): any { + return 'col-' + Math.ceil(12/value); + } +} diff --git a/dmp-frontend/src/app/core/pipes/field-value.pipe.ts b/dmp-frontend/src/app/core/pipes/field-value.pipe.ts new file mode 100644 index 000000000..360b8e87e --- /dev/null +++ b/dmp-frontend/src/app/core/pipes/field-value.pipe.ts @@ -0,0 +1,85 @@ +import {Pipe, PipeTransform} from "@angular/core"; +import {DatePipe} from "@angular/common"; +import {DatasetProfileFieldViewStyle} from "@app/core/common/enum/dataset-profile-field-view-style"; + +@Pipe({ + name: 'fieldValue' +}) +export class FieldValuePipe implements PipeTransform { + + constructor(private date: DatePipe) { + } + + transform(controlValue: any): string | null { + let value = controlValue.value; + let renderStyle = controlValue.viewStyle?.renderStyle; + if (renderStyle && value) { + switch (renderStyle) { + case DatasetProfileFieldViewStyle.Currency: + if (value) { + return JSON.parse(value).name; + } + break; + case DatasetProfileFieldViewStyle.BooleanDecision: + return value == 'true' ? 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' : 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO'; + case DatasetProfileFieldViewStyle.CheckBox: + return value ? 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.YES' : 'DATASET-PROFILE-EDITOR.STEPS.FORM.FIELD.DEFAULT-VALUES.BOOLEAN-DECISION.NO'; + case DatasetProfileFieldViewStyle.RadioBox: + if (value && controlValue.data.options) { + return controlValue.data.options.find(option => option.value === value).label; + } + break; + case DatasetProfileFieldViewStyle.DatePicker: + return this.date.transform(controlValue.value, 'dd/MM/yyyy'); + case DatasetProfileFieldViewStyle.FreeText: + return value; + case DatasetProfileFieldViewStyle.ComboBox: + if (value && controlValue.data.options && !controlValue.data.multiList) { + return controlValue.data.options.find(option => value == option.value).label; + } else if (value && controlValue.data.options && controlValue.data.multiList) { + return controlValue.data.options.filter(option => value.includes(option.value)).map(option => option.label).join(','); + } + break; + case DatasetProfileFieldViewStyle.RichTextArea: + if(value) { + return value.replace(/ /g, ' ').replace(/(\r\n|\n|\r| +(?= ))|\s\s+/gm, " ").replace(/<[^>]*>/g, ''); + } + break; + case DatasetProfileFieldViewStyle.TextArea: + return value; + case DatasetProfileFieldViewStyle.Registries: + case DatasetProfileFieldViewStyle.Services: + case DatasetProfileFieldViewStyle.Researchers: + case DatasetProfileFieldViewStyle.Organizations: + case DatasetProfileFieldViewStyle.ExternalDatasets: + case DatasetProfileFieldViewStyle.DataRepositories: + case DatasetProfileFieldViewStyle.PubRepositories: + case DatasetProfileFieldViewStyle.JournalRepositories: + case DatasetProfileFieldViewStyle.Taxonomies: + case DatasetProfileFieldViewStyle.Licenses: + case DatasetProfileFieldViewStyle.Publications: + case DatasetProfileFieldViewStyle.Tags: + return this.parseJson(value); + case DatasetProfileFieldViewStyle.InternalDmpEntities: + return this.parseJson(value, 'label'); + case DatasetProfileFieldViewStyle.DatasetIdentifier: + case DatasetProfileFieldViewStyle.Validation: + if(value && value.identifier) { + return value.identifier; + } + break; + default: + return null; + } + } + return null; + } + + public parseJson(value: any, field: string = 'name') { + if(Array.isArray(value)) { + return value.map(element => JSON.parse(element)[field]).join(','); + } else { + return JSON.parse(value)[field]; + } + } +} 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 9b92ad064..64082cb55 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -66,11 +66,6 @@ export class ConfigurationService extends BaseComponent { return this._allowOrganizationCreator; } - private _doiLink: string; - get doiLink(): string { - return this._doiLink; - } - private _useSplash: string; get useSplash(): string { return this._useSplash; @@ -137,7 +132,6 @@ export class ConfigurationService extends BaseComponent { this._lockInterval = config.lockInterval; this._guideAssets = config.guideAssets; this._allowOrganizationCreator = config.allowOrganizationCreator; - this._doiLink = config.doiLink; this._useSplash = config.useSplash; this._orcidPath = config.orcidPath; if (config.matomo) { diff --git a/dmp-frontend/src/app/core/services/deposit-repositories/deposit-repositories.service.ts b/dmp-frontend/src/app/core/services/deposit-repositories/deposit-repositories.service.ts new file mode 100644 index 000000000..c40347075 --- /dev/null +++ b/dmp-frontend/src/app/core/services/deposit-repositories/deposit-repositories.service.ts @@ -0,0 +1,43 @@ +import { HttpClient, HttpHeaders } from '@angular/common/http'; +import { Injectable } from '@angular/core'; +import { DepositConfigurationModel } from '@app/core/model/deposit/deposit-configuration'; +import { DepositCode, DepositRequest } from '@app/core/model/deposit/deposit-request'; +import { DoiModel } from '@app/core/model/doi/doi'; +import { Observable } from 'rxjs'; +import { ConfigurationService } from '../configuration/configuration.service'; +import { BaseHttpService } from '../http/base-http.service'; + +@Injectable() +export class DepositRepositoriesService { + + private actionUrl: string; + private headers = new HttpHeaders(); + + constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { + this.actionUrl = configurationService.server + 'deposit/'; + } + + getAvailableRepos(): Observable { + return this.http.get(this.actionUrl + 'repos', { headers: this.headers }); + } + + getAccessToken(repositoryId: string, code: string): Observable { + const depositCode = new DepositCode(); + depositCode.repositoryId = repositoryId; + depositCode.code = code; + return this.http.post(this.actionUrl + 'getAccessToken', depositCode, { headers: this.headers }); + } + + createDoi(repositoryId: string, dmpId: string, accessToken: string | null): Observable { + const depositRequest = new DepositRequest(); + depositRequest.repositoryId = repositoryId; + depositRequest.dmpId = dmpId; + depositRequest.accessToken = accessToken; + return this.http.post(this.actionUrl + 'createDoi', depositRequest, { headers: this.headers }); + } + + getLogo(repositoryId: string): Observable { + return this.http.get(this.actionUrl + 'logo/' + repositoryId, { headers: this.headers }); + } + +} diff --git a/dmp-frontend/src/app/core/services/matomo/matomo-service.ts b/dmp-frontend/src/app/core/services/matomo/matomo-service.ts index f4711f996..700535510 100644 --- a/dmp-frontend/src/app/core/services/matomo/matomo-service.ts +++ b/dmp-frontend/src/app/core/services/matomo/matomo-service.ts @@ -36,4 +36,15 @@ export class MatomoService { this.matomoTracker.trackSiteSearch(keyword, category, resultsCount); } } + + trackDownload(category: "dmps"|"datasets", type: "docx"|"pdf"|"xml"|"json", id: string): void { + if (this.configurationService.matomoEnabled) { + var principal = this.authService.current(); + if (principal != null) { this.matomoTracker.setUserId(principal.id); } + this.matomoTracker.trackLink(this.configurationService.server + category + "/" + type + "/" + id, "download"); + + // this.matomoTracker.trackLink(url, "download"); + // this.matomoTracker.trackEvent(category, "Downloaded", type); + } + } } 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 e08ffe914..0ef6e4b2f 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 @@ -43,6 +43,9 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp } private _configuration: MultipleAutoCompleteConfiguration; + @Input() + separatorKeysCodes = []; + // Selected Option Event @Output() optionSelected: EventEmitter = new EventEmitter(); @Output() optionRemoved: EventEmitter = new EventEmitter(); @@ -69,7 +72,6 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp _groupedItems: Observable; selectable = false; removable = true; - separatorKeysCodes = [ENTER, COMMA]; get empty() { return (!this.value || this.value.length === 0) && (!this.inputValue || this.inputValue.length === 0); } @@ -377,7 +379,7 @@ export class MultipleAutoCompleteComponent extends _CustomComponentMixinBase imp //Chip Functions _addItem(event: MatChipInputEvent): void { - + console.log(this._items) const input = event.input; const value = event.value; // Add our fruit diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/multiplicity-editor-model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/multiplicity-editor-model.ts index 0c8cad83b..5f219c713 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/multiplicity-editor-model.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/multiplicity-editor-model.ts @@ -6,11 +6,13 @@ export class MultiplicityEditorModel extends BaseFormModel { public min: number; public max: number; public placeholder: string; + public tableView: boolean; fromModel(item: Multiplicity): MultiplicityEditorModel { this.min = item.min; this.max = item.max; this.placeholder = item.placeholder; + this.tableView = item.tableView; return this; } @@ -21,7 +23,8 @@ export class MultiplicityEditorModel extends BaseFormModel { placeholder: [{ value: this.placeholder, disabled: (disabled && !skipDisable.includes('MultiplicityEditorModel.placeholder')) - }] + }], + tableView: [{value: this.tableView, disabled: (disabled && !skipDisable.includes('MultiplicityEditorModel.tableView'))}] }); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html index 5aa4096d6..72d631d4f 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.html @@ -117,6 +117,12 @@ type="text" [formControl]="form.get('multiplicity').get('placeholder')"> +
+ + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.MULTIPLICITY-TABLEVIEW' | translate}} + +
@@ -198,7 +204,7 @@
- +
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 bc404e5e4..44c1e2c4e 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 @@ -261,7 +261,8 @@ export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent i description: formValue.description, hasCommentField: formValue.hasCommentField, commentFieldValue: '', - multiplicity: {max: formValue.multiplicity.max, min: formValue.multiplicity.min, placeholder: formValue.multiplicity.placeholder}, + multiplicity: {max: formValue.multiplicity.max, min: formValue.multiplicity.min, + placeholder: formValue.multiplicity.placeholder, tableView: formValue.multiplicity.tableView}, multiplicityItems:null, fields: fields.map(editorField=>{ const model = new DatasetDescriptionFieldEditorModel().fromModel(editorField); 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 9ea712673..c0288f59d 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 @@ -468,9 +468,20 @@
- diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.scss index 6caaaed3b..6a9648d6e 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/dataset-profile-editor.component.scss @@ -133,17 +133,19 @@ $blue-color-light: #5cf7f2; border-radius: 30px; border: 1px solid #129D99; background: transparent; - padding-left: 2em; - padding-right: 2em; + //padding-left: 2em; + //padding-right: 2em; height: 2.5em; + min-width: 110px; + width: auto; box-shadow: 0px 3px 6px #1E202029; color: #129D99; flex: 0 0 auto; &.save-btn{ background-color: #f7dd72; border: 1px solid transparent; - padding-left: 2em; - padding-right: 2em; + //padding-left: 2em; + //padding-right: 2em; box-shadow: 0px 3px 6px #1E202029; color: #212121; 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 424072c2b..b5e80c54f 100644 --- a/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/drafts/drafts.component.ts @@ -263,6 +263,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "pdf", dataset.id); }); } @@ -274,6 +275,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "docx", dataset.id); }); } @@ -286,6 +288,7 @@ export class DraftsComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "xml", dataset.id); }); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts index 0110adf19..ffcf3740b 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-activity/recent-edited-activity.component.ts @@ -425,6 +425,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "xml", id); }); } @@ -436,6 +437,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "docx", id); }); } @@ -447,6 +449,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "pdf", id); }); } @@ -457,6 +460,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn 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); }); @@ -476,6 +480,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "pdf", dataset.id); }); } @@ -487,6 +492,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "docx", dataset.id); }); } @@ -499,6 +505,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "xml", dataset.id); }); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts index 1eb17a363..6f51f4a54 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.ts @@ -27,6 +27,7 @@ import { Location } from '@angular/common'; 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 {ConfigurationService} from "@app/core/services/configuration/configuration.service"; @Component({ selector: 'app-recent-edited-dataset-activity', @@ -61,7 +62,8 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen private location: Location, private lockService: LockService, private httpClient: HttpClient, - private matomoService: MatomoService + private matomoService: MatomoService, + private configurationService: ConfigurationService ) { super(); } @@ -304,6 +306,7 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "pdf", dataset.id); }); } @@ -315,6 +318,7 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "docx", dataset.id); }); } @@ -327,6 +331,7 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "xml", dataset.id); }); } 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 ae9bfc46d..4ad783614 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 @@ -369,6 +369,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "xml", id); }); } @@ -380,6 +381,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "docx", id); }); } @@ -391,6 +393,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "pdf", id); }); } @@ -401,6 +404,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O 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); }); 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 8aba4d08e..a33d78874 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 @@ -27,15 +27,52 @@
-
- + + + + + +
+ + + +
+
- diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.scss b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.scss index e6509e5df..48fdc4538 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.scss +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.scss @@ -208,7 +208,7 @@ align-items: center; } - .dataset-save-btn { + .dataset-save-btn, .dataset-export-btn { background: #ffffff 0% 0% no-repeat padding-box; border-radius: 30px; opacity: 1; diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts index 15f4e3452..618db108c 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-wizard.component.ts @@ -532,7 +532,6 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme if (profiledId && profiledId.length > 0) { this.formGroup.removeControl('datasetProfileDefinition'); this.getDefinition(profiledId); - console.log(this.table0fContents.tocentries.length + 1); } } @@ -660,7 +659,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme // } - submit(saveType?: SaveType) { + submit(saveType?: SaveType, onSuccess: Function = null, onError: Function = null) { this.scrollTop = document.getElementById('dataset-editor-form').scrollTop; this.tocScrollTop = document.getElementById('stepper-options').scrollTop; this.datasetWizardService.createDataset(this.formGroup.getRawValue()) @@ -670,8 +669,16 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.hasChanges = false; this.datasetIsOnceSaved = true; this.onCallbackSuccess(data, saveType); + if(onSuccess) { + onSuccess(); + } }, - error => this.onCallbackError(error)); + error => { + if(onError) { + onError(); + } + this.onCallbackError(error) + }); } @@ -841,16 +848,27 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme .pipe( filter(x => x), takeUntil(this._destroyed) - ).subscribe(_ => { - this.viewOnly = false; - this.datasetWizardModel.status = DatasetStatus.Draft; - setTimeout(x => { - this.formGroup = null; - }); - setTimeout(x => { - this.formGroup = this.datasetWizardModel.buildForm(); - this.registerFormListeners(); - }); + ).subscribe(result => { + if (result) { + // if (!this.isFormValid()) { return; } + this.formGroup.get('status').setValue(DatasetStatus.Draft); + this.submit(SaveType.finalize, () => { + this.viewOnly = false; + this.datasetWizardModel.status = DatasetStatus.Draft; + setTimeout(x => { + this.formGroup = null; + }); + setTimeout(x => { + this.formGroup = this.datasetWizardModel.buildForm(); + this.registerFormListeners(); + }); + }, () => { + this.formGroup.get('status').setValue(DatasetStatus.Finalized); + this.viewOnly = true; + }); + } else { + this.saving = false; + } }); @@ -886,7 +904,11 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme if (result) { // if (!this.isFormValid()) { return; } this.formGroup.get('status').setValue(DatasetStatus.Finalized); - this.submit(SaveType.finalize); + this.submit(SaveType.finalize, null, () => { + this.formGroup.get('status').setValue(DatasetStatus.Draft); + }); + } else { + this.saving = false; } }); } @@ -958,37 +980,40 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme }); } - downloadPDF(): void { - this.datasetWizardService.downloadPDF(this.downloadDocumentId) + downloadPDF(id: string): void { + this.datasetWizardService.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('datasets', "pdf", id); }); } - downloadDOCX(): void { - this.datasetWizardService.downloadDOCX(this.downloadDocumentId) + downloadDOCX(id: string): void { + this.datasetWizardService.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('datasets', "docx", id); }); } - downloadXML(): void { - this.datasetWizardService.downloadXML(this.downloadDocumentId) + downloadXML(id: string): void { + this.datasetWizardService.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('datasets', "xml", id); }); } diff --git a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.ts b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.ts index 284dd1a3d..04d6db3d1 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.ts +++ b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.ts @@ -99,6 +99,7 @@ export class DatasetListingItemComponent extends BaseComponent implements OnInit const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "pdf", dataset.id); }); } @@ -110,6 +111,7 @@ export class DatasetListingItemComponent extends BaseComponent implements OnInit const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "docx", dataset.id); }); } @@ -122,6 +124,7 @@ export class DatasetListingItemComponent extends BaseComponent implements OnInit const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "xml", dataset.id); }); } diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts index c665817f2..750f98a47 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.ts @@ -340,6 +340,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "pdf", id); }); } @@ -351,6 +352,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "docx", id); }); } @@ -362,6 +364,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('datasets', "xml", id); }); } diff --git a/dmp-frontend/src/app/ui/dmp/dmp.module.ts b/dmp-frontend/src/app/ui/dmp/dmp.module.ts index 01f0355b6..d6060d4b1 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp.module.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp.module.ts @@ -1,54 +1,61 @@ -import { NgModule } from '@angular/core'; -import { FormattingModule } from '@app/core/formatting.module'; -import { AutoCompleteModule } from '@app/library/auto-complete/auto-complete.module'; -import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; -import { ExportMethodDialogModule } from '@app/library/export-method-dialog/export-method-dialog.module'; -import { UrlListingModule } from '@app/library/url-listing/url-listing.module'; -import { DmpCloneComponent } from '@app/ui/dmp/clone/dmp-clone.component'; -import { DmpRoutingModule } from '@app/ui/dmp/dmp.routing'; -import { AddResearcherComponent } from '@app/ui/dmp/editor/add-researcher/add-researcher.component'; -import { AvailableProfilesComponent } from '@app/ui/dmp/editor/available-profiles/available-profiles.component'; -import { DatasetsTabComponent } from '@app/ui/dmp/editor/datasets-tab/datasets-tab.component'; -import { DmpEditorComponent } from '@app/ui/dmp/editor/dmp-editor.component'; -import { DmpFinalizeDialogComponent } from '@app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component'; -import { DynamicDmpFieldResolverComponent } from '@app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component'; -import { DynamicFieldGrantComponent } from '@app/ui/dmp/editor/dynamic-fields-grant/dynamic-field-grant/dynamic-field-grant.component'; -import { DynamicFieldsGrantComponent } from '@app/ui/dmp/editor/dynamic-fields-grant/dynamic-fields-grant.component'; -import { GeneralTabComponent } from '@app/ui/dmp/editor/general-tab/general-tab.component'; -import { GrantTabComponent } from '@app/ui/dmp/editor/grant-tab/grant-tab.component'; -import { PeopleTabComponent } from '@app/ui/dmp/editor/people-tab/people-tab.component'; -import { InvitationAcceptedComponent } from '@app/ui/dmp/invitation/accepted/dmp-invitation-accepted.component'; -import { DmpInvitationDialogComponent } from '@app/ui/dmp/invitation/dmp-invitation-dialog.component'; -import { DmpCriteriaComponent } from '@app/ui/dmp/listing/criteria/dmp-criteria.component'; -import { DmpUploadDialogue } from '@app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component'; -import { DmpListingComponent } from '@app/ui/dmp/listing/dmp-listing.component'; -import { DmpListingItemComponent } from '@app/ui/dmp/listing/listing-item/dmp-listing-item.component'; -import { DmpOverviewModule } from '@app/ui/dmp/overview/dmp-overview.module'; -import { DmpWizardComponent } from '@app/ui/dmp/wizard/dmp-wizard.component'; -import { DmpWizardEditorComponent } from '@app/ui/dmp/wizard/editor/dmp-wizard-editor.component'; -import { DmpWizardDatasetListingComponent } from '@app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component'; -import { CommonFormsModule } from '@common/forms/common-forms.module'; -import { FormValidationErrorsDialogModule } from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module'; -import { CommonUiModule } from '@common/ui/common-ui.module'; -import { MultipleChoiceDialogModule } from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module'; -import { AddOrganizationComponent } from './editor/add-organization/add-organization.component'; -import { AddCostComponent } from './editor/cost-editor/add-cost/add-cost.component'; -import { CostListingComponent } from './editor/cost-editor/cost-listing/cost-listing.component'; -import { DmpCriteriaDialogComponent } from './listing/criteria/dmp-criteria-dialog.component'; -import { StartNewDmpDialogComponent } from './start-new-dmp-dialogue/start-new-dmp-dialog.component'; -import { MainInfoComponent } from './editor/main-info/main-info.component'; -import { FundingInfoComponent } from './editor/funding-info/funding-info.component'; -import { DatasetInfoComponent } from './editor/dataset-info/dataset-info.component'; -import { DatasetEditorDetailsModule } from './editor/dataset-editor-details/dataset-editor-details.module'; -import { DatasetEditorDetailsComponent } from './editor/dataset-editor-details/dataset-editor-details.component'; -import { DatasetDescriptionFormModule } from '../misc/dataset-description-form/dataset-description-form.module'; -import { LicenseInfoComponent } from './editor/license-info/license-info.component'; -import { StartNewDatasetDialogComponent } from './start-new-dataset-dialogue/start-new-dataset-dialog.component'; -import { NgxDropzoneModule } from 'ngx-dropzone'; -import { DmpToDatasetDialogComponent } from './dmp-to-dataset/dmp-to-dataset-dialog.component'; -import { FormProgressIndicationComponent } from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.component'; -import { FormProgressIndicationModule } from '../misc/dataset-description-form/components/form-progress-indication/form-progress-indication.module'; -import { DatasetPreviewDialogComponent } from './dataset-preview/dataset-preview-dialog.component'; +import {NgModule} from '@angular/core'; +import {FormattingModule} from '@app/core/formatting.module'; +import {AutoCompleteModule} from '@app/library/auto-complete/auto-complete.module'; +import {ConfirmationDialogModule} from '@common/modules/confirmation-dialog/confirmation-dialog.module'; +import {ExportMethodDialogModule} from '@app/library/export-method-dialog/export-method-dialog.module'; +import {UrlListingModule} from '@app/library/url-listing/url-listing.module'; +import {DmpCloneComponent} from '@app/ui/dmp/clone/dmp-clone.component'; +import {DmpRoutingModule} from '@app/ui/dmp/dmp.routing'; +import {AddResearcherComponent} from '@app/ui/dmp/editor/add-researcher/add-researcher.component'; +import {AvailableProfilesComponent} from '@app/ui/dmp/editor/available-profiles/available-profiles.component'; +import {DatasetsTabComponent} from '@app/ui/dmp/editor/datasets-tab/datasets-tab.component'; +import {DmpEditorComponent} from '@app/ui/dmp/editor/dmp-editor.component'; +import {DmpFinalizeDialogComponent} from '@app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component'; +import { + DynamicDmpFieldResolverComponent +} from '@app/ui/dmp/editor/dynamic-field-resolver/dynamic-dmp-field-resolver.component'; +import { + DynamicFieldGrantComponent +} from '@app/ui/dmp/editor/dynamic-fields-grant/dynamic-field-grant/dynamic-field-grant.component'; +import {DynamicFieldsGrantComponent} from '@app/ui/dmp/editor/dynamic-fields-grant/dynamic-fields-grant.component'; +import {GeneralTabComponent} from '@app/ui/dmp/editor/general-tab/general-tab.component'; +import {GrantTabComponent} from '@app/ui/dmp/editor/grant-tab/grant-tab.component'; +import {PeopleTabComponent} from '@app/ui/dmp/editor/people-tab/people-tab.component'; +import {InvitationAcceptedComponent} from '@app/ui/dmp/invitation/accepted/dmp-invitation-accepted.component'; +import {DmpInvitationDialogComponent} from '@app/ui/dmp/invitation/dmp-invitation-dialog.component'; +import {DmpCriteriaComponent} from '@app/ui/dmp/listing/criteria/dmp-criteria.component'; +import {DmpUploadDialogue} from '@app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component'; +import {DmpListingComponent} from '@app/ui/dmp/listing/dmp-listing.component'; +import {DmpListingItemComponent} from '@app/ui/dmp/listing/listing-item/dmp-listing-item.component'; +import {DmpOverviewModule} from '@app/ui/dmp/overview/dmp-overview.module'; +import {DmpWizardComponent} from '@app/ui/dmp/wizard/dmp-wizard.component'; +import {DmpWizardEditorComponent} from '@app/ui/dmp/wizard/editor/dmp-wizard-editor.component'; +import {DmpWizardDatasetListingComponent} from '@app/ui/dmp/wizard/listing/dmp-wizard-dataset-listing.component'; +import {CommonFormsModule} from '@common/forms/common-forms.module'; +import { + FormValidationErrorsDialogModule +} from '@common/forms/form-validation-errors-dialog/form-validation-errors-dialog.module'; +import {CommonUiModule} from '@common/ui/common-ui.module'; +import {MultipleChoiceDialogModule} from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.module'; +import {AddOrganizationComponent} from './editor/add-organization/add-organization.component'; +import {AddCostComponent} from './editor/cost-editor/add-cost/add-cost.component'; +import {CostListingComponent} from './editor/cost-editor/cost-listing/cost-listing.component'; +import {DmpCriteriaDialogComponent} from './listing/criteria/dmp-criteria-dialog.component'; +import {StartNewDmpDialogComponent} from './start-new-dmp-dialogue/start-new-dmp-dialog.component'; +import {MainInfoComponent} from './editor/main-info/main-info.component'; +import {FundingInfoComponent} from './editor/funding-info/funding-info.component'; +import {DatasetInfoComponent} from './editor/dataset-info/dataset-info.component'; +import {DatasetEditorDetailsModule} from './editor/dataset-editor-details/dataset-editor-details.module'; +import {DatasetEditorDetailsComponent} from './editor/dataset-editor-details/dataset-editor-details.component'; +import {DatasetDescriptionFormModule} from '../misc/dataset-description-form/dataset-description-form.module'; +import {LicenseInfoComponent} from './editor/license-info/license-info.component'; +import {StartNewDatasetDialogComponent} from './start-new-dataset-dialogue/start-new-dataset-dialog.component'; +import {NgxDropzoneModule} from 'ngx-dropzone'; +import {DmpToDatasetDialogComponent} from './dmp-to-dataset/dmp-to-dataset-dialog.component'; +import { + FormProgressIndicationModule +} 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"; @NgModule({ diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.html new file mode 100644 index 000000000..08206f330 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.html @@ -0,0 +1,13 @@ +
+ +

{{ 'DMP-LISTING.ACTIONS.DEPOSIT' | translate }}

+
+ + + diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.scss b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.scss new file mode 100644 index 000000000..4d8681e21 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.scss @@ -0,0 +1,36 @@ +.frame-btn { + border: 1px solid #212121; + color: black; + background: #ffffff; + box-shadow: 0px 2px 6px #00000029; + display: flex; + justify-content: center; + align-items: center; +} + +.frame-txt { + color: #000000; + font-size: 0.75em; + font-weight: bold; + letter-spacing: 0px; + text-transform: uppercase; + cursor: pointer; +} + +.mat-mini-fab { + width: 2.5em; + height: 2.5em; +} + +.mat-mini-fab-icon { + font-size: 1.2em; + display: flex; + justify-content: center; + align-items: center; +} + +.logo { + margin-right: 16px; + max-width: 24px; + max-height: 24px; +} diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.ts new file mode 100644 index 000000000..36a1572a3 --- /dev/null +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-deposit-dropdown/dmp-deposit-dropdown.component.ts @@ -0,0 +1,139 @@ +import {Component, EventEmitter, Input, OnInit, Output} from '@angular/core'; +import {MatDialog} from '@angular/material/dialog'; +import {DepositConfigurationStatus} from '@app/core/common/enum/deposit-configuration-status'; +import {DepositConfigurationModel} from '@app/core/model/deposit/deposit-configuration'; +import {DmpOverviewModel} from '@app/core/model/dmp/dmp-overview'; +import {DoiModel} from '@app/core/model/doi/doi'; +import {DepositRepositoriesService} from '@app/core/services/deposit-repositories/deposit-repositories.service'; +import { + SnackBarNotificationLevel, + UiNotificationService +} from '@app/core/services/notification/ui-notification-service'; +import {Oauth2DialogService} from '@app/ui/misc/oauth2-dialog/service/oauth2-dialog.service'; +import {BaseComponent} from '@common/base/base.component'; +import {MultipleChoiceDialogComponent} from '@common/modules/multiple-choice-dialog/multiple-choice-dialog.component'; +import {TranslateService} from '@ngx-translate/core'; +import {takeUntil} from 'rxjs/operators'; +import {DomSanitizer, SafeResourceUrl} from "@angular/platform-browser"; + +@Component({ + selector: 'app-dmp-deposit-dropdown', + templateUrl: './dmp-deposit-dropdown.component.html', + styleUrls: ['./dmp-deposit-dropdown.component.scss'] +}) +export class DmpDepositDropdown extends BaseComponent implements OnInit { + @Input() + inputRepos: DepositConfigurationModel[]; + @Input() + dmp: DmpOverviewModel; + outputRepos = []; + logos: Map = new Map(); + @Output() + outputReposEmitter: EventEmitter = new EventEmitter(); + private oauthLock: boolean; + + constructor( + private depositRepositoriesService: DepositRepositoriesService, + private dialog: MatDialog, + private language: TranslateService, + private translate: TranslateService, + private uiNotificationService: UiNotificationService, + private oauth2DialogService: Oauth2DialogService, + private sanitizer: DomSanitizer + ) { + super(); + } + + hasDoi(repo, dois, i) { + return repo.repositoryId !== dois[i].repositoryId; + } + + ngOnInit(): void { + for (var i = 0; i < this.dmp.dois.length; i++) { + this.inputRepos = this.inputRepos.filter(r => this.hasDoi(r, this.dmp.dois, i)); + } + this.inputRepos.forEach(repo => { + if(repo.hasLogo) { + this.depositRepositoriesService.getLogo(repo.repositoryId).subscribe(logo => { + this.logos.set(repo.repositoryId, this.sanitizer.bypassSecurityTrustResourceUrl('data:image/png;base64, ' + logo)); + }) + } + }) + } + + deposit(repo: DepositConfigurationModel) { + + if (repo.depositType == DepositConfigurationStatus.BothSystemAndUser) { + + const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, { + maxWidth: '600px', + restoreFocus: false, + data: { + message: this.language.instant('DMP-OVERVIEW.DEPOSIT.ACCOUNT-LOGIN'), + titles: [this.language.instant('DMP-OVERVIEW.DEPOSIT.LOGIN', {'repository': repo.repositoryId}), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')] + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { + switch (result) { + case 0: + this.showOauth2Dialog(repo.repositoryAuthorizationUrl + '?client_id=' + repo.repositoryClientId + + '&response_type=code&scope=deposit:write+deposit:actions+user:email&state=astate&redirect_uri=' + + repo.redirectUri, repo, this.dmp); + break; + case 1: + this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null) + .pipe(takeUntil(this._destroyed)) + .subscribe(doi => { + this.onDOICallbackSuccess(); + this.outputRepos.push(doi); + this.outputReposEmitter.emit(this.outputRepos); + }, error => this.onDOICallbackError(error)); + break; + } + }); + + } else if (repo.depositType == DepositConfigurationStatus.System) { + this.depositRepositoriesService.createDoi(repo.repositoryId, this.dmp.id, null) + .pipe(takeUntil(this._destroyed)) + .subscribe(doi => { + this.onDOICallbackSuccess(); + this.outputRepos.push(doi); + this.outputReposEmitter.emit(this.outputRepos); + }, error => this.onDOICallbackError(error)); + } + } + + onDOICallbackSuccess(): void { + this.uiNotificationService.snackBarNotification(this.language.instant('DMP-EDITOR.SNACK-BAR.SUCCESSFUL-DOI'), SnackBarNotificationLevel.Success); + } + + onDOICallbackError(error) { + this.uiNotificationService.snackBarNotification(error.error.message ? error.error.message : this.language.instant('DMP-EDITOR.SNACK-BAR.UNSUCCESSFUL-DOI'), SnackBarNotificationLevel.Error); + } + + showOauth2Dialog(url: string, repo: DepositConfigurationModel, dmp: DmpOverviewModel) { + this.oauth2DialogService.login(url) + .pipe(takeUntil(this._destroyed)) + .subscribe(result => { + if (result !== undefined) { + if (result.oauthCode !== undefined && result.oauthCode !== null && !this.oauthLock) { + this.depositRepositoriesService.getAccessToken(repo.repositoryId, result.oauthCode) + .pipe(takeUntil(this._destroyed)) + .subscribe(token => { + this.depositRepositoriesService.createDoi(repo.repositoryId, dmp.id, token) + .pipe(takeUntil(this._destroyed)) + .subscribe(doi => { + this.onDOICallbackSuccess(); + this.outputRepos.push(doi); + this.outputReposEmitter.emit(this.outputRepos); + }, error => this.onDOICallbackError(error)); + }); + this.oauthLock = true; + } + } else { + this.oauthLock = false; + } + }); + } + +} 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 4ff6b5729..ae70a647e 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 @@ -11,6 +11,38 @@
{{ formGroup.get('label').value }} ({{'DMP-EDITOR.CHANGES' | translate}})
+
+ + + + + + + +
+ + + +
@@ -23,6 +55,7 @@
+
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.scss b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.scss index 63259747e..ef7f7b0a9 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.scss @@ -157,8 +157,8 @@ a:hover { align-items: center; } -.save-btn { - background: #ffffff 0% 0% no-repeat padding-box; +.save-btn, .dmp-export-btn { + background: #ffffff 0% 0% no-repeat padding-box !important; border-radius: 30px; opacity: 1; width: 110px; diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts index 007dfa991..f5ca821cb 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-editor.component.ts @@ -699,6 +699,7 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements 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); }); } @@ -709,6 +710,7 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements 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); }); } @@ -719,6 +721,7 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements 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); }); } @@ -729,6 +732,7 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements 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); }); @@ -980,7 +984,8 @@ export class DmpEditorComponent extends CheckDeactivateBaseComponent implements dmpDescription: this.formGroup.get('description').value, datasets: this.formGroup.get('datasets').value.map(x => { return { label: x.label, id: x.id, status: x.status }; - }) + }), + accessRights: false } const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, { diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html index 634ea89e8..a19f9cc0d 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.html @@ -64,8 +64,11 @@
{{ 'DMP-FINALISE-DIALOG.IMPACT' | translate }}
-
- {{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION' | translate }} +
+ {{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-PUBLISH' | translate }} +
+
+ {{ 'DMP-FINALISE-DIALOG.AFTER-FINALIZATION-RESTRICT-ACCESS' | translate }}
diff --git a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts index f16ff8747..dd8b27e34 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/editor/dmp-finalize-dialog/dmp-finalize-dialog.component.ts @@ -95,6 +95,7 @@ export interface DmpFinalizeDialogInput { dmpLabel: string; dmpDescription: string; datasets: DmpFinalizeDialogDataset[]; + accessRights: boolean; } export interface DmpFinalizeDialogDataset { diff --git a/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.html b/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.html index f722893f0..8d9829904 100644 --- a/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.html +++ b/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.html @@ -10,7 +10,7 @@ diff --git a/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.ts b/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.ts index ee29a5ace..f3304275b 100644 --- a/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.ts +++ b/dmp-frontend/src/app/ui/dmp/invitation/dmp-invitation-dialog.component.ts @@ -32,7 +32,6 @@ export class DmpInvitationDialogComponent extends BaseComponent implements OnIni public filteredUsers: DmpInvitationUser[]; public emails: string[] = []; public roles = Role; - visible = true; selectable = true; removable = true; 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 c6e72d002..aa1830664 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 @@ -226,6 +226,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "xml", id); }); } @@ -237,6 +238,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "docx", id); }); } @@ -248,6 +250,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { const filename = this.getFilenameFromContentDispositionHeader(response.headers.get('Content-Disposition')); FileSaver.saveAs(blob, filename); + this.matomoService.trackDownload('dmps', "pdf", id); }); } @@ -258,6 +261,7 @@ export class DmpListingItemComponent extends BaseComponent implements OnInit { 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); }); 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 c0efb9577..0d69b4b3a 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 @@ -112,23 +112,49 @@
-

{{'DMP-EDITOR.TITLE.SUBTITLE' | translate}}

-
-

- -

-
- -
+
@@ -141,13 +167,8 @@
-
- -

{{ 'DMP-LISTING.ACTIONS.DEPOSIT' | translate }}

-
-
+ +
@@ -167,12 +188,12 @@

{{ 'DMP-LISTING.ACTIONS.START-NEW-VERSION' | translate }}

-
+
+
+
+
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field-dialog/form-composite-field-dialog.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field-dialog/form-composite-field-dialog.component.ts new file mode 100644 index 000000000..d1a3625cb --- /dev/null +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-field-dialog/form-composite-field-dialog.component.ts @@ -0,0 +1,31 @@ +import {Component, Inject} from "@angular/core"; +import {MAT_DIALOG_DATA, MatDialogRef} from "@angular/material/dialog"; +import {VisibilityRulesService} from "@app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service"; + +@Component({ + selector: 'app-form-composite-field-dialog', + templateUrl: 'form-composite-field-dialog.component.html' +}) +export class FormCompositeFieldDialogComponent { + + public visibilityRulesService: VisibilityRulesService; + + constructor( + private dialogRef: MatDialogRef, + @Inject(MAT_DIALOG_DATA) public data: any + ) { + this.visibilityRulesService = data.visibilityRulesService; + } + + cancel() { + this.dialogRef.close(); + } + + save() { + this.dialogRef.close(this.data.formGroup); + } + + public close() { + this.dialogRef.close(false); + } +} 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 a158ea875..24f35ac7a 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 @@ -1,20 +1,19 @@ -
- +
-
+
-
- -
+ [datasetProfileId]="datasetProfileId" [isChild]="isChild"> +
+ +
-
+
@@ -37,6 +36,9 @@ Add one more field +
--> +
+
{{this.fieldFormGroup.get('data').value.label}}
+
- + @@ -32,8 +33,8 @@ -
diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts index b3937f33a..4fdfb42e4 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.ts @@ -40,7 +40,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit private visibilityRulesService: VisibilityRulesService, ) { super(); - + } ngOnInit() { @@ -48,7 +48,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit const rules_to_append = this._enrichWithMultiplicityRules(this.tocentries); this.visibilityRulesService.buildVisibilityRules([...this.visibilityRules, ...rules_to_append ], this.form); - + // if (this.form) { // this.form.valueChanges // .pipe(takeUntil(this._destroyed)) @@ -57,7 +57,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit // }); // } this.visibilityRulesInstance.emit(this.visibilityRulesService); - + @@ -139,15 +139,15 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit const childIdsWithVisRules = (entry.form.get('fields') as FormArray).controls.reduce((all, s) => { const sval = s.value as Field; - return this.visibilityRules.find(x => (x.targetField === sval.id) || (x.sourceField === sval.id)) ? [...all, sval] : all; + return this.visibilityRules.find(x => (x.targetField === sval.id) || (x.sourceField === sval.id)) ? [...all, sval] : all; },[]) as Field[]; - + const innerCompositeFieldOriginalIds = (entry.form.get('fields') as FormArray).controls.map( x=> x.get('id').value) as string[]; //multiplicity items const multiplicityItemsValue = entry.form.get('multiplicityItems').value as CompositeField[]; - + // ********* FIELDS OF FIELDSET ARE EITHER TARGETS OR SOURCES ***** @@ -210,7 +210,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit const newRule = {...x, targetField: field.id, sourceField: idMappings.find(l => l.original === x.sourceField).multiplicityIdValue} as Rule; rules_to_append.push(newRule); }) - + //outer dependencies const outerDep = original_as_target.filter( x=> !innerCompositeFieldOriginalIds.includes(x.sourceField)); outerDep.forEach(x=>{ @@ -222,10 +222,10 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit }) }); } - - - - + + + + // ** FIELDSET ITSELF IS TARGET // ** source it can never be @@ -239,7 +239,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit if(compositeFieldAsTargetRules.length){ - + compositeFieldAsTargetRules.forEach(x =>{ idCompositeFieldMappings.forEach(l=>{ const newRule = {...x, targetField: l.newValue}; @@ -264,7 +264,7 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit const tempResult:ToCEntry[] = []; - + if(sections &§ions.length){ sections.controls.forEach(section=>{ tempResult.push(this._buildRecursively(section as FormGroup, ToCEntryType.Section)); @@ -300,9 +300,9 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit } private _sortByOrdinal(tocentries: ToCEntry[]){ - + if(!tocentries || !tocentries.length) return; - + tocentries.sort(this._customCompare); tocentries.forEach(entry=>{ this._sortByOrdinal(entry.subEntries); @@ -327,7 +327,6 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit }); } - getTocEntries(): ToCEntry[] { if (!this.form) { return []; } const result: ToCEntry[] = []; diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts b/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts index 40f9bca47..73e0bb5d8 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/visibility-rules/visibility-rules.service.ts @@ -346,7 +346,6 @@ export class VisibilityRulesService { public addNewRule(rule: Rule, currentVisibility = this.DEFAULTVISIBILITY): void { const targetId = rule.targetField; const sourceId = rule.sourceField; - console.log(rule); this.visibilityRuleContext.addToVisibilityRulesContext(rule); diff --git a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts index 98a59d698..d7d89b2ae 100644 --- a/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts +++ b/dmp-frontend/src/app/ui/quick-wizard/quick-wizard-editor/quick-wizard-editor.component.ts @@ -104,7 +104,8 @@ export class QuickWizardEditorComponent extends CheckDeactivateBaseComponent imp dmpDescription: this.formGroup.get('dmp').get('description').value, datasets: (this.formGroup.get('datasets').get('datasetsList') as FormArray).controls.map(x => { return { label: x.get('datasetLabel').value, status: DatasetStatus.Finalized }; - }) + }), + accessRights: false } const dialogRef = this.dialog.open(DmpFinalizeDialogComponent, { diff --git a/dmp-frontend/src/app/utilities/enhancers/utils.ts b/dmp-frontend/src/app/utilities/enhancers/utils.ts index 6749dc1be..6b439858f 100644 --- a/dmp-frontend/src/app/utilities/enhancers/utils.ts +++ b/dmp-frontend/src/app/utilities/enhancers/utils.ts @@ -1,3 +1,5 @@ +import {AbstractControl, FormArray, FormControl, FormGroup} from "@angular/forms"; + export function isNullOrUndefined(object: any): boolean { return object === null || object === undefined; } @@ -5,3 +7,40 @@ export function isNullOrUndefined(object: any): boolean { export function isNumeric(val: any): val is number | string { return !Array.isArray(val) && (val - parseFloat(val) + 1) >= 0; } + +/** + * Deep clones the given AbstractControl, preserving values, validators, async validators, and disabled status. + * @param control AbstractControl + * @returns AbstractControl + */ +export function cloneAbstractControl(control: T): T { + let newControl: T; + + if (control instanceof FormGroup) { + const formGroup = new FormGroup({}, control.validator, control.asyncValidator); + const controls = control.controls; + + Object.keys(controls).forEach(key => { + formGroup.addControl(key, cloneAbstractControl(controls[key])); + }) + + newControl = formGroup as any; + } + else if (control instanceof FormArray) { + const formArray = new FormArray([], control.validator, control.asyncValidator); + + control.controls.forEach(formControl => formArray.push(cloneAbstractControl(formControl))) + + newControl = formArray as any; + } + else if (control instanceof FormControl) { + newControl = new FormControl(control.value, control.validator, control.asyncValidator) as any; + } + else { + throw new Error('Error: unexpected control value'); + } + + if (control.disabled) newControl.disable({emitEvent: false}); + + return newControl; +} diff --git a/dmp-frontend/src/assets/config/config.json b/dmp-frontend/src/assets/config/config.json index 7b0bbad3d..72c5d8a10 100644 --- a/dmp-frontend/src/assets/config/config.json +++ b/dmp-frontend/src/assets/config/config.json @@ -57,7 +57,6 @@ "lockInterval": 60000, "guideAssets": "assets/images/guide", "allowOrganizationCreator": true, - "doiLink": "https://sandbox.zenodo.org/record/", "useSplash": false, "orcidPath": "https://orcid.org/", "maxFileSizeInMB": 10 diff --git a/dmp-frontend/src/assets/i18n/de.json b/dmp-frontend/src/assets/i18n/de.json index 9e0e2ed4e..e47ca8c80 100644 --- a/dmp-frontend/src/assets/i18n/de.json +++ b/dmp-frontend/src/assets/i18n/de.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Multiplicity Min", "MULTIPLICITY-MAX": "Multiplicity Max", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Order", "COMMENT-PLACEHOLDER": "Please Specify", "COMMENT-HINT": "Provide additional information or justification about your selection", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Login with Zenodo", "USE-DEFAULT": "Use Default Token" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "DMP ist durch einen anderen Benutzer gesperrt", "PERMISSION": "Sie sind nicht berechtigt, diesen DMP zu bearbeiten", "INSERT-MANUALLY": "Insert it manually", - "CREATE-DATASET": "Create new one" + "CREATE-DATASET": "Create new one", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Fill with description", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Fill with description", diff --git a/dmp-frontend/src/assets/i18n/en.json b/dmp-frontend/src/assets/i18n/en.json index 6f563ad38..e4d542f3f 100644 --- a/dmp-frontend/src/assets/i18n/en.json +++ b/dmp-frontend/src/assets/i18n/en.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Multiplicity Min", "MULTIPLICITY-MAX": "Multiplicity Max", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Order", "COMMENT-PLACEHOLDER": "Please Specify", "COMMENT-HINT": "Provide additional information or justification about your selection", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Login with Zenodo", "USE-DEFAULT": "Use Default Token" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1007,7 +1017,7 @@ "CLONE-DMP": "Clone", "NEW-VERSION": "New Version", "CREATE-DATASET": "Creating Dataset", - "SUBTITLE": "DOI", + "SUBTITLE": "DOI provided by", "PREVIEW-DATASET": "Previewing Dataset" }, "FIELDS": { @@ -1059,7 +1069,8 @@ "LOCK": "DMP is locked by another user", "PERMISSION": "You have no permission to edit this DMP", "INSERT-MANUALLY": "Insert it manually", - "CREATE-DATASET": "Create new one" + "CREATE-DATASET": "Create new one", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Fill with description", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Fill with description", @@ -1784,7 +1796,8 @@ "AT-LEAST-ONE-DATASET-FINALISED": "You need to have at least one Dataset Finalized" }, "IMPACT": "This action will finalize your DMP, and you won't be able to edit it again.", - "AFTER-FINALIZATION": "After finalizing your DMP you can Publish it, and it'll be publicly available to the ARGOS tool.", + "AFTER-FINALIZATION-PUBLISH": "After finalizing your DMP, it'll be published and be publicly available to the ARGOS tool.", + "AFTER-FINALIZATION-RESTRICT-ACCESS": "Your DMP can be published and be publicly available to the ARGOS tool after finalization when its access rights are opened. Current access rights: restricted", "INVALID": "Invalid" }, "DRAFTS": { diff --git a/dmp-frontend/src/assets/i18n/es.json b/dmp-frontend/src/assets/i18n/es.json index 1c1d11e2d..4be20f2db 100644 --- a/dmp-frontend/src/assets/i18n/es.json +++ b/dmp-frontend/src/assets/i18n/es.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Multiplicidad mínima", "MULTIPLICITY-MAX": "Multiplicidad máxima", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Orden", "COMMENT-PLACEHOLDER": "Por favir especifique", "COMMENT-HINT": "Proporcione información adicional o justifique su selección", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Identificarse con Zenodo", "USE-DEFAULT": "Usar el token por defecto" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "El PGD ha sido bloqueado por otro usuario", "PERMISSION": "No tiene permisos para editar este PGD", "INSERT-MANUALLY": "Insértelo de forma manual", - "CREATE-DATASET": "Crear uno nuevo" + "CREATE-DATASET": "Crear uno nuevo", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Rellenar con la descripción", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "Todos los cambios no grabados volverán a su estado inicial y será redireccionado al editor de PGD. ¿Desea continuar?", "DISCARD-EDITED-CONFIRM": "Sí, descartar los cambios y volver.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Rellenar con la descripción", diff --git a/dmp-frontend/src/assets/i18n/gr.json b/dmp-frontend/src/assets/i18n/gr.json index 9cf4eca81..e34963205 100644 --- a/dmp-frontend/src/assets/i18n/gr.json +++ b/dmp-frontend/src/assets/i18n/gr.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Ελάχιστη τιμή Min", "MULTIPLICITY-MAX": "Μέγιστη τιμή Max", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Εντολή", "COMMENT-PLACEHOLDER": "Παρακαλώ προσδιορίστε", "COMMENT-HINT": "Προσθέστε επιπλέον πληροφορίες ή αιτιολόγηση σχετικά με την επιλογή σας", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Σύνδεση με Zenodo", "USE-DEFAULT": "Χρήση Προκαθορισμένου Token" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "Κλειδωμένο Σχέδιο Διαχείρισης Δεδομένων", "PERMISSION": "Δεν έχετε άδεια να επεξεργαστείτε αυτό το Σχέδιο Διαχείρισης Δεδομένων", "INSERT-MANUALLY": "Εισάγετε το χειροκίνητα", - "CREATE-DATASET": "Δημιούργια νέου" + "CREATE-DATASET": "Δημιούργια νέου", + "DISABLED-EXPORT": "Παρακαλώ αποθηκεύστε τις αλλαγές σας για να εξάγετε αυτό το Σχέδιο Διαχείρισης Δεδομένων" }, "PLACEHOLDER": { "DESCRIPTION": "Συμπληρώστε με περιγραφή", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Παρακαλώ αποθηκεύστε τις αλλαγές σας για να εξάγετε αυτό το Σύνολο Δεδομένων" }, "PLACEHOLDER": { "DESCRIPTION": "Συμπληρώστε με περιγραφή", diff --git a/dmp-frontend/src/assets/i18n/hr.json b/dmp-frontend/src/assets/i18n/hr.json index 69b1ab7d2..1a7e8157c 100644 --- a/dmp-frontend/src/assets/i18n/hr.json +++ b/dmp-frontend/src/assets/i18n/hr.json @@ -2,11 +2,11 @@ "GENERAL": { "VALIDATION": { "REQUIRED": "Obavezno", - "GRANT-START-AFTER-END": "Datum početka ne može biti kasniji od datuma završetka granta.", + "GRANT-START-AFTER-END": "Datum početka ne može biti kasniji od datuma završetka potpore.", "PATTERN-_": "Znak \"_\" nije dozvoljen", "URL": { "LABEL": "URL", - "MESSAGE": "Molimo unesite valjani URL" + "MESSAGE": "Molimo unesite ispravni URL" } }, "DELETE-CONFIRMATION": { @@ -25,11 +25,11 @@ "UNSUCCESSFUL-LOGOUT": "Neuspješna odjava", "UNSUCCESSFUL-LOGIN": "Neuspješna prijava", "SUCCESSFUL-DATASET-PROFILE-DELETE": "Uspješno brisanje", - "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Nije moguće obrisati obrazac zato što je povezan sa skupom podataka", + "UNSUCCESSFUL-DATASET-PROFILE-DELETE": "Nije moguće obrisati predložak zato što je povezan sa skupom podataka", "SUCCESSFUL-DELETE": "Uspješno brisanje", "UNSUCCESSFUL-DELETE": "Neuspješno brisanje", "UNSUCCESSFUL-EMAIL-SEND": "Neuspješno slanje e-maila", - "UNSUCCESSFUL-REMOVE-TEMPLATE": "Neuspješno uklanjanje obrasca. Jedan ili više skupova podataka u okviru Plana koristi ovaj obrazac" + "UNSUCCESSFUL-REMOVE-TEMPLATE": "Neuspješno uklanjanje predloška. Jedan ili više skupova podataka u okviru Plana koristi ovaj predložak" }, "ERRORS": { "HTTP-REQUEST-ERROR": "Došlo je do neočekivane greške" @@ -83,13 +83,13 @@ } }, "START-NEW-DMP-DIALOG": { - "IMPORT": "Dodaj", - "FUNCTION-SUPPORTS": "funkcija podržava", + "IMPORT": "Funkcija dodavanja", + "FUNCTION-SUPPORTS": "podržava isključivo", "JSON-FILES": ".json datoteke", - "PRODUCED": "izrađen", - "RDA-SPECIFICATIONS": "prema RDA specifikacijama", - "MACHINE-ACTIONABLE": "Za strojno čitljive Planove", - "UPLOAD-FILE": "Pohrani datoteku", + "PRODUCED": "izrađene prema", + "RDA-SPECIFICATIONS": "RDA specifikacijama", + "MACHINE-ACTIONABLE": "za strojno čitljive Planove", + "UPLOAD-FILE": "Prenesi datoteku", "REPLACE-FILE": "Zamijeni datoteku" }, "INVITATION-DIALOG": { @@ -111,7 +111,7 @@ "LOAD-MORE": "Učitaj još", "SHOW-LESS": "Prikaži manje", "LOG-IN": "Prijava", - "TAKE-A-TOUR": "Ako vam je potrebna pomoć pogledajte upute" + "TAKE-A-TOUR": "Pokreni virtualni obilazak Argosa" }, "PREPOSITIONS": { "OF": "od" @@ -119,7 +119,7 @@ "TITLES": { "PREFIX": "Otvorite Plan upravljanja podacima -", "GENERAL": "Uređivač Plana upravljanja podacima", - "ABOUT": "Više o", + "ABOUT": "O Argosu", "PRIVACY": "Politika privatnosti", "OPENSOURCE-LICENCES": "Licencije otvorenog koda", "TERMS": "Uvjeti korištenja", @@ -130,34 +130,34 @@ "PLANS-NEW": "Novi Plan (Napredno)", "DMP-NEW": "Novi Plan", "DATASETS": "Moji skupovi podataka", - "EXPLORE": "Objavljeni skupovi podataka", - "DATASETCREATEWIZARD": "Dodajte skup podataka (Čarobnjak)", + "EXPLORE": "Objavljeni opisi skupova podataka", + "DATASETCREATEWIZARD": "Dodajte opis skupa podataka (Čarobnjak)", "GRANTS": "Moje potpore", - "DMP-PROFILES": "Obrasci za Planove", - "DATASET-PROFILES": "Obrasci za skupove podataka", + "DMP-PROFILES": "Predlošci planova", + "DATASET-PROFILES": "Predlošci skupova podataka", "USERS": "Korisnici", "PROFILE": "Moj profil", "LOGIN": "Prijava", "DMP-OVERVIEW": "Pregled Plana", "DMP-EDIT": "Uređivanje Plana", - "DATASET-OVERVIEW": "Pregled skupova podataka", - "DATASET-EDIT": "Prikaz/uređivanje skupa podataka", + "DATASET-OVERVIEW": "Pregled opisa skupova podataka", + "DATASET-EDIT": "Prikaz/uređivanje opisa skupa podataka", "DMP-NEW-VERSION": "Nova verzija Plana", "DMP-CLONE": "Napravite kopiju Plana", - "DATASET-NEW": "Novi skup podataka", + "DATASET-NEW": "Novi opis skupa podataka", "GRANT-NEW": "Nova potpora", "GRANT-EDIT": "Prikažite/uredite potporu", - "DMP-PROFILE-NEW": "Novi obrazac Plana", - "DMP-PROFILE-EDIT": "Uredite obrazac Plana", - "DATASET-PROFILES-NEW": "Novi obrazac za skup podataka", - "DATASET-PROFILES-EDIT": "Uredite obrazac skupa podataka", + "DMP-PROFILE-NEW": "Novi predložak Plana", + "DMP-PROFILE-EDIT": "Uredite predložak Plana", + "DATASET-PROFILES-NEW": "Novi predložak za opis skupa podataka", + "DATASET-PROFILES-EDIT": "Uredite predložak opisa skupa podataka", "EXPLORE-PLANS-OVERVIEW": "Pregled objavljenih Planova", "DATASET-PUBLIC-EDIT": "Prikaz objavljenih skupova podataka", "DMP-PUBLIC-EDIT": "Prikaz objavljenih Planova", - "DATASET-COPY": "Kopiraj skup podataka", - "DATASET-UPDATE": "Dopuni skup podataka", - "DATASET-PROFILES-NEW-VERSION": "Nova verzija obrasca za skup podataka", - "DATASET-PROFILES-CLONE": "Nova kopija obrasca za skup podataka", + "DATASET-COPY": "Kopiraj opis skupa podataka", + "DATASET-UPDATE": "Dopuni opis skupa podataka", + "DATASET-PROFILES-NEW-VERSION": "Nova verzija predloška za opis skupa podataka", + "DATASET-PROFILES-CLONE": "Nova kopija predloška za opis skupa podataka", "LANGUAGE-EDITOR": "Uređivanje jezika", "GUIDE-EDITOR": "Uređivanje uputa za korisnike", "LANGUAGE": "Jezik", @@ -167,7 +167,7 @@ "PDF": "PDF", "XML": "XML", "JSON": "RDA JSON", - "DOC": "Dokument" + "DOC": "DOCX" }, "LANGUAGES": { "ENGLISH": "Engleski", @@ -179,7 +179,7 @@ "SERBIAN": "Srpski", "PORTUGUESE": "Portugalski", "CROATIAN": "Hrvatski", - "POLISH": "Polish" + "POLISH": "Poljski" } }, "COOKIE": { @@ -214,27 +214,27 @@ "DMP": "Plan", "DMPS": "Planovi", "MY-DMPS": "Moji Planovi", - "DATASETS": "Skupovi podataka", - "DATASET": "Skup podataka", + "DATASETS": "Opisi skupova podataka", + "DATASET": "Opis skupa podataka", "PUBLIC-DATASETS": "Istražite ARGOS", "USERS": "Korisnici", - "DATASETS-ADMIN": "Obrasci za skupove podataka", - "DMP-PROFILES": "Obrasci za Planove", + "DATASETS-ADMIN": "Predlošci za opise skupova podataka", + "DMP-PROFILES": "Predlošci za Planove", "ABOUT": "O Argosu", - "MY-DATASET-DESCRIPTIONS": "MOJI SKUPOVI PODATAKA", + "MY-DATASET-DESCRIPTIONS": "MOJI OPISI SKUPOVA PODATAKA", "DATASET-DESCRIPTION-WIZARD": "Čarobnjak za skupove podataka", - "PUBLIC DATASETS": "OBJAVLJENI SKUPOVI PODATAKA", + "PUBLIC DATASETS": "OBJAVLJENI OPISI SKUPOVA PODATAKA", "PUBLIC-DMPS": "OBJAVLJENI PLANOVI", "HOME": "POČETAK", "DMP-WIZARD": "Čarobnjak za kreiranje Planova", - "DATASET-TEMPLATES": "OBRASCI ZA SKUPOVE PODATAKA", - "TEMPLATE": "OBRAZAC", - "DMP-TEMPLATES": "OBRASCI ZA PLANOVE", + "DATASET-TEMPLATES": "PREDLOŠCI ZA OPIS SKUPA PODATAKA", + "TEMPLATE": "PREDLOŽAK", + "DMP-TEMPLATES": "PREDLOŠCI ZA PLANOVE", "USERS-BREADCRUMB": "KORISNICI", "START-NEW-DMP": "Kreirajte novi Plan", - "START-NEW-DMP-TXT": "Krenite ispočetka ili nastavite raditi u Argosu! Kreirajte novi plan ili uvezite postojeći", + "START-NEW-DMP-TXT": "Krenite od početka ili nastavite raditi u Argosu! Kreirajte novi plan ili uvezite postojeći", "START-WIZARD": "Pokrenite Čarobnjaka", - "IMPORT-FROM-FILE": "Uvoz iz vanjskog izvora", + "IMPORT-FROM-FILE": "Uvoz", "SEARCH": { "DATASET": "Skup podataka", "DMP": "Plan upravljanja podacima", @@ -248,11 +248,11 @@ "DASHBOARD": "Početak", "DMP": "PLANOVI UPRAVLJANJA PODACIMA", "MY-DMPS": "Moji Planovi", - "DATASETS": "SKUPOVI PODATAKA", + "DATASETS": "OPISI SKUPOVA PODATAKA", "GRANTS": "POTPORE", "NEW DATASET": "Novi skup podataka", "QUICK-WIZARD": "Novi Plan (Čarobnjak)", - "QUICK-WIZARD-DATASET": "Dodajte skup podataka (Čarobnjak)", + "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", @@ -262,15 +262,15 @@ "HISTORY-EDITED": "ZADNJI PUT UNESENO", "PUBLIC": "OBJAVLJENO", "PUBLIC-DMPS": "Javno dostupni Planovi", - "PUBLIC-DESC": "Javno dostupni skupovi podataka", + "PUBLIC-DESC": "Javno dostupni opisi skupova podataka", "ACCOUNT": "Korisnički račun", "ADMIN": "ADMINISTRATOR", - "DATASET-TEMPLATES": "Obrasci za skupove podataka", - "DMP-TEMPLATES": "Obrasci za Planove", + "DATASET-TEMPLATES": "Predlošci za opisivanje skupa podataka", + "DMP-TEMPLATES": "Predlošci za Planove", "USERS": "Korisnici", "LANGUAGE-EDITOR": "Uređivanje jezika", "GUIDE-EDITOR": "Uređivanje uputa za korisnike", - "CO-BRANDING": "Co-Branding", + "CO-BRANDING": "Razvoj i suradnja", "SUPPORT": "Podrška", "FEEDBACK": "Molimo pošaljite nam svoje sugestije i komentare" }, @@ -303,7 +303,7 @@ "DATASET-TEMPLATE-DESCRIPTION-PLACEHOLDER": "Opis predloška skupa podataka", "UNTITLED": "Neimenovano", "QUESTION": "Upit", - "TEMPLATE-OUTLINE": "Nacrt predloška", + "TEMPLATE-OUTLINE": "Skica predloška", "ERRORS": { "USER-NOT-FOUND": "Korisnik nije pronađen." } @@ -341,7 +341,7 @@ "DESCRIPTION": "Opis" }, "FORM": { - "TITLE": "Opis obrasca", + "TITLE": "Opis predloška", "SECTION": { "TITLE": "Informacije o odjeljku", "FIELDS": { @@ -374,12 +374,14 @@ "MULTIPLICITY-MIN": "Višestrukost, minimalno polja", "MULTIPLICITY-MAX": "Višestrukost, maksimalno polja", "MULTIPLICITY-PLACEHOLDER": "", + "MULTIPLICITY-TABLEVIEW": "Pogledajte unose u tablici", "MULTIPLICITY-ADD-ONE-FIELD": "Dodaj polje", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Dodaj redak", "ORDER": "Redoslijed", "COMMENT-PLACEHOLDER": "Navedite", "COMMENT-HINT": "Navedite dodatne informacije ili obrazložite izbor", "RDA-COMMON-STANDARDS": "RDA zajednički standardi", - "EXPORT": "Include in Export" + "EXPORT": "Uključi u izvoz" }, "ACTIONS": { "ADD-CHILD-FIELD": "Dodajte potpolje +" @@ -415,7 +417,7 @@ "FIELD-FREE-TEXT-TITLE": "Podaci za slobodan tekst", "FIELD-FREE-TEXT-PLACEHOLDER": "Polje za unos", "FIELD-COMBO-BOX-TYPE": "Vrsta", - "FIELD-WORD-LIST-TITLE": "Podaci o listi", + "FIELD-WORD-LIST-TITLE": "Uređivanje popisa", "FIELD-WORD-LIST-PLACEHOLDER": "Polje za unos", "FIELD-WORD-LIST-LABEL": "Oznaka", "FIELD-WORD-LIST-VALUE": "Vrijednost", @@ -446,7 +448,7 @@ "FIELD-DATE-PICKER-VALUE": "Vrijednost", "FIELD-MULTIPLE-AUTOCOMPLETE": "Višestruki automatski unos", "FIELD-MULTIPLE-WORDLIST": "Višestruki odabir", - "FIELD-CURRENCY-TITLE": "Currency Data", + "FIELD-CURRENCY-TITLE": "Podaci o valuti", "FIELD-CURRENCY-PLACEHOLDER": "Primjer unosa", "FIELD-REGISTRIES-TITLE": "Metapodaci", "FIELD-REGISTRIES-PLACEHOLDER": "Primjer unosa", @@ -466,13 +468,13 @@ "FIELD-TAXONOMIES-PLACEHOLDER": "Primjer unosa", "FIELD-LICENSES-TITLE": "Licencirani podaci", "FIELD-LICENSES-PLACEHOLDER": "Primjer unosa", - "FIELD-PUBLICATIONS-TITLE": "Podaci o objaljivanju", + "FIELD-PUBLICATIONS-TITLE": "Podaci o objavljivanju", "FIELD-PUBLICATIONS-PLACEHOLDER": "Primjer unosa", "FIELD-TAGS-TITLE": "Podaci s oznakama", "FIELD-TAGS-PLACEHOLDER": "Primjer unosa", "FIELD-DATASET-IDENTIFIER-TITLE": "Identifikator skupa podataka", "FIELD-DATASET-IDENTIFIER-PLACEHOLDER": "Primjer unosa", - "FIELD-VALIDATOR-TITLE": "Validator Data", + "FIELD-VALIDATOR-TITLE": "Validator Podaci", "FIELD-VALIDATOR-PLACEHOLDER": "Primjer unosa", "EXTERNAL-DATASET-TYPE-NAME": "Vrsta", "EXTERNAL-DATASET-TYPES": { @@ -531,8 +533,8 @@ }, "TABLE-OF-CONTENTS": { "ERROR-MESSAGES": { - "FIELDSET-MUST-HAVE-PARENT-SECTION": "Question can only be child of section.", - "INPUT-SECTION-SAME-LEVEL": "Ne mogu postojati pitanje i odjeljak na istom nivou.’’ Cannot have question and section on the same level.", + "FIELDSET-MUST-HAVE-PARENT-SECTION": "Mora postojati nadređena sekcija.", + "INPUT-SECTION-SAME-LEVEL": "Ne mogu postojati pitanje i odjeljak na istom nivou.", "DRAG-NOT-SUPPORTED": "Radnja povuci - ispusti (engl. drag ‘n’ drop) odlomka nije podržana za ovo odredište.", "PAGE-ELEMENT-ONLY-TOP-LEVEL": "Elementi poglavlja mogu biti samo na najvišoj razini" } @@ -610,15 +612,15 @@ "PUBLISHED": "Objavljeno", "VERSION": "Verzija", "CONTAINED-DATASETS": "Sadrži skupove podataka", - "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": "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", - "GET-IDEA": "da biste dobili inspiraciju!", + "GET-IDEA": "kako biste dobili inspiraciju!", "SORT-BY": "Poredaj po", "COLUMNS": { "NAME": "Ime", "GRANT": "Potpora", - "PROFILE": "Obrazac", + "PROFILE": "Predložak", "CREATION-TIME": "Vrijeme kreiranja", "ORGANISATIONS": "Institucije", "LATEST_VERSION": "Zadnja verzija", @@ -681,7 +683,7 @@ "TOOLTIP": { "PUBLISHED": "Javno dostupno - zatvoren Plan", "INVOLVED-DATASETS": "Uključeni skupovi podataka", - "TEMPLATES-INVOLVED": "Uključeni obrasci za skupove podataka" + "TEMPLATES-INVOLVED": "Uključeni predlošci skupova podataka" }, "EMPTY-LIST": "Ništa još nije dostupno." }, @@ -709,7 +711,7 @@ "FIRST-STEP": { "TITLE": "Informacije o skupu podataka", "DMP": "Plan upravljanja podacima", - "PROFILE": "Obrazac za skup podataka", + "PROFILE": "Predložak za opis skupa podataka", "SUB-TITLE": "Kreiran:" }, "SECOND-STEP": { @@ -740,7 +742,7 @@ "DOWNLOAD-XML": "Preuzmi XML", "DOWNLOAD-DOCX": "Preuzmi DOCX", "COPY-DATASET": "Kopiraj skup podataka", - "UPDATE-DATASET-PROFILE": "Dopuni obrazac", + "UPDATE-DATASET-PROFILE": "Dopuni predložak", "VALIDATE": "Potvrdi", "UNDO-FINALIZATION-QUESTION": "Poništi zadnji korak?", "CONFIRM": "Potvrdi", @@ -749,7 +751,7 @@ "MESSAGES": { "DATASET-NOT-FOUND": "Skup podataka ne postoji", "DATASET-NOT-ALLOWED": "Nemate pristup ovom skupu podataka", - "SUCCESS-UPDATE-DATASET-PROFILE": "Obrazac skupa podataka uspješno je dopunjen", + "SUCCESS-UPDATE-DATASET-PROFILE": "Predložak opisa skupa podataka uspješno je dopunjen", "MISSING-FIELDS": "Neka obavezna polja ostala su prazna. Molimo da provjerite Plan i jeste li odgovorili na sva obavezna pitanja te dodali valjane URL-ove. (Polja koja nedostaju označena su crvenom bojom.)", "NO-FILES-SELECTED": "Nije izabrana niti jedna datoteka", "LARGE-FILE-OR-UNACCEPTED-TYPE": "Datoteka je prevelika ili format nije podržan.", @@ -780,9 +782,9 @@ }, "DMP-OVERVIEW": { "GRANT": "Potpora", - "DMP-AUTHORS": "Autori Plana", + "DMP-AUTHORS": "Autor/i Plana", "RESEARCHERS": "Istraživači", - "DATASETS-USED": "Skupovi podataka koji se koriste", + "DATASETS-USED": "Pridruženi skupovi podataka", "COLLABORATORS": "Suradnici", "PUBLIC": "Javno", "PRIVATE": "Zatvoreno za javnost", @@ -803,16 +805,24 @@ "ZENODO-LOGIN": "Prijavite se pomoću Zenodo korisničkog računa", "USE-DEFAULT": "Koristite zadanu opciju" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Koji račun želite koristiti?", + "LOGIN": "Prijavite se s { {repozitorija} }", + "NO-REPOSITORIES": "Nema repozitorija za objavljivanje", + "SELECT-REPOSITORIES": "Odaberite repozitorijima za polog", + "AUTHORIZE": "Nastavite s autorizacijom", + "CANCEL": "Otkazati" + }, "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." } }, "DATASET-OVERVIEW": { - "DATASET-AUTHORS": "Autori skupa podataka", + "DATASET-AUTHORS": "Autor/i skupa podataka", "ERROR": { - "DELETED-DATASET": "Traženi skup podataka je obrisan", - "FORBIDEN-DATASET": "Nemate dozvolu za pristup ovom ovom skupu podataka" + "DELETED-DATASET": "Traženi opis skupa podataka je obrisan", + "FORBIDEN-DATASET": "Nemate dozvolu za pristup ovom opisu skupa podataka" }, "LOCKED": { "TITLE": "Skup podataka je zaključan", @@ -827,12 +837,12 @@ "DATASET-LISTING": { "TITLE": "Skupovi podataka", "DATASET-DESCRIPTION": "Skup podataka", - "SELECT-DATASETS-TO-CLONE": "Izaberite skupove podataka koje želite da uključiti u Plan. Odabrane skupove podataka moći ćete uređivati.", - "SELECT-DATASETS-NONE": "Ovi skupovi podataka nisu dostupni za odabrani plan upravljanja podacima.", + "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.", "TEXT-INFO": "Skupovi podataka se opisuju prema unaprijed određenim predlošcima. U Argosu, Plan može sadržavati onoliko opisa koliko ima skupova podataka. Pretražite", "TEXT-INFO-REST": "za pregled skupova podataka opisanih u Planovima u Argosu", - "LINK-PUBLIC-DATASETS": "javno dostupne skupove podataka", - "TEXT-INFO-PAR": "Novi skupovi podataka mogu se dodati u postojeće Planove upravljanja podacima u bilo kojem trenutku, a za njihovo opisivanje može se koristiti više od jednog predloška. Generirati možete kopije skupova podataka, koje možete koristiti i u drugim planovima. Skupovi podataka mogu se obrisati bez negativnih posljedica po Plan u cjelini.", + "LINK-PUBLIC-DATASETS": "Pretražite javno dostupne skupove podataka", + "TEXT-INFO-PAR": "Novi Opisi skupova podataka mogu se dodati u postojeće Planove upravljanja podacima u bilo kojem trenutku, a za njihovo opisivanje može se koristiti više od jednog predloška. Generirati možete kopije skupova podataka, koje možete koristiti i u drugim planovima. Skupovi podataka mogu se obrisati bez negativnih posljedica po Plan u cjelini.", "COLUMNS": { "NAME": "Ime", "REFERENCE": "Referenca", @@ -843,18 +853,18 @@ "CREATED": "Kreirano", "PUBLISHED": "Objavljeno", "FINALIZED": "Završeno", - "LAST-EDITED": "Zadnji izmjena", + "LAST-EDITED": "Zadnja izmjena", "ACTIONS": "Radnje", "DMP": "Plan upravljanja podacima", - "PROFILE": "Obrazac", + "PROFILE": "Predložak", "DATAREPOSITORIES": "Podatkovni repozitoriji", - "REGISTRIES": "Popisi", + "REGISTRIES": "Registri", "SERVICES": "Usluge" }, "ACTIONS": { "EDIT": "Uredi", "MAKE-IT-PUBLIC": "Objavi", - "VIEW": "Pregledaj", + "VIEW": "Pregled", "NEW": "Novi skup podataka", "CREATE-NEW": "Kreiraj novi skup podataka", "EXPORT": "Preuzmi", @@ -869,31 +879,31 @@ }, "TOOLTIP": { "DATASET-STATUS": { - "DRAFT": "Zatvoreno za javnost - Skup podataka koji se uređuje", - "FINALIZED": "Zatvoreno za javnost - Zatvoren skup podataka" + "DRAFT": "Zatvoreno za javnost - Opis skupa podataka koji se uređuje", + "FINALIZED": "Zatvoreno za javnost - Zatvoren opis skupa podataka" }, "DMP": "Plan upravljanja podacima", "GRANT": "Potpora", - "TEMPLATES-INVOLVED": "Predložak skupa podataka", + "TEMPLATES-INVOLVED": "Predložak opisa skupa podataka", "VERSION": "Verzija Plana", - "PART-OF": "Dio", + "PART-OF": "Ovaj skup podataka dio je:", "TO-DMP": "U Planu", "DMP-FOR": "Plan za" }, "EMPTY-LIST": "Ništa još nije dostupno." }, "DATASET-PUBLIC-LISTING": { - "TITLE": "Objavljeni skupovi podataka", + "TITLE": "Objavljeni opisi skupova podataka", "TOOLTIP": { - "FINALIZED": "Zatvoreno za javnost - zatvoreni skup podataka", + "FINALIZED": "Zatvoreno za javnost - zatvoreni opis skupa podataka", "DMP": "Plan upravljanja podacima", "GRANT": "Potpora", - "TEMPLATES-INVOLVED": "Predložak skupa podataka" + "TEMPLATES-INVOLVED": "Predložak opisa skupa podataka" }, "EMPTY-LIST": "Još uvijek ništa nije dostupno." }, "DATASET-PROFILE-LISTING": { - "TITLE": "Predlošci za skup podataka", + "TITLE": "Predlošci za opis skupa podataka", "COLUMNS": { "NAME": "Ime", "REFERNCE": "Referenca", @@ -911,7 +921,7 @@ "DMP": "Plan upravljanja podacima", "PROFILE": "Predložak", "DATAREPOSITORIES": "Podatkovni repozitoriji", - "REGISTRIES": "Popisi", + "REGISTRIES": "Registri", "SERVICES": "Usluge" }, "ACTIONS": { @@ -927,7 +937,7 @@ }, "DATASET-UPLOAD": { "TITLE": "Uvoz skupa podataka", - "UPLOAD-BUTTON": "Prenesi datoteku", + "UPLOAD-BUTTON": "Odaberi datoteku", "ACTIONS": { "IMPORT": "Uvezi", "CANCEL": "Poništi" @@ -943,7 +953,7 @@ }, "DMP-PROFILE-EDITOR": { "TITLE": { - "NEW": "Novi predlošci za Planove", + "NEW": "Novi predlošci planova", "EDIT": "Uredi" }, "FIELDS": { @@ -1018,29 +1028,29 @@ "ORGANISATIONS": "Ustanove", "ORGANISATIONS-HINT": "Navedite ustanove koje sudjeluju u izradi i uređivanju Planova upravljanja podacima", "RESEARCHERS": "Istraživači", - "RESEARCHERS-HINT": "Upišite imena osoba koje su izradile, obradile i/ili analizirale podatke obuhvaćene Planom upravljanja podacima.", + "RESEARCHERS-HINT": "Upišite imena svih osoba koje su sudjelovale u izradi, obradi i analizi podataka obuhvaćenih Planom upravljanja podacima.", "AUTHORS": "Autori", "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", - "PROFILE": "Predlošci za Planove", + "PROFILE": "Predlošci Planova", "PROJECT": "Projekt", "GRANT": "Potpora", "GRANTS": "Potpore", - "GRANTS-HINT": "Pronađite Vašu potporu ili unesite novu", + "GRANTS-HINT": "Pronađite potporu ili unesite novu", "FUNDER": "Financijer", - "FUNDER-HINT": "Odaberite Vašeg financijera ili unesite novog", + "FUNDER-HINT": "Odaberite financijera ili unesite novog", "FUNDING-ORGANIZATIONS": "Ustanove financijeri", "PROJECT-HINT": "Projekti u Argosu definiraju se kao aktivnosti koje su financirane bespovratnim sredstvima ili kao zajedničke aktivnosti u okviru kolaborativnih shema financiranja (npr. otvoreni poziv za kolaboraciju). Molimo Vas da popunite ako Vaš projekt spada u ovu kategoriju. U suprotnom ostavite prazno i popunit će se automatski.", "STATUS": "Status Plana", "EXTERNAL-SOURCE-HINT": "Lista vrijednosti iz vanjskih izvora", "COLLABORATORS": "Suradnici", "LANGUAGE": "Jezik", - "LANGUAGE-HINT": "Odaberite jezik za Vaš Plan upravljanja podacima", + "LANGUAGE-HINT": "Odaberite jezik Plana upravljanja podacima", "LICENSE": "Licencija", "VISIBILITY": "Vidljivost", - "VISIBILITY-HINT": "Odredite kako će Plan biti prikazan u Argosu. Ako odaberete Javno dostupno, Plan će automatski biti dostupan svim korisnicima u kolekciji \"Javno dostupni planovi\".", + "VISIBILITY-HINT": "Odredite kako će Plan biti prikazan u Argosu. Ako odaberete 'Javno dostupno', Plan će automatski biti dostupan svim korisnicima u kolekciji 'Javno dostupni planovi'.", "PUBLICATION": "Datum objave", "CONTACT": "Kontakt", "COST": "Troškovi", @@ -1059,7 +1069,8 @@ "LOCK": "Plan upravljanja podacima je zaključan od strane drugog korisnika", "PERMISSION": "Nemate ovlasti za uređivanje ovog Plana", "INSERT-MANUALLY": "Ručni unos", - "CREATE-DATASET": "Kreirajte novi" + "CREATE-DATASET": "Kreirajte novi", + "DISABLED-EXPORT": "Spremite promjene za izvoz ovog DMP-a" }, "PLACEHOLDER": { "DESCRIPTION": "Dodajte opis", @@ -1095,7 +1106,7 @@ "MAIN-INFO": { "INTRO": "Plan upravljanja podacima (engl. Data Management Plan) u Argosu 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 i informacije o skupovima istraživačkih podataka koje ukazuju na procedure primijenjene tijekom životnog ciklusa podataka.", "HINT": "Kratki opis Plana s namjenom i ciljevima.", - "TYPING": "Unesite više znakova kako bismo lakše pronašli ispravno ime.", + "TYPING": "Za relevantnije rezultate potrebno je upisati više znakova.", "UNIQUE-IDENTIFIER": "Jedinstveni identifikator", "RESEARCHER-IDENTIFIER-EXISTS": "Identifikator istraživača već postoji.", "ORGANISATION-IDENTIFIER-EXSTS": "Identifikator ustanove već postoji.", @@ -1105,7 +1116,7 @@ "CANCEL": "Poništi" }, "FUNDING-INFO": { - "INTRO": "Nalazite se na sučelju za uređivanje Plana upravljanja podacima. Unesite informacije o opsegu, financiranju i sudionicima Vašeg Plana te odredite prava pristupa i ponovnog korištenja Plana koji izrađujete.", + "INTRO": "Nalazite se na sučelju za uređivanje Plana upravljanja podacima. Ovdje unesite informacije o opsegu, financiranju i osobama koje su sudjelovale u upravljanju podacima te mu odredite licenciju, pravo pristupa i ponovnog korištenja.", "FIND": "Ne pronalazite odgovarajući?", "UNIQUE-IDENTIFIER": "Jedinstveni identifikator", "IDENTIFIER-FUNDER-EXISTS": "Identifikator financijera postoji.", @@ -1114,13 +1125,13 @@ }, "DATASET-INFO": { "INTRO": "Plan upravljanja podacima (eng. Data Management Plan) u Argosu 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 obrascima. U Argosu, Plan može sadržavati onoliko opisa koliko ima skupova podataka.", + "SECOND-INTRO": "Skupovi podataka se opisuju prema unaprijed definiranim predlošcima. U Argosu, 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." }, "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", - "HINT": "Izaberite licenciju s popisa koju smatrate prikladnom za Vaš Plan", + "HINT": "Izaberite licenciju s popisa koju želite primijeniti na Plan", "TYPING": "Kako bismo lakše pronašli ispravnu licenciju unesite više znakova." }, "DATASET-DESCRIPTION": { @@ -1138,7 +1149,7 @@ } }, "DMP-PROFILE-LISTING": { - "TITLE": "Predlošci za Planove", + "TITLE": "Predlošci planova", "CREATE-DMP-TEMPLATE": "Kreiraj predložak za Plan", "COLUMNS": { "NAME": "Ime", @@ -1155,7 +1166,7 @@ "UPLOAD-XML-FILE-CANCEL": "Poništi" }, "STATUS": { - "DRAFT": "Nacrt", + "DRAFT": "Skica", "FINALIZED": "Završeno" }, "MESSAGES": { @@ -1173,7 +1184,7 @@ } }, "CRITERIA": { - "FILTERS": "Filtri", + "FILTERS": "Filteri", "GRANTS": { "LIKE": "Pretraživanje", "PERIOD-FROM": "Početak potpore", @@ -1194,8 +1205,8 @@ "PERIOD-TO": "Kraj", "STATUS": "Status", "NONE": "-", - "TAGS": "Oznaka", - "SELECT-TAGS": "Odaberi oznaku", + "TAGS": "Ključne riječi", + "SELECT-TAGS": "Odaberite ključne riječi", "LIKE": "Pretražite skupove podataka", "DRAFT-LIKE": "Pretražite skice skupova podataka", "SELECT-GRANTS": "Odaberite potpore", @@ -1234,11 +1245,11 @@ "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": "Savjet: Kako biste izbjegli nejasne, pomiješane informacije različitih vrsta podataka, predlažemo da svaku vrstu podataka unesete kao novi skup podataka sa svojim opisom." + "INTRO-TIP": "Kako biste izbjegli nejasne ili pomiješane informacije različitih vrsta podataka, predlažemo da za svaku vrstu podataka unesete novi Opis skupa podataka." }, "FIELDS": { "NAME": "Naziv skupa podataka", - "TITLE": "Naslov skupa podataka", + "TITLE": "Naziv skupa podataka", "DESCRIPTION": "Opis", "PROFILE": "Predložak", "URI": "URL", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "Sve nespremljene promjene bit će odbačene, podaci će se vratiti u izvorno stanje i bit ćete preusmjereni natrag na sučelje za uređivanje Plana. Želite li nastaviti?", "DISCARD-EDITED-CONFIRM": "Da, odbaci promjene.", "DISCARD-EDITED-DENY": "Ne." - } + }, + "DISABLED-EXPORT": "Spremite promjene za izvoz ovog skupa Podataka" }, "PLACEHOLDER": { "DESCRIPTION": "Unesite opis", @@ -1306,13 +1318,13 @@ }, "PREFILL-STEP": { "TITLE": "Započnite s izradom opisa svog skupa podataka", - "PREFILL": "Koristite prethodno uneseno", + "PREFILL": "Dohvati", "OR": "ILI", - "HINT": "Dohvatite odgovore na neka pitanja obrasca odabirom skupa podataka sa Zenoda ili započnite samostalno odgovarati na pitanja.", - "MANUALLY": "Ručno", + "HINT": "Dohvatite odgovore na neka od pitanja odabirom skupa podataka sa Zenoda ili započnite samostalno odgovarati na pitanja.", + "MANUALLY": "Ručni unos", "PROFILE": "Predložak za skup podataka", "PREFILLED-DATASET": "Prethodno uneseni skup podataka", - "SEARCH": "Počnite tipkati da biste tražili skup podataka ili softver", + "SEARCH": "Pretraživanje skupova podataka", "NEXT": "Sljedeće" } }, @@ -1412,9 +1424,9 @@ "TAXONOMIES": "Taksonomije", "LICENSES": "Licencije", "PUBLICATIONS": "Publikacije", - "REGISTRIES": "Registri", + "REGISTRIES": "Registri metapodatkovnih standarda", "SERVICES": "Usluge", - "TAGS": "Oznake", + "TAGS": "Ključne riječi", "RESEARCHERS": "Istraživači", "ORGANIZATIONS": "Ustanove", "DATASET-IDENTIFIER": "Identifikatori skupa podataka", @@ -1510,7 +1522,7 @@ }, "DATASET-PROFILE": { "PREVIEW": "Pregled", - "FORM-DESCRIPTION": "Opis obrasca", + "FORM-DESCRIPTION": "Opis predloška", "PAGES-DESCRIPTION": "Opis stranica" }, "RECENT-ACTIVITY": { @@ -1588,7 +1600,7 @@ }, "CONTACT": { "SUPPORT": { - "TITLE": "Kontaktirajte podršku", + "TITLE": "Podrška", "SUBTITLE": "Kako Vam možemo pomoći?", "SUBJECT": "Tema", "DESCRIPTION": "Opis", @@ -1609,7 +1621,7 @@ "MY-GRANTS": "Moje potpore", "GRANTS": "Potpore", "MY-DMPS": "Moji Planovi", - "TITLE": "Šta je ARGOS?", + "TITLE": "Što je ARGOS?", "DMP-QUESTION": "Što je Plan upravljanja podacima u ARGOSU?", "INFO-TEXT": "ARGOS je otvorena modularna aplikacija koja pojednostavljuje izradu Planova upravljanja podacima (eng. Data Management Plan), kao i njihovu provjeru, praćenje i održavanje. Uz pomoć ARGOSa, svi sudionici u istraživanju (istraživači, administratori, nadzorna tijela i drugi) mogu izraditi primjenjive Planove koji se mogu slobodno razmjenjivati kroz različite infrastrukture radi provođenja određenih dijelova procesa upravljanja podacima u skladu s namjerama i obvezama vlasnika podataka.", "INFO-DMP-TEXT": "Plan upravljanja podacima (eng. Data Management Plan, skraćeno DMP) je živi dokument koji opisuje skupove podataka prikupljene ili korištene tijekom i nakon istraživanja. Planovi sadrže osnovne informacije o mogućnostima za ponovnu upotrebu i naknadnu distribuciju rezultata istraživanja, kao i za njihovo korištenje u novim kontekstima, čime se potvrđuje njihova valjanost i osigurava njihovo ponovno korištenje.", @@ -1619,27 +1631,27 @@ "LEARN-MORE": "kako biste naučili kako izraditi vlastiti Plan!", "ORGANIZATIONS": "Povezane ustanove", "DMPS": "Planovi upravljanja podacima", - "MY-DATASETS": "Moji skupovi podataka", - "DATASETS": "Skupovi podataka", + "MY-DATASETS": "Opisi mojih skupovi podataka", + "DATASETS": "Opisi skupova podataka", "SEARCH": "PRETRAŽITE...", "DATA-MANAGEMENT-PLANS": "PLANOVI UPRAVLJANJA PODACIMA", "PERSONAL-USAGE": "Osobna upotreba", "PUBLIC-USAGE": "Javna upotreba", - "DATASET-DESCRIPTIONS": "Skupovi podataka", - "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Skupovi podataka", + "DATASET-DESCRIPTIONS": "Opisi skupova podataka", + "DATASET-DESCRIPTIONS-DASHBOARD-TEXT": "Opisi skupova podataka", "PUBLIC-DMPS": "Javno dostupni Planovi", - "PUBLIC-DATASETS": "Javno dostupni skupovi podataka", + "PUBLIC-DATASETS": "Javno dostupni opisi skupova podataka", "RELATED-ORGANISATIONS": "Povezane ustanove", "DRAFTS": "Nacrti", "ALL": "Sve", "EMPTY-LIST": "Ništa još nije dostupno.", "LATEST-ACTIVITY": "Posljednja aktivnost", - "DMP-ABOUT-BEG": "Plan upravljanja podacima u ARGOSu sadrži osnovne informacije o istraživanju, kao što su svrha i ciljevi istraživanja, uključeni istraživači te dokumentaciju o skupovima istraživačkih podataka", - "DMP-ABOUT-END": ", informacije koje ukazuju na procedure i sredstva korištena prilikom upravljanja podacima.", + "DMP-ABOUT-BEG": "Plan upravljanja podacima u Argosu sadrži osnovne informacije o istraživanju (kao što su svrha i ciljevi istraživanja), uključenim istraživačima te dokumentaciju o skupovima istraživačkih podataka", + "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 skup podataka", - "ADD-DATASET": "Unesite skup podataka", + "ADD-DATASET-DESCRIPTION": "Unesite opis skupa podataka", + "ADD-DATASET": "Unesite opis skupa podataka", "ADD-DMP-DESCRIPTION": "Opišite Plan" }, "TOUR-GUIDE": { @@ -1648,13 +1660,13 @@ "IMPORT-DMP": "Plan možete uvesti", "START-WIZARD": "ili stvoriti novi u Argosu.", "DATASET": "Ovo je Vaša kontrolna ploča. Ovdje možete pregledavati i uređivati sve skupove podataka kojima ste doprinijeli ili koje ste sami izradili.", - "NEW-DATASET": "Pomoću opcije Unesite skup podataka možete opisivati nove skupove podataka u bilo kojem trenutku tijekom istraživanja.", + "NEW-DATASET": "Pomoću opcije Unesite opis skupa podataka možete opisivati nove skupove podataka u bilo kojem trenutku tijekom istraživanja.", "GOT-IT": "Razumijem!", "LEAVE-TOUR": "Napusti obilazak" }, "ADD-NEW-DATASET": { - "OPTIONS-NOT-ENOUGH": "Ponuđene opcije nisu dovoljne?", - "START-NEW-DMP": "Započnite novi Plan" + "OPTIONS-NOT-ENOUGH": "Ako niste pronašli odgovarajući Plan,", + "START-NEW-DMP": "započnite novi." } }, "USER-DIALOG": { @@ -1697,18 +1709,18 @@ }, "ROLE-ORGANIZATION": { "FACULTY": "Fakultet", - "LIBRARIAN": "Knjižnica", - "RESEARCHER": "Istraživač", - "STUDENT": "Student (bacc., dipl.)", - "EARLY-CAREER-RESEARCHER": "Mladi istraživač (PhD candidate, post-graduate)", - "RESEARCH-ADMINISTRATOR": "Administrator istraživanja", - "REPOSITORY-MANAGER": "Repozitorij", + "LIBRARIAN": "Knjižničar/ka", + "RESEARCHER": "Istraživač/ica", + "STUDENT": "Student/ica (bacc., dipl.)", + "EARLY-CAREER-RESEARCHER": "Mladi istraživač/ica (doktorand/ica, asistent/ica)", + "RESEARCH-ADMINISTRATOR": "Administrator/ica istraživanja", + "REPOSITORY-MANAGER": "Upravitelj/ica repozitorija", "RESEARCH-INFRASTRUCTURE": "Istraživačka infrastruktura", "SERVICE-PROVIDER": "Pružatelj usluga", "PUBLISHER": "Izdavač", "RESEARCH-FUNDER": "Financijer istraživanja", "POLICY-MAKER": "Donositelj politike", - "SME-INDUSTRY": "Malo ili srednje poduzeće", + "SME-INDUSTRY": "Mala ili srednja tvrtka", "OTHER": "Drugo" }, "ACTIONS": { @@ -1749,9 +1761,9 @@ "GRANT-STATUS": { "TITLE": "Status potpore", "OPTIONS": { - "ANY": "Bilo koji", - "ACTIVE": "Aktivan", - "INACTIVE": "Neaktivan" + "ANY": "Bilo koja", + "ACTIVE": "Aktivna", + "INACTIVE": "Neaktivna" } }, "GRANT": { @@ -1763,7 +1775,7 @@ }, "ROLE": { "TITLE": "Uloga", - "ANY": "Bilo koji", + "ANY": "Bilo koja", "OWNER": "Vlasnik", "MEMBER": "Član" }, @@ -1843,31 +1855,31 @@ "DESCRIPTION": "Sažetak", "DESCRIPTION-HINT": "Ukratko opišite kontekst i svrhu Plana", "PROFILE": "Predložak za skup podataka", - "PROFILE-HINT": "Izaberite predložak za opis podataka. Ako želite da izaberete više od jednog obrasca, koristite \"Novi Plan (napredno)\". Novi skup podataka možete dodati i u bilo kom trenutku nakon kreiranja Plana.", - "HELP": "Ako ne pronalazite obrazac ili želite kreirati prilagođeni obrazac za svoju ustanovu, zajednicu istraživača ili za potrebe edukacije, kontaktirajte nas." + "PROFILE-HINT": "Izaberite predložak za opis podataka. Ako želite da izaberete više od jednog predloška, koristite \"Novi Plan (napredno)\". Novi skup podataka možete dodati i u bilo kom trenutku nakon kreiranja Plana.", + "HELP": "Ako ne pronalazite predložak ili želite kreirati prilagođeni predložak za svoju ustanovu, zajednicu istraživača ili za potrebe edukacije, kontaktirajte nas." } }, "THIRD-STEP": { "TITLE": "Skup podataka", "NEW-TITLE": "", - "DATASET-LABEL": "Naslov skupa podataka", + "DATASET-LABEL": "Naziv skupa podataka", "DATASET-NAME": "Skup podataka:", "DATASET-NAME-FOR": "Za Plan:", "LIST-BUTTON-TOOLTIP": "Popis skupova podataka", - "ADD-BUTTON-TOOLTIP": "Unesite skup podataka" + "ADD-BUTTON-TOOLTIP": "Unesite opis skupa podataka" } } }, "ADD": { - "TITLE": "Unesite skup podataka u postojeći Plan", + "TITLE": "Unesite opis skupa podataka u postojeći Plan", "DATASET-WIZARD": "Čarobnjak za skup podataka", - "POST-SELECTION-INFO": "Ovaj čarobnjak pojednostavljuje proces dodavanja novih skupova podataka u postojeće Planove upravljanja podacima, vodeći Vas kroz proces kreiranja te unos samo osnovnih informacija. Cjelovitom opisu skupa podataka može se naknadno pristupiti putem izbornika", + "POST-SELECTION-INFO": "Ovaj čarobnjak pojednostavljuje proces dodavanja novih opisa skupova podataka u postojeće Planove upravljanja podacima, vodeći Vas kroz proces kreiranja te unos samo osnovnih informacija. Cjelovitom opisu skupa podataka može se naknadno pristupiti putem izbornika", "SUBTITLE": "Čarobnjak omogućuje opisivanje dodatnih skupova podataka kojima se upravlja, a u kontekstu plana upravljanja podacima i uz osnovne informacije neophodne za njihov opis.", "CREATED": "Kreirano" } }, "SAVE-DIALOG": { - "TITLE": "Želite li dodati skup podataka?", + "TITLE": "Želite li dodati opis skupa podataka?", "ACTIONS": { "AFFIRMATIVE": "Da", "NEGATIVE": "Ne" @@ -1881,4 +1893,4 @@ "FINALIZED": "Završeno", "DELETED": "Izbrisano" } -} +} \ No newline at end of file diff --git a/dmp-frontend/src/assets/i18n/pl.json b/dmp-frontend/src/assets/i18n/pl.json index 4dba630af..6aa8aec2b 100644 --- a/dmp-frontend/src/assets/i18n/pl.json +++ b/dmp-frontend/src/assets/i18n/pl.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "$Minimalna wielokrotność$", "MULTIPLICITY-MAX": "$Maksymalna wielokrotność$", "MULTIPLICITY-PLACEHOLDER": "$Tekst zastępujący wielokrotność$", - "MULTIPLICITY-ADD-ONE-FIELD": "Dodaj więcej", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", + "MULTIPLICITY-ADD-ONE-FIELD": "Dodaj więcej", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Kolejność", "COMMENT-PLACEHOLDER": "Proszę doprecyzować", "COMMENT-HINT": "Podaj dodatkowe informacje lub uzasadnienie swojego wyboru", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Zaloguj się za pomocą Zenodo", "USE-DEFAULT": "Użyj domyślnego tokena" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,8 +1069,9 @@ "LOCK": "DMP jest zablokowany przez innego użytkownika", "PERMISSION": "Nie masz uprawnień do edycji tego DMP", "INSERT-MANUALLY": "Wstaw ręcznie", - "CREATE-DATASET": "Utwórz nowy" - }, + "CREATE-DATASET": "Utwórz nowy", + "DISABLED-EXPORT": "Please save your changes to export this DMP" + }, "PLACEHOLDER": { "DESCRIPTION": "Dodaj opis", "ORGANIZATION": "Wybierz organizację", @@ -1268,8 +1279,9 @@ "DISCARD-EDITED-MESSAGE": "Wszystkie niezapisane zmiany zostaną przywrócone do stanu początkowego i nastąpi przekierowanie z powrotem do Edytora DMP. Czy chcesz kontynuować?", "DISCARD-EDITED-CONFIRM": "Tak, cofnij zmiany i wróć.", "DISCARD-EDITED-DENY": "Nie" - } - }, + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" + }, "PLACEHOLDER": { "DESCRIPTION": "Wpisz opis", "EXTERNAL-LINK": "Podaj zewnętrzny link URL" diff --git a/dmp-frontend/src/assets/i18n/pt.json b/dmp-frontend/src/assets/i18n/pt.json index 8123b7bca..9bff4f4fe 100644 --- a/dmp-frontend/src/assets/i18n/pt.json +++ b/dmp-frontend/src/assets/i18n/pt.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Multiplicidade Min", "MULTIPLICITY-MAX": "Multiplicidade Máx", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Ordem", "COMMENT-PLACEHOLDER": "Por favor especifique", "COMMENT-HINT": "Disponibilize informação ou justificação adicional sobre a sua seleção", @@ -808,6 +810,14 @@ "ZENODO-LOGIN": "Entre com o Zenodo", "USE-DEFAULT": "Use o Token" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "O PGD está bloqueado por outro utilizador", "PERMISSION": "Não tem permissão para editar este PGD", "INSERT-MANUALLY": "Inserir manualmente", - "CREATE-DATASET": "Criar um novo" + "CREATE-DATASET": "Criar um novo", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Preencha com a descrição", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "Todas as alterações irão ser descartadas e será redirecionado para o editor do PGD. Pretende continuar?", "DISCARD-EDITED-CONFIRM": "Sim, reverter as alterações e voltar atrás.", "DISCARD-EDITED-DENY": "Não" - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Preencher com descrição", diff --git a/dmp-frontend/src/assets/i18n/sk.json b/dmp-frontend/src/assets/i18n/sk.json index 06032b3d8..4e4998d69 100644 --- a/dmp-frontend/src/assets/i18n/sk.json +++ b/dmp-frontend/src/assets/i18n/sk.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Multiplicity Min", "MULTIPLICITY-MAX": "Multiplicity Max", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Order", "COMMENT-PLACEHOLDER": "Please Specify", "COMMENT-HINT": "Provide additional information or justification about your selection", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Prihlásiť sa do Zenodo", "USE-DEFAULT": "Použite predvolený token" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "DMP je zamknutý iným používateľom DMP", "PERMISSION": "Na úpravu tohto DMP nemáte povolenie", "INSERT-MANUALLY": "Doplniť manuálne", - "CREATE-DATASET": "Vytvoriť nový" + "CREATE-DATASET": "Vytvoriť nový", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Doplniť opis", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Doplniť opis", diff --git a/dmp-frontend/src/assets/i18n/sr.json b/dmp-frontend/src/assets/i18n/sr.json index bd4751501..25bc7afaf 100644 --- a/dmp-frontend/src/assets/i18n/sr.json +++ b/dmp-frontend/src/assets/i18n/sr.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "Višestrukost, minimalno polja", "MULTIPLICITY-MAX": "Višestrukost, maksimalno polja", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Redosled", "COMMENT-PLACEHOLDER": "Navedite", "COMMENT-HINT": "Navedite dodatne informacije ili obrazložite izbor", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Prijavite se pomoću Zenodo naloga", "USE-DEFAULT": "Koristite podrazumevani znak" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "Plan upravljanja podacima je zaključao drugi korisnik", "PERMISSION": "Nemate dozvolu da uređujete ovaj Plan", "INSERT-MANUALLY": "Unesite ručno", - "CREATE-DATASET": "Kreirajte novi" + "CREATE-DATASET": "Kreirajte novi", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Dodajte opis", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Dopunite opisom", diff --git a/dmp-frontend/src/assets/i18n/tr.json b/dmp-frontend/src/assets/i18n/tr.json index a99da8a5b..a6856a9b8 100644 --- a/dmp-frontend/src/assets/i18n/tr.json +++ b/dmp-frontend/src/assets/i18n/tr.json @@ -374,7 +374,9 @@ "MULTIPLICITY-MIN": "En az Çokluk", "MULTIPLICITY-MAX": "En fazla Çokluk", "MULTIPLICITY-PLACEHOLDER": "Multiplicity Placeholder Text", + "MULTIPLICITY-TABLEVIEW": "View inputs in table", "MULTIPLICITY-ADD-ONE-FIELD": "Add more", + "MULTIPLICITY-ADD-ONE-FIELD-TABLEVIEW": "Add row", "ORDER": "Düzen", "COMMENT-PLACEHOLDER": "Lütfen Belirtiniz", "COMMENT-HINT": "Seçiminiz hakkında gerekçe veya ek bilgi veriniz", @@ -803,6 +805,14 @@ "ZENODO-LOGIN": "Zenodo ile oturum aç", "USE-DEFAULT": "Mevcut Jetonu Kullan" }, + "DEPOSIT": { + "ACCOUNT-LOGIN": "Which account would you like to use?", + "LOGIN": "Login with {{repository}}", + "NO-REPOSITORIES": "No publishing repositories", + "SELECT-REPOSITORIES": "Select repositories to deposit", + "AUTHORIZE": "Proceed to authorization", + "CANCEL": "Cancel" + }, "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." @@ -1059,7 +1069,8 @@ "LOCK": "VYP başka bir kullanıcı tarafından kilitlendi", "PERMISSION": "Bu VYP'nı düzenleme yetkiniz yok", "INSERT-MANUALLY": "Manuel olarak ekle", - "CREATE-DATASET": "Yeni bir tane oluştur" + "CREATE-DATASET": "Yeni bir tane oluştur", + "DISABLED-EXPORT": "Please save your changes to export this DMP" }, "PLACEHOLDER": { "DESCRIPTION": "Açıklamaları Doldur", @@ -1268,7 +1279,8 @@ "DISCARD-EDITED-MESSAGE": "All unsaved changes will be reverted to their initial state and you will be redirected back to DMP Editor. Would you like to proceed?", "DISCARD-EDITED-CONFIRM": "Yes, revert changes and go back.", "DISCARD-EDITED-DENY": "No." - } + }, + "DISABLED-EXPORT": "Please save your changes to export this Dataset" }, "PLACEHOLDER": { "DESCRIPTION": "Açıklamayla Doldur", diff --git a/dmp-frontend/src/assets/images/repository-placeholder.png b/dmp-frontend/src/assets/images/repository-placeholder.png new file mode 100644 index 000000000..c5f84947a Binary files /dev/null and b/dmp-frontend/src/assets/images/repository-placeholder.png differ diff --git a/repo-jars/dataverse.json b/repo-jars/dataverse.json new file mode 100644 index 000000000..473d94515 --- /dev/null +++ b/repo-jars/dataverse.json @@ -0,0 +1,11 @@ +{ + "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 diff --git a/repo-jars/zenodo.json b/repo-jars/zenodo.json new file mode 100644 index 000000000..cd77e1ed4 --- /dev/null +++ b/repo-jars/zenodo.json @@ -0,0 +1,14 @@ +{ + "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