diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java index dad3243b4..d2b712ea2 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDao.java @@ -16,4 +16,6 @@ public interface DatasetProfileDao extends DatabaseAccessLayer getAuthenticated(QueryableList query, UUID principal, List roles); + List getAllIds(); + } \ No newline at end of file diff --git a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java index 0822ce6f4..b6cbb445b 100644 --- a/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java +++ b/dmp-backend/data/src/main/java/eu/eudat/data/dao/entities/DatasetProfileDaoImpl.java @@ -15,6 +15,7 @@ import org.springframework.stereotype.Component; import javax.persistence.criteria.Join; import javax.persistence.criteria.JoinType; import java.util.Arrays; +import java.util.Collections; import java.util.List; import java.util.UUID; import java.util.concurrent.CompletableFuture; @@ -86,6 +87,11 @@ public class DatasetProfileDaoImpl extends DatabaseAccess implem return getDatabaseService().getQueryable(DatasetProfile.class); } + @Override + public List getAllIds(){ + return getDatabaseService().getQueryable(DatasetProfile.class).withFields(Collections.singletonList("id")).toList(); + } + @Override public void delete(DatasetProfile item) { this.getDatabaseService().delete(item); 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 cbd796ca2..036069e86 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 @@ -25,7 +25,12 @@ import java.util.stream.Collectors; name = "fullyDetailed", attributeNodes = { @NamedAttributeNode("grant"), @NamedAttributeNode("profile"), - @NamedAttributeNode("users"), @NamedAttributeNode("organisations"), @NamedAttributeNode("researchers")}), + @NamedAttributeNode(value = "users", subgraph = "users"), @NamedAttributeNode("organisations"), @NamedAttributeNode("researchers") + }, + subgraphs = { + @NamedSubgraph(name = "users", attributeNodes = {@NamedAttributeNode("user")}) + } + ), @NamedEntityGraph( name = "dmpRecentActivity", attributeNodes = { diff --git a/dmp-backend/web/pom.xml b/dmp-backend/web/pom.xml index 8d9e4047b..4eb9021f9 100644 --- a/dmp-backend/web/pom.xml +++ b/dmp-backend/web/pom.xml @@ -34,7 +34,7 @@ gr.cite.opendmp repositorydepositbase - 1.0.1 + 1.0.3 diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java new file mode 100644 index 000000000..b0bf85aea --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/AboutController.java @@ -0,0 +1,46 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.managers.MaterialManager; +import eu.eudat.logic.managers.MetricsManager; +import eu.eudat.types.MetricNames; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.stream.Stream; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/material/about/"}) +public class AboutController { + + private Environment environment; + private MaterialManager materialManager; + private final MetricsManager metricsManager; + + @Autowired + public AboutController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { + this.environment = environment; + this.materialManager = materialManager; + this.metricsManager = metricsManager; + } + + @RequestMapping(path = "{lang}", method = RequestMethod.GET ) + public ResponseEntity getAbout(@PathVariable(name = "lang") String lang) throws IOException { +// long files = 0; +// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { +// files = paths.count(); +// } +// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); + try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("about.path"))))) { + return this.materialManager.getResponseEntity(lang, paths); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java index 7a7e32a19..7829f2fa9 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Admin.java @@ -190,8 +190,10 @@ public class Admin extends BaseController { .status(ApiMessageCode.SUCCESS_MESSAGE).message("")); } - @RequestMapping(method = RequestMethod.GET, value = {"/getRDACommonStandards"}, produces = "application/json") - public ResponseEntity getRDACommonStandards(@ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(configLoader.getRdaProperties())); + + @RequestMapping(method = RequestMethod.GET, value = {"/getSemantics"}, produces = "application/json") + public ResponseEntity>> getSemantics(@RequestParam(value = "query", required = false) String query, @ClaimedAuthorities(claims = {ADMIN, DATASET_PROFILE_MANAGER}) Principal principal) { + List semantics = this.datasetProfileManager.getSemantics(query); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().status(ApiMessageCode.SUCCESS_MESSAGE).payload(semantics)); } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java index efc212e5e..a2a1926f6 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DMPs.java @@ -9,12 +9,10 @@ import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Dataset; import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.data.query.items.table.dmp.DataManagementPlanTableRequest; -import eu.eudat.data.query.items.table.dmp.DataManagmentPlanPublicTableRequest; import eu.eudat.exceptions.datamanagementplan.DMPNewVersionException; import eu.eudat.exceptions.datamanagementplan.DMPWithDatasetsDeleteException; import eu.eudat.exceptions.security.UnauthorisedException; import eu.eudat.logic.managers.DataManagementPlanManager; -import eu.eudat.logic.managers.DatasetManager; import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.logic.services.ApiContext; @@ -152,7 +150,7 @@ public class DMPs extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/publicOverview/{id}"}) public @ResponseBody - ResponseEntity getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + ResponseEntity> getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { // try { DataManagementPlanOverviewModel dataManagementPlan = this.dataManagementPlanManager.getOverviewSingle(id, principal, true); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataManagementPlan)); @@ -184,7 +182,21 @@ public class DMPs extends BaseController { public @ResponseBody ResponseEntity getRDAJsonDocument(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) { try { - return this.dataManagementPlanManager.getRDAJsonDocument(id, principal); + FileEnvelope rdaJsonDocument = this.dataManagementPlanManager.getRDAJsonDocument(id, principal); + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(rdaJsonDocument.getFile().length()); + responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); + responseHeaders.set("Content-Disposition", "attachment;filename=" + rdaJsonDocument.getFilename()); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + InputStream resource = new FileInputStream(rdaJsonDocument.getFile()); + byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource); + resource.close(); + Files.deleteIfExists(rdaJsonDocument.getFile().toPath()); + + return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); } catch (Exception e) { return ResponseEntity.status(HttpStatus.EXPECTATION_FAILED).body(new ResponseItem<>().message(e.getMessage()).status(ApiMessageCode.ERROR_MESSAGE)); } @@ -321,21 +333,6 @@ public class DMPs extends BaseController { } } - /* - * DOI Generation - * */ - - @RequestMapping(method = RequestMethod.POST, value = {"/createZenodoDoi/{id}"}) - public ResponseEntity> createZenodoDoi(@PathVariable String id, Principal principal) { - try { - String zenodoDOI = this.dataManagementPlanManager.createZenodoDoi(UUID.fromString(id), principal); - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Successfully created DOI for Data Datamanagement Plan in question.").payload(zenodoDOI)); - } 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())); - } - } - /* * Data Index * */ diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java index 94a17913b..8c5b003fa 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Datasets.java @@ -117,7 +117,7 @@ public class Datasets extends BaseController { @RequestMapping(method = RequestMethod.GET, value = {"/publicOverview/{id}"}) public @ResponseBody - ResponseEntity getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { + ResponseEntity> getOverviewSinglePublic(@PathVariable String id, @ClaimedAuthorities(claims = {Authorities.ADMIN, Authorities.MANAGER, Authorities.USER, Authorities.ANONYMOUS}) Principal principal) throws Exception { // try { DatasetOverviewModel dataset = this.datasetManager.getOverviewSingle(id, principal, true); return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).payload(dataset)); diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailUnlinkConfirmation.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailUnlinkConfirmation.java new file mode 100644 index 000000000..5dcc639bc --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/EmailUnlinkConfirmation.java @@ -0,0 +1,57 @@ +package eu.eudat.controllers; + +import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; +import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; +import eu.eudat.logic.managers.UnlinkEmailConfirmationManager; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.models.data.userinfo.UserUnlinkRequestModel; +import eu.eudat.types.ApiMessageCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.transaction.Transactional; + +@RestController +@CrossOrigin +@RequestMapping(value = "api/emailUnlinkConfirmation") +public class EmailUnlinkConfirmation { + + private UnlinkEmailConfirmationManager unlinkEmailConfirmationManager; + + @Autowired + public EmailUnlinkConfirmation(UnlinkEmailConfirmationManager unlinkEmailConfirmationManager){ + this.unlinkEmailConfirmationManager = unlinkEmailConfirmationManager; + } + + @Transactional + @RequestMapping(method = RequestMethod.GET, value = {"/{emailToken}"}) + public @ResponseBody + ResponseEntity emailConfirmation(@PathVariable(value = "emailToken") String token) { + try { + this.unlinkEmailConfirmationManager.confirmEmail(token); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (TokenExpiredException | HasConfirmedEmailException ex) { + if (ex instanceof TokenExpiredException) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE)); + } + else { + return ResponseEntity.status(HttpStatus.FOUND).body(new ResponseItem().status(ApiMessageCode.WARN_MESSAGE)); + } + } + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, consumes = "application/json", produces = "application/json") + public @ResponseBody + ResponseEntity sendUnlinkConfirmationEmail(@RequestBody UserUnlinkRequestModel requestModel, Principal principal) { + try { + this.unlinkEmailConfirmationManager.sendConfirmationEmail(requestModel.getEmail(), principal, requestModel.getUserId(), requestModel.getProvider()); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (Exception ex) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.NO_MESSAGE).message("Could not send unlink email.")); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java new file mode 100644 index 000000000..0aa9ff078 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FaqController.java @@ -0,0 +1,45 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.managers.MaterialManager; +import eu.eudat.logic.managers.MetricsManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.stream.Stream; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/material/faq/"}) +public class FaqController { + + private Environment environment; + private MaterialManager materialManager; + private final MetricsManager metricsManager; + + @Autowired + public FaqController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { + this.environment = environment; + this.materialManager = materialManager; + this.metricsManager = metricsManager; + } + + @RequestMapping(path = "{lang}", method = RequestMethod.GET ) + public ResponseEntity getFaq(@PathVariable(name = "lang") String lang) throws IOException { +// long files = 0; +// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { +// files = paths.count(); +// } +// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); + try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("faq.path"))))) { + return this.materialManager.getResponseEntity(lang, paths); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java new file mode 100644 index 000000000..f46e0f4f0 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/GlossaryController.java @@ -0,0 +1,45 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.managers.MaterialManager; +import eu.eudat.logic.managers.MetricsManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.stream.Stream; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/material/glossary/"}) +public class GlossaryController { + + private Environment environment; + private MaterialManager materialManager; + private final MetricsManager metricsManager; + + @Autowired + public GlossaryController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { + this.environment = environment; + this.materialManager = materialManager; + this.metricsManager = metricsManager; + } + + @RequestMapping(path = "{lang}", method = RequestMethod.GET ) + public ResponseEntity getGlossary(@PathVariable(name = "lang") String lang) throws IOException { +// long files = 0; +// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { +// files = paths.count(); +// } +// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); + try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("glossary.path"))))) { + return this.materialManager.getResponseEntity(lang, paths); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/ManagementController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/ManagementController.java new file mode 100644 index 000000000..d72441595 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/ManagementController.java @@ -0,0 +1,54 @@ +package eu.eudat.controllers; + +import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException; +import eu.eudat.logic.managers.DatasetProfileManager; +import eu.eudat.logic.security.claims.ClaimedAuthorities; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.admin.composite.DatasetProfile; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.models.data.security.Principal; +import eu.eudat.types.ApiMessageCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpStatus; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import javax.transaction.Transactional; + +import static eu.eudat.types.Authorities.ADMIN; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/management/"}) +public class ManagementController extends BaseController { + + private DatasetProfileManager datasetProfileManager; + + @Autowired + public ManagementController(ApiContext apiContext, DatasetProfileManager datasetProfileManager){ + super(apiContext); + this.datasetProfileManager = datasetProfileManager; + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/addSemantics"}) + public ResponseEntity addSemanticsInDatasetProfiles(@ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.datasetProfileManager.addSemanticsInDatasetProfiles(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (Exception exception) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(exception.getMessage())); + } + } + + @Transactional + @RequestMapping(method = RequestMethod.POST, value = {"/addRdaInSemantics"}) + public ResponseEntity addRdaInSemanticsInDatasetProfiles(@ClaimedAuthorities(claims = {ADMIN}) Principal principal) throws Exception { + try { + this.datasetProfileManager.addRdaInSemanticsInDatasetProfiles(); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE)); + } catch (Exception exception) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message(exception.getMessage())); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java new file mode 100644 index 000000000..9f95273c7 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Saml2MetadataController.java @@ -0,0 +1,78 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.Saml2ConfigurableProvider; +import eu.eudat.logic.security.validators.configurableProvider.Saml2SSOUtils; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.models.data.helpers.responses.ResponseItem; +import eu.eudat.types.ApiMessageCode; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.nio.charset.StandardCharsets; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/saml2/"}) +public class Saml2MetadataController extends BaseController { + + private final ConfigLoader configLoader; + + @Autowired + public Saml2MetadataController(ApiContext apiContext, ConfigLoader configLoader) { + super(apiContext); + this.configLoader = configLoader; + } + + @RequestMapping(method = RequestMethod.GET, value = {"metadata/{configurableProviderId}"}) + public @ResponseBody + ResponseEntity getMetadata(@PathVariable String configurableProviderId) { + Saml2ConfigurableProvider saml2ConfigurableProvider = (Saml2ConfigurableProvider) this.configLoader.getConfigurableProviders().getProviders().stream() + .filter(prov -> prov.getConfigurableLoginId().equals(configurableProviderId)) + .findFirst().orElse(null); + if (saml2ConfigurableProvider != null) { + try { + String metadataXml = Saml2SSOUtils.getMetadata(saml2ConfigurableProvider); + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(metadataXml.length()); + responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); + responseHeaders.set("Content-Disposition", "attachment;filename=" + configurableProviderId + ".xml"); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + return new ResponseEntity<>(metadataXml.getBytes(StandardCharsets.UTF_8), + responseHeaders, + HttpStatus.OK); + } catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to fetch metadata.")); + } + } + else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to fetch metadata.")); + } + } + @RequestMapping(method = RequestMethod.GET, value = {"authnRequest/{configurableProviderId}"}) + public @ResponseBody + ResponseEntity> getAuthnRequest(@PathVariable String configurableProviderId) { + Saml2ConfigurableProvider saml2ConfigurableProvider = (Saml2ConfigurableProvider) this.configLoader.getConfigurableProviders().getProviders().stream() + .filter(prov -> prov.getConfigurableLoginId().equals(configurableProviderId)) + .findFirst().orElse(null); + if (saml2ConfigurableProvider != null) { + try { + String authnRequestXml = Saml2SSOUtils.getAuthnRequest(saml2ConfigurableProvider); + return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().status(ApiMessageCode.SUCCESS_MESSAGE).message("Created").payload(authnRequestXml)); + } + catch (Exception e) { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Failed to create authentication request.")); + } + + } + else { + return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ResponseItem().status(ApiMessageCode.ERROR_MESSAGE).message("Unknown provider.")); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java new file mode 100644 index 000000000..d9d015193 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/TermsOfServiceController.java @@ -0,0 +1,45 @@ +package eu.eudat.controllers; + +import eu.eudat.logic.managers.MaterialManager; +import eu.eudat.logic.managers.MetricsManager; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.core.env.Environment; +import org.springframework.http.ResponseEntity; +import org.springframework.web.bind.annotation.*; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Objects; +import java.util.stream.Stream; + +@RestController +@CrossOrigin +@RequestMapping(value = {"/api/material/termsofservice/"}) +public class TermsOfServiceController { + + private Environment environment; + private MaterialManager materialManager; + private final MetricsManager metricsManager; + + @Autowired + public TermsOfServiceController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { + this.environment = environment; + this.materialManager = materialManager; + this.metricsManager = metricsManager; + } + + @RequestMapping(path = "{lang}", method = RequestMethod.GET ) + public ResponseEntity getTermsOfService(@PathVariable(name = "lang") String lang) throws IOException { +// long files = 0; +// try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { +// files = paths.count(); +// } +// metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); + try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("termsofservice.path"))))) { + return this.materialManager.getResponseEntity(lang, paths); + } + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java index 9e26cf92a..f513238cf 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/UserGuideController.java @@ -1,5 +1,6 @@ package eu.eudat.controllers; +import eu.eudat.logic.managers.MaterialManager; import eu.eudat.logic.managers.MetricsManager; import eu.eudat.logic.security.claims.ClaimedAuthorities; import eu.eudat.models.data.helpers.responses.ResponseItem; @@ -32,47 +33,26 @@ import static eu.eudat.types.Authorities.ADMIN; public class UserGuideController { private Environment environment; + private MaterialManager materialManager; private final MetricsManager metricsManager; @Autowired - public UserGuideController(Environment environment, MetricsManager metricsManager) { + public UserGuideController(Environment environment, MaterialManager materialManager, MetricsManager metricsManager) { this.environment = environment; + this.materialManager = materialManager; this.metricsManager = metricsManager; } @RequestMapping(path = "{lang}", method = RequestMethod.GET ) - public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { + public ResponseEntity getUserGuide(@PathVariable(name = "lang") String lang) throws IOException { long files = 0; try (Stream paths = Files.list(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { files = paths.count(); } - metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); + metricsManager.calculateValue(MetricNames.LANGUAGES, (int) files, null); try (Stream paths = Files.walk(Paths.get(Objects.requireNonNull(this.environment.getProperty("userguide.path"))))) { - List result = paths.filter(Files::isRegularFile) - .map(Path::toString).collect(Collectors.toList()); - - String fileName = result.stream().filter(guide -> guide.contains("_" + lang)).findFirst().orElse(null); - if (fileName == null) { - fileName = result.stream().filter(guide -> guide.contains("_en")).findFirst().get(); - } - InputStream is = new FileInputStream(fileName); - - Path path = Paths.get(fileName); - - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(is.available()); - responseHeaders.setContentType(MediaType.TEXT_HTML); - responseHeaders.set("Content-Disposition", "attachment;filename=" + path.getFileName().toString()); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = new byte[is.available()]; - is.read(content); - is.close(); - - return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); + return this.materialManager.getResponseEntity(lang, paths); } - } @RequestMapping(value = "current", method = RequestMethod.POST) diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java index 2a7c56f5a..88a020232 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/Users.java @@ -88,16 +88,6 @@ public class Users extends BaseController { return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem>().payload(dataTable).status(ApiMessageCode.NO_MESSAGE)); } - @RequestMapping(method = RequestMethod.GET, value = {"/hasDOIToken"}, consumes = "application/json", produces = "application/json") - public @ResponseBody - ResponseEntity> hasDOIToken(Principal principal) throws NullEmailException { - try { - return ResponseEntity.status(HttpStatus.OK).body(new ResponseItem().payload(this.userManager.isDOITokenValid(principal)).status(ApiMessageCode.NO_MESSAGE)); - } catch (NonValidTokenException | ExpiredTokenException | IOException e) { - return ResponseEntity.status(460).body(new ResponseItem().payload(false).status(ApiMessageCode.ERROR_MESSAGE).message(e.getMessage())); - } - } - @Transactional @RequestMapping(method = RequestMethod.POST, value = {"/registerDOIToken"}, consumes = "application/json", produces = "application/json") public @ResponseBody 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 abcf306b5..cb2e8a2bc 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 @@ -481,6 +481,7 @@ public class DataManagementPlanManager { checkDmpValidationRules(newDmp); } UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + newDmp.setCreator(user); createOrganisationsIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, apiContext.getOperationsContext().getDatabaseRepository().getResearcherDao(), user); @@ -645,6 +646,7 @@ public class DataManagementPlanManager { if (latestVersionDMP.get(0).getVersion().equals(oldDmp.getVersion())) { DMP newDmp = dataManagementPlan.toDataModel(); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); + newDmp.setCreator(user); createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); @@ -705,6 +707,7 @@ public class DataManagementPlanManager { DMP newDmp = dataManagementPlan.toDataModel(); UserInfo user = apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserInfoBuilder.class).id(principal.getId()).build(); + newDmp.setCreator(user); createOrganisationsIfTheyDontExist(newDmp, databaseRepository.getOrganisationDao()); createResearchersIfTheyDontExist(newDmp, databaseRepository.getResearcherDao(), user); @@ -1064,9 +1067,6 @@ public class DataManagementPlanManager { }); UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); sendNotification(dmp, user, NotificationType.DMP_PUBLISH); -// if (dmp.getDois() != null && !dmp.getDois().isEmpty()) { -// this.createZenodoDoi(dmp.getId(), principal, true); -// } } @Transactional @@ -1456,6 +1456,40 @@ public class DataManagementPlanManager { } dmpElement.appendChild(dmpProfileElement); + Element dmpContactElement = xmlDoc.createElement("contact"); + Element dmpContactName = xmlDoc.createElement("name"); + Element dmpContactEmail = xmlDoc.createElement("email"); + if(dmp.getCreator() != null){ + dmpContactName.setTextContent(dmp.getCreator().getName()); + dmpContactEmail.setTextContent(dmp.getCreator().getEmail()); + } + else{ + Iterator users = dmp.getUsers().iterator(); + if(users.hasNext()){ + UserDMP creator = users.next(); + dmpContactName.setTextContent(creator.getUser().getName()); + dmpContactEmail.setTextContent(creator.getUser().getEmail()); + } + } + dmpContactElement.appendChild(dmpContactName); + dmpContactElement.appendChild(dmpContactEmail); + dmpElement.appendChild(dmpContactElement); + + Element dmpContributorsElement = xmlDoc.createElement("contributors"); + Iterator users = dmp.getUsers().iterator(); + while(users.hasNext()){ + Element dmpContributorElement = xmlDoc.createElement("contributor"); + Element dmpContributorName = xmlDoc.createElement("name"); + Element dmpContributorEmail= xmlDoc.createElement("email"); + UserDMP contributor = users.next(); + dmpContributorName.setTextContent(contributor.getUser().getName()); + dmpContributorEmail.setTextContent(contributor.getUser().getEmail()); + dmpContributorElement.appendChild(dmpContributorName); + dmpContributorElement.appendChild(dmpContributorEmail); + dmpContributorsElement.appendChild(dmpContributorElement); + } + dmpElement.appendChild(dmpContributorsElement); + // Funder. Element funder = xmlDoc.createElement("funder"); Element funderLabel = xmlDoc.createElement("label"); @@ -1464,6 +1498,13 @@ public class DataManagementPlanManager { funderId.setTextContent(dmp.getGrant().getFunder().getId().toString()); funder.appendChild(funderLabel); funder.appendChild(funderId); + if(dmp.getGrant().getFunder().getReference() != null){ + String referencePrefix = dmp.getGrant().getFunder().getReference().split(":")[0]; + String shortReference = dmp.getGrant().getFunder().getReference().substring(referencePrefix.length() + 1); + Element funderReference = xmlDoc.createElement("reference"); + funderReference.setTextContent(shortReference); + funder.appendChild(funderReference); + } dmpElement.appendChild(funder); // Grant. Element grant = xmlDoc.createElement("grant"); @@ -1473,15 +1514,31 @@ public class DataManagementPlanManager { grantId.setTextContent(dmp.getGrant().getId().toString()); grant.appendChild(grantLabel); grant.appendChild(grantId); + if(dmp.getGrant().getReference() != null) { + String referencePrefix = dmp.getGrant().getReference().split(":")[0]; + String shortReference = dmp.getGrant().getReference().substring(referencePrefix.length() + 1); + Element grantReference = xmlDoc.createElement("reference"); + grantReference.setTextContent(shortReference); + grant.appendChild(grantReference); + } dmpElement.appendChild(grant); // Project. Element project = xmlDoc.createElement("project"); - Element projectLabel = xmlDoc.createElement("label"); Element projectId = xmlDoc.createElement("id"); - projectLabel.setTextContent(dmp.getProject().getLabel()); + Element projectLabel = xmlDoc.createElement("label"); + Element projectDescription = xmlDoc.createElement("description"); + Element projectStartDate = xmlDoc.createElement("start"); + Element projectEndDate = xmlDoc.createElement("end"); projectId.setTextContent(dmp.getProject().getId().toString()); - project.appendChild(projectLabel); + projectLabel.setTextContent(dmp.getProject().getLabel()); + projectDescription.setTextContent(dmp.getProject().getDescription()); + projectStartDate.setTextContent(dmp.getProject().getStartdate().toString()); + projectEndDate.setTextContent(dmp.getProject().getEnddate().toString()); project.appendChild(projectId); + project.appendChild(projectLabel); + project.appendChild(projectDescription); + project.appendChild(projectStartDate); + project.appendChild(projectEndDate); dmpElement.appendChild(project); Element organisationsElement = xmlDoc.createElement("organisations"); @@ -1513,11 +1570,20 @@ public class DataManagementPlanManager { for (Dataset dataset : datasets) { Element datasetElement = xmlDoc.createElement("dataset"); - Element datsetProfileElement = xmlDoc.createElement("profile"); datasetElement.setAttribute("name", dataset.getLabel()); + + Element datasetDescriptionElement = xmlDoc.createElement("description"); + datasetElement.appendChild(datasetDescriptionElement); + datasetDescriptionElement.setTextContent(dataset.getDescription()); + + Element datsetProfileElement = xmlDoc.createElement("profile-id"); datasetElement.appendChild(datsetProfileElement); datsetProfileElement.setTextContent(dataset.getProfile().getId().toString()); + Element datsetProfileLabelElement = xmlDoc.createElement("profile-label"); + datasetElement.appendChild(datsetProfileLabelElement); + datsetProfileLabelElement.setTextContent(dataset.getProfile().getLabel()); + DatasetWizardModel datasetWizardModel = new DatasetWizardModel(); Map properties = new HashMap<>(); if (dataset.getProperties() != null) { @@ -1535,12 +1601,18 @@ public class DataManagementPlanManager { // Get DatasetProfiles from DMP to add to XML. for (DatasetProfile datasetProfile : dmp.getAssociatedDmps()) { Element profile = xmlDoc.createElement("profile"); - Element profileLabel = xmlDoc.createElement("profilelabel"); - profileLabel.setTextContent(datasetProfile.getLabel()); - profile.appendChild(profileLabel); Element profileId = xmlDoc.createElement("profileId"); profileId.setTextContent(datasetProfile.getId().toString()); profile.appendChild(profileId); + Element profileGroupId = xmlDoc.createElement("profileGroupId"); + profileGroupId.setTextContent(datasetProfile.getGroupId().toString()); + profile.appendChild(profileGroupId); + Element profileLabel = xmlDoc.createElement("profileLabel"); + profileLabel.setTextContent(datasetProfile.getLabel()); + profile.appendChild(profileLabel); + Element profileVersion = xmlDoc.createElement("profileVersion"); + profileVersion.setTextContent(String.valueOf(datasetProfile.getVersion())); + profile.appendChild(profileVersion); profiles.appendChild(profile); } dmpElement.appendChild(profiles); @@ -1556,13 +1628,12 @@ public class DataManagementPlanManager { return fileEnvelope; } - public ResponseEntity getRDAJsonDocument(String id, Principal principal) throws Exception { + public FileEnvelope getRDAJsonDocument(String id, Principal principal) throws Exception { eu.eudat.data.entities.DMP dmp = databaseRepository.getDmpDao().find(UUID.fromString(id)); if (!dmp.isPublic() && dmp.getUsers().stream().noneMatch(userInfo -> userInfo.getUser().getId() == principal.getId())) throw new UnauthorisedException(); -// RDAExportModel rdaExportModel = new RDAExportModel().fromDataModel(dmp, datasetManager, principal); - final Boolean isFinalized = dmp.getStatus() == DMP.DMPStatus.FINALISED.getValue(); - final Boolean isPublic = dmp.isPublic(); + final boolean isFinalized = dmp.getStatus() == DMP.DMPStatus.FINALISED.getValue(); + final boolean isPublic = dmp.isPublic(); dmp.setDataset(dmp.getDataset().stream() .filter(dataset -> dataset.getStatus() != Dataset.Status.DELETED.getValue() && dataset.getStatus() != Dataset.Status.CANCELED.getValue()) @@ -1570,15 +1641,12 @@ public class DataManagementPlanManager { .collect(Collectors.toSet())); String result = rdaManager.convertToRDA(dmp); - /*ObjectMapper mapper = new ObjectMapper(); - mapper.setSerializationInclusion(JsonInclude.Include.NON_NULL);*/ - String fileName = "DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion();//dmp.getLabel(); + String fileName = "DMP_" + dmp.getGrant().getLabel() + "_" + dmp.getVersion(); fileName = fileName.replaceAll("[^a-zA-Z0-9+ ]", "").replace(" ", "_").replace(",", "_"); String uuid = UUID.randomUUID().toString(); File file = new File(this.environment.getProperty("temp.temp") + uuid + ".json"); OutputStream output = new FileOutputStream(file); try { -// mapper.writeValue(file, rdaExportModel); output.write(result.getBytes()); output.flush(); output.close(); @@ -1586,18 +1654,10 @@ public class DataManagementPlanManager { logger.error(e.getMessage(), e); } - InputStream resource = new FileInputStream(file); - HttpHeaders responseHeaders = new HttpHeaders(); - responseHeaders.setContentLength(file.length()); - responseHeaders.setContentType(MediaType.APPLICATION_OCTET_STREAM); - responseHeaders.set("Content-Disposition", "attachment;filename=" + fileName + ".json"); - responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); - responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); - - byte[] content = org.apache.poi.util.IOUtils.toByteArray(resource); - resource.close(); - Files.deleteIfExists(file.toPath()); - return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); + FileEnvelope rdaJsonDocument = new FileEnvelope(); + rdaJsonDocument.setFilename(fileName + ".json"); + rdaJsonDocument.setFile(file); + return rdaJsonDocument; } public ResponseEntity getDocument(String id, String contentType, Principal principal, ConfigLoader configLoader) throws InstantiationException, IllegalAccessException, IOException { @@ -2041,100 +2101,6 @@ public class DataManagementPlanManager { return null; } - private String getUnpublishedDOI(String DOI, String token, Integer version) { - try { - RestTemplate restTemplate = new RestTemplate(); - HttpHeaders headers = new HttpHeaders(); - headers.setAccept(Collections.singletonList(MediaType.APPLICATION_JSON)); - headers.setContentType(MediaType.APPLICATION_JSON); - Map createResponse = null; - LinkedHashMap links = null; - LinkedHashMap metadata = null; - String listUrl = this.environment.getProperty("zenodo.url") + "deposit/depositions" + "?q=conceptdoi:\"" + DOI + "\"&access_token=" + token; - ResponseEntity listResponses = restTemplate.getForEntity(listUrl, Map[].class); - createResponse = listResponses.getBody()[0]; - metadata = (LinkedHashMap) createResponse.get("metadata"); - links = (LinkedHashMap) createResponse.get("links"); - - if (metadata.get("version").equals(version.toString())) { - return links.get("publish"); - } else { - return null; - } - }catch (Exception e) { - logger.warn(e.getMessage(), e); - return null; - } - } - - public String createZenodoDoi(UUID id, Principal principal) throws Exception { - return this.createZenodoDoi(id, principal, false); - } - - public String createZenodoDoi(UUID id, Principal principal, boolean update) throws Exception { - DMP dmp = this.apiContext.getOperationsContext().getDatabaseRepository().getDmpDao().find(id); - 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(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)) { - zenodoToken = principal.getZenodoToken(); - } - } catch (NonValidTokenException e) { - zenodoToken = this.environment.getProperty("zenodo.access_token"); - } - - 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(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)) @@ -2147,18 +2113,22 @@ public class DataManagementPlanManager { 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; + eu.eudat.depositinterface.models.FileEnvelope pdfEnvelope = new eu.eudat.depositinterface.models.FileEnvelope(); + pdfEnvelope.setFile(pdfFile); + pdfEnvelope.setFilename(name + ".pdf"); + eu.eudat.depositinterface.models.FileEnvelope rdaJsonFile = new eu.eudat.depositinterface.models.FileEnvelope(); try { - jsonFile = getRDAJsonDocument(depositRequest.getDmpId(), principal); + FileEnvelope rdaJsonDocument = getRDAJsonDocument(depositRequest.getDmpId(), principal); + rdaJsonFile.setFile(rdaJsonDocument.getFile()); + rdaJsonFile.setFilename(rdaJsonDocument.getFilename()); } catch (Exception e) { - throw e; + logger.error(e.getMessage(), 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); + DMPDepositModel dmpDepositModel = DMPToDepositMapper.fromDMP(dmp, pdfEnvelope, rdaJsonFile, supportingFilesZip, previousDOI); Optional repo = this.repositoriesDeposit.stream().filter(x -> x.getConfiguration().getRepositoryId().equals(depositRequest.getRepositoryId())).findFirst(); String finalDoi = repo.map(r -> { @@ -2192,10 +2162,12 @@ public class DataManagementPlanManager { if(supportingFilesZip != null) { Files.deleteIfExists(supportingFilesZip.toPath()); } + Files.deleteIfExists(rdaJsonFile.getFile().toPath()); Files.deleteIfExists(pdfFile.toPath()); Files.deleteIfExists(file.getFile().toPath()); return doiModel; + } private File createSupportingFilesZip(DMP dmp) throws IOException { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java index 298cfc37f..793f6382d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetManager.java @@ -1136,7 +1136,7 @@ public class DatasetManager { List tags = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().query(criteria).stream().map(eu.eudat.elastic.entities.Dataset::getTags).flatMap(Collection::stream).filter(StreamDistinctBy.distinctByKey(Tag::getId)).collect(Collectors.toList()); Set tagNodes = new HashSet<>(); tagNodes.addAll(JsonSearcher.findNodes(propertiesJson, "renderStyle", "tags", true)); - tagNodes.addAll(JsonSearcher.findNodes(propertiesJson, "rdaProperty", "dataset.keyword")); + tagNodes.addAll(JsonSearcher.findNodes(propertiesJson, "schematics", "rda.dataset.keyword")); if(wizardModel.getTags() == null){ wizardModel.setTags(new ArrayList<>()); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java index c34231f90..3786dddb2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/DatasetProfileManager.java @@ -10,13 +10,14 @@ import eu.eudat.data.query.items.item.datasetprofile.DatasetProfileAutocompleteR import eu.eudat.data.query.items.table.datasetprofile.DatasetProfileTableRequestItem; import eu.eudat.exceptions.datasetprofile.DatasetProfileNewVersionException; import eu.eudat.logic.builders.model.models.DataTableDataBuilder; +import eu.eudat.logic.proxy.config.Semantic; +import eu.eudat.logic.proxy.config.configloaders.ConfigLoader; import eu.eudat.logic.services.ApiContext; import eu.eudat.logic.services.operations.DatabaseRepository; import eu.eudat.logic.utilities.builders.XmlBuilder; import eu.eudat.logic.utilities.documents.helpers.FileEnvelope; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ExportXmlBuilderDatasetProfile; import eu.eudat.logic.utilities.documents.xml.datasetProfileXml.ImportXmlBuilderDatasetProfile; -import eu.eudat.logic.utilities.helpers.StreamDistinctBy; import eu.eudat.models.data.components.commons.datafield.AutoCompleteData; import eu.eudat.models.data.datasetprofile.DatasetProfileAutocompleteItem; import eu.eudat.models.data.datasetprofile.DatasetProfileListingModel; @@ -34,23 +35,27 @@ import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.env.Environment; import org.springframework.http.*; -import org.springframework.http.client.ClientHttpRequestFactory; import org.springframework.http.client.SimpleClientHttpRequestFactory; -import org.springframework.http.converter.HttpMessageConverter; -import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter; import org.springframework.stereotype.Component; import org.springframework.web.client.RestTemplate; import org.springframework.web.multipart.MultipartFile; import org.w3c.dom.Document; import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; import javax.activation.MimetypesFileTypeMap; import javax.transaction.Transactional; +import javax.xml.transform.OutputKeys; +import javax.xml.transform.Transformer; +import javax.xml.transform.TransformerException; +import javax.xml.transform.TransformerFactory; +import javax.xml.transform.dom.DOMSource; +import javax.xml.transform.stream.StreamResult; import javax.xml.xpath.*; import java.io.*; import java.nio.file.Files; import java.util.*; -import java.util.concurrent.CompletableFuture; import java.util.stream.Collectors; @@ -62,14 +67,16 @@ public class DatasetProfileManager { private ApiContext apiContext; private DatabaseRepository databaseRepository; private Environment environment; + private ConfigLoader configLoader; private final MetricsManager metricsManager; @Autowired - public DatasetProfileManager(ApiContext apiContext, Environment environment, MetricsManager metricsManager) { + public DatasetProfileManager(ApiContext apiContext, Environment environment, ConfigLoader configLoader, MetricsManager metricsManager) { this.apiContext = apiContext; this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); this.environment = environment; + this.configLoader = configLoader; this.metricsManager = metricsManager; } @@ -363,4 +370,79 @@ public class DatasetProfileManager { } } + + public List getSemantics(String query) { + List semantics = configLoader.getSemantics(); + List filteredSemantics = semantics.stream().map(Semantic::getName).collect(Collectors.toList()); + if(query != null && !query.isEmpty()){ + filteredSemantics = semantics.stream().filter(x -> x.getCategory().contains(query) || x.getName().contains(query)).map(Semantic::getName).collect(Collectors.toList()); + } + return filteredSemantics; + } + + public void addSemanticsInDatasetProfiles() throws XPathExpressionException { + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DatasetProfile dp: ids){ + DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + XPathExpression expr = xpath.compile("//rdaCommonStandard"); + NodeList rdaProperties = (NodeList) expr.evaluate(document, XPathConstants.NODESET); + for(int i = 0; i < rdaProperties.getLength(); i++){ + Node rdaPropertyNode = rdaProperties.item(i); + String rdaProperty = rdaPropertyNode.getTextContent(); + Element schematics = document.createElement("schematics"); + Node fieldParent = rdaPropertyNode.getParentNode(); + if(rdaProperty != null && !rdaProperty.isEmpty()){ + Element schematic = document.createElement("schematic"); + schematic.setTextContent("rda." + rdaProperty); + schematics.appendChild(schematic); + } + fieldParent.insertBefore(schematics, rdaPropertyNode); + fieldParent.removeChild(rdaPropertyNode); + } + this.updateDatasetProfileXml(document, datasetProfile); + } + } + + public void addRdaInSemanticsInDatasetProfiles() throws XPathExpressionException { + List ids = this.databaseRepository.getDatasetProfileDao().getAllIds(); + for(DatasetProfile dp: ids){ + DatasetProfile datasetProfile = this.databaseRepository.getDatasetProfileDao().find(dp.getId()); + Document document = XmlBuilder.fromXml(datasetProfile.getDefinition()); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + XPathExpression expr = xpath.compile("//schematic"); + NodeList schematics = (NodeList) expr.evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < schematics.getLength(); i++) { + Node schematicNode = schematics.item(i); + String schematicRda = schematicNode.getTextContent(); + if (schematicRda != null && !schematicRda.isEmpty() && !schematicRda.startsWith("rda.")) { + schematicNode.setTextContent("rda." + schematicRda); + } + } + this.updateDatasetProfileXml(document, datasetProfile); + } + } + + private void updateDatasetProfileXml(Document document, DatasetProfile datasetProfile) { + try { + DOMSource domSource = new DOMSource(document); + StringWriter writer = new StringWriter(); + StreamResult result = new StreamResult(writer); + TransformerFactory tf = TransformerFactory.newInstance(); + Transformer transformer = tf.newTransformer(); + transformer.setOutputProperty(OutputKeys.INDENT, "yes"); + transformer.transform(domSource, result); + String newDefinition = writer.toString(); + if(newDefinition != null){ + datasetProfile.setDefinition(newDefinition); + this.databaseRepository.getDatasetProfileDao().createOrUpdate(datasetProfile); + } + } + catch(TransformerException ex) { + logger.error(ex.getMessage(), ex); + } + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MaterialManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MaterialManager.java new file mode 100644 index 000000000..344fe24b3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/MaterialManager.java @@ -0,0 +1,51 @@ +package eu.eudat.logic.managers; + +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.http.HttpHeaders; +import org.springframework.http.HttpStatus; +import org.springframework.http.MediaType; +import org.springframework.http.ResponseEntity; +import org.springframework.stereotype.Component; + +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.List; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component +public class MaterialManager { + + @Autowired + public MaterialManager(){} + + public ResponseEntity getResponseEntity(String lang, Stream paths) throws IOException { + List result = paths.filter(Files::isRegularFile) + .map(Path::toString).collect(Collectors.toList()); + + String fileName = result.stream().filter(about -> about.contains("_" + lang)).findFirst().orElse(null); + if (fileName == null) { + fileName = result.stream().filter(about -> about.contains("_en")).findFirst().get(); + } + InputStream is = new FileInputStream(fileName); + + Path path = Paths.get(fileName); + + HttpHeaders responseHeaders = new HttpHeaders(); + responseHeaders.setContentLength(is.available()); + responseHeaders.setContentType(MediaType.TEXT_HTML); + responseHeaders.set("Content-Disposition", "attachment;filename=" + path.getFileName().toString()); + responseHeaders.set("Access-Control-Expose-Headers", "Content-Disposition"); + responseHeaders.get("Access-Control-Expose-Headers").add("Content-Type"); + + byte[] content = new byte[is.available()]; + is.read(content); + is.close(); + + return new ResponseEntity<>(content, responseHeaders, HttpStatus.OK); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java new file mode 100644 index 000000000..5785f1676 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UnlinkEmailConfirmationManager.java @@ -0,0 +1,106 @@ +package eu.eudat.logic.managers; + +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import eu.eudat.data.entities.Credential; +import eu.eudat.data.entities.EmailConfirmation; +import eu.eudat.data.entities.UserInfo; +import eu.eudat.data.entities.UserToken; +import eu.eudat.exceptions.emailconfirmation.HasConfirmedEmailException; +import eu.eudat.exceptions.emailconfirmation.TokenExpiredException; +import eu.eudat.logic.builders.entity.UserTokenBuilder; +import eu.eudat.logic.services.ApiContext; +import eu.eudat.logic.services.operations.DatabaseRepository; +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 javax.transaction.Transactional; +import java.sql.Timestamp; +import java.time.LocalDateTime; +import java.util.*; +import java.util.stream.Collectors; + +@Component +public class UnlinkEmailConfirmationManager { + + private static Logger logger = LoggerFactory.getLogger(UnlinkEmailConfirmationManager.class); + + private ApiContext apiContext; + private DatabaseRepository databaseRepository; + + @Autowired + public UnlinkEmailConfirmationManager(ApiContext apiContext) { + this.apiContext = apiContext; + this.databaseRepository = apiContext.getOperationsContext().getDatabaseRepository(); + } + + @Transactional + public void confirmEmail(String token) throws TokenExpiredException, HasConfirmedEmailException { + EmailConfirmation loginConfirmationEmail = apiContext.getOperationsContext() + .getDatabaseRepository().getLoginConfirmationEmailDao().asQueryable() + .where((builder, root) -> builder.equal(root.get("token"), UUID.fromString(token))).getSingle(); + + if (loginConfirmationEmail.getExpiresAt().compareTo(new Date()) < 0) + throw new TokenExpiredException("Token has expired."); + + if(loginConfirmationEmail.getIsConfirmed()) + throw new HasConfirmedEmailException("Email is already confirmed."); + +// UserInfo userAskingForUnlink = databaseRepository.getUserInfoDao().asQueryable() +// .where((builder, root) -> builder.equal(root.get("id"), loginConfirmationEmail.getUserId())).getSingle(); + + try { + Map map = new ObjectMapper().readValue(loginConfirmationEmail.getData(), new TypeReference>() {}); + String emailTobeUnlinked = (String) map.get("email"); + Integer provider = Integer.valueOf((String) map.get("provider")); + + unlinkUser(emailTobeUnlinked, provider); + + loginConfirmationEmail.setIsConfirmed(true); + databaseRepository.getLoginConfirmationEmailDao().createOrUpdate(loginConfirmationEmail); + } + catch (Exception e) { + logger.error(e.getMessage(), e); + } + } + + @Transactional + private void unlinkUser(String emailTobeUnlinked, Integer provider){ + Credential credential = databaseRepository.getCredentialDao().asQueryable() + .where((builder, root) -> builder.and(builder.equal(root.get("email"), emailTobeUnlinked), builder.equal(root.get("provider"), provider))).getSingle(); + if(credential != null) { + UserInfo userTobeUnlinked = databaseRepository.getUserInfoDao().asQueryable() + .where((builder, root) -> builder.and(builder.equal(root.get("userStatus"), 1), builder.equal(root.get("name"), credential.getPublicValue()))).getSingle(); + userTobeUnlinked.setEmail(emailTobeUnlinked); + userTobeUnlinked.setUserStatus((short) 0); + databaseRepository.getUserInfoDao().createOrUpdate(userTobeUnlinked); + + credential.setUserInfo(userTobeUnlinked); + databaseRepository.getCredentialDao().createOrUpdate(credential); + + UserToken userToken = this.apiContext.getOperationsContext().getBuilderFactory().getBuilder(UserTokenBuilder.class) + .token(UUID.randomUUID()).user(userTobeUnlinked) + .expiresAt(Timestamp.valueOf(LocalDateTime.now().plusDays(10))).issuedAt(new Date()) + .build(); + apiContext.getOperationsContext().getDatabaseRepository().getUserTokenDao().createOrUpdate(userToken); + } + } + + public void sendConfirmationEmail(String email, Principal principal, UUID userId, Integer provider) { + UserInfo user = apiContext.getOperationsContext().getDatabaseRepository().getUserInfoDao().find(principal.getId()); + + if (user.getEmail() != null && !user.getEmail().equals(email)) { + apiContext.getUtilitiesService().getConfirmationEmailService().createUnlinkConfirmationEmail( + databaseRepository.getLoginConfirmationEmailDao(), + apiContext.getUtilitiesService().getMailService(), + email, + userId, + principal, + provider + ); + } + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java index e7b00d0e6..3820bdfa7 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/managers/UserManager.java @@ -159,31 +159,10 @@ public class UserManager { return dataTableData; } - public Boolean isDOITokenValid(Principal principal) throws NonValidTokenException, ExpiredTokenException, IOException { - if (principal.getZenodoToken() != null && !principal.getZenodoToken().isEmpty()) { - if (Instant.now().isBefore(principal.getZenodoDuration())) { - return true; - } - try { - this.updateDOIToken(ZenodoAccessType.REFRESH_TOKEN, principal.getZenodoRefresh(), this.environment.getProperty("zenodo.login.redirect_uri"), principal); - return true; - }catch (Exception e) { - this.deleteDOIToken(principal); - throw new ExpiredTokenException("Zenodo Token is expired."); - } - } - throw new NonValidTokenException("This account has no Zenodo Token"); - } - public void registerDOIToken(DOIRequest doiRequest, Principal principal) throws IOException { - this.updateDOIToken(ZenodoAccessType.AUTHORIZATION_CODE, doiRequest.getZenodoRequest().getCode(), doiRequest.getRedirectUri(), principal); - } - - private void updateDOIToken(ZenodoAccessType accessType, String code, String redirectUri, Principal principal) throws IOException { - ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(accessType, code - , this.environment.getProperty("zenodo.login.client_id") - , this.environment.getProperty("zenodo.login.client_secret") - , redirectUri); + ZenodoResponseToken responseToken = this.zenodoCustomProvider.getAccessToken(ZenodoAccessType.AUTHORIZATION_CODE, + doiRequest.getZenodoRequest().getCode(), this.environment.getProperty("zenodo.login.client_id"), + this.environment.getProperty("zenodo.login.client_secret"), doiRequest.getRedirectUri()); Map settings = new HashMap<>(); settings.put("zenodoEmail", responseToken.getEmail()); settings.put("zenodoRefresh", responseToken.getRefreshToken()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java index 44b2f1be4..9efc1e713 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/mapper/prefilling/PrefillingMapper.java @@ -112,17 +112,17 @@ public class PrefillingMapper { throw e; } } else { - List nodes = JsonSearcher.findNodes(parentNode, "rdaProperty", prefillingMapping.getMaDmpTarget()); + List nodes = JsonSearcher.findNodes(parentNode, "schematics", "rda." + prefillingMapping.getMaDmpTarget()); // zenodo prefilling customizations if(type.equals("zenodo")){ if(prefillingMapping.getMaDmpTarget().equals("dataset.distribution.data_access")){ if(parsedValue != null && parsedValue.equals("open")){ - List issuedNodes = JsonSearcher.findNodes(parentNode, "rdaProperty", "dataset.issued"); + List issuedNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.issued"); if(!issuedNodes.isEmpty()){ String issuedIdNode = issuedNodes.get(0).get("id").asText(); String issuedValue = (String) properties.get(issuedIdNode); - List licStartDateNodes = JsonSearcher.findNodes(parentNode, "rdaProperty", "dataset.distribution.license.start_date"); + List licStartDateNodes = JsonSearcher.findNodes(parentNode, "schematics", "rda.dataset.distribution.license.start_date"); for (JsonNode licStartDateNode : licStartDateNodes) { String licStartDateId = licStartDateNode.get(0) != null ? licStartDateNode.get(0).get("id").asText() : licStartDateNode.get("id").asText(); properties.put(licStartDateId, issuedValue); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java index e027714ed..d629a1503 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/DataFieldsUrlConfiguration.java @@ -8,6 +8,8 @@ import javax.xml.bind.annotation.XmlElement; public class DataFieldsUrlConfiguration { private String id; private String name; + private String pid; + private String pidTypeField; private String uri; private String description; private String source; @@ -36,6 +38,23 @@ public class DataFieldsUrlConfiguration { this.name = name; } + public String getPid() { + return pid; + } + + @XmlElement(name = "pid") + public void setPid(String pid) { + this.pid = pid; + } + + public String getPidTypeField() { + return pidTypeField; + } + + @XmlElement(name = "pidTypeField") + public void setPidTypeField(String pidTypeField) { + this.pidTypeField = pidTypeField; + } public String getUri() { return uri; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/Semantic.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/Semantic.java new file mode 100644 index 000000000..bd7d717d2 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/config/Semantic.java @@ -0,0 +1,25 @@ +package eu.eudat.logic.proxy.config; + +import com.fasterxml.jackson.annotation.JsonProperty; + +public class Semantic { + + @JsonProperty("category") + private String category; + @JsonProperty("name") + private String name; + + public String getCategory() { + return category; + } + public void setCategory(String category) { + this.category = category; + } + + public String getName() { + return name; + } + public void setName(String name) { + this.name = name; + } +} 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 175442eda..f253f5c12 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,7 @@ package eu.eudat.logic.proxy.config.configloaders; import eu.eudat.logic.proxy.config.ExternalUrls; +import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; import org.apache.poi.xwpf.usermodel.XWPFDocument; @@ -9,7 +10,7 @@ import java.util.Map; public interface ConfigLoader { ExternalUrls getExternalUrls(); - List getRdaProperties(); + List getSemantics(); XWPFDocument getDocument(); XWPFDocument getDatasetDocument(); ConfigurableProviders getConfigurableProviders(); 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 36c6d3ac3..4faa489d9 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 @@ -1,8 +1,10 @@ package eu.eudat.logic.proxy.config.configloaders; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.DeserializationFeature; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.logic.proxy.config.ExternalUrls; +import eu.eudat.logic.proxy.config.Semantic; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.ConfigurableProviders; import org.apache.poi.xwpf.usermodel.XWPFDocument; import org.slf4j.Logger; @@ -35,7 +37,7 @@ public class DefaultConfigLoader implements ConfigLoader { private static final ObjectMapper mapper = new ObjectMapper(); private ExternalUrls externalUrls; - private List rdaProperties; + private List semantics; private XWPFDocument document; private XWPFDocument datasetDocument; private ConfigurableProviders configurableProviders; @@ -64,24 +66,17 @@ public class DefaultConfigLoader implements ConfigLoader { } } - private void setRdaProperties() { - String filePath = environment.getProperty("configuration.rda"); + private void setSemantics() { + String filePath = environment.getProperty("configuration.semantics"); logger.info("Loaded also config file: " + filePath); - BufferedReader reader; - List rdaList = new LinkedList<>(); - try { - reader = new BufferedReader(new InputStreamReader(getStreamFromPath(filePath))); - String line = reader.readLine(); - while (line != null) { - rdaList.add(line); - line = reader.readLine(); + if (filePath != null) { + try { + semantics = mapper.readValue(getStreamFromPath(filePath), new TypeReference>(){}); + } + catch (IOException e) { + logger.error(e.getMessage(), e); } - reader.close(); - } catch (IOException | NullPointerException e) { - logger.error(e.getMessage(), e); } - - rdaProperties = rdaList; } private void setDocument() { @@ -171,12 +166,12 @@ public class DefaultConfigLoader implements ConfigLoader { return externalUrls; } - public List getRdaProperties() { - if (rdaProperties == null) { - rdaProperties = new ArrayList<>(); - this.setRdaProperties(); + public List getSemantics() { + if (semantics == null) { + semantics = new ArrayList<>(); + this.setSemantics(); } - return rdaProperties; + return semantics; } public XWPFDocument getDocument() { diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java index 911493f29..6b9a8b9b5 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcher.java @@ -467,7 +467,14 @@ public class RemoteFetcher { } private String transformKey(DataUrlConfiguration dataUrlConfiguration, String key) { - if (dataUrlConfiguration.getFieldsUrlConfiguration().getId() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getId().replace("'",""))) return "pid"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getId() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getId().replace("'",""))) { + if(dataUrlConfiguration.getFieldsUrlConfiguration().getPid() == null) + return "pid"; + else + return "originalId"; + } + if (dataUrlConfiguration.getFieldsUrlConfiguration().getPid() != null && key.equals("pid")) return "pid"; + if (dataUrlConfiguration.getFieldsUrlConfiguration().getPidTypeField() != null && key.equals("pidTypeField")) return "pidTypeField"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getDescription() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getDescription().replace("'",""))) return "description"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getUri() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getUri().replace("'",""))) return "uri"; if (dataUrlConfiguration.getFieldsUrlConfiguration().getName() != null && key.equals(dataUrlConfiguration.getFieldsUrlConfiguration().getName().replace("'",""))) return "name"; diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java index 56f256254..20c57356d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/proxy/fetching/RemoteFetcherUtils.java @@ -1,11 +1,15 @@ package eu.eudat.logic.proxy.fetching; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.ObjectMapper; import com.jayway.jsonpath.Configuration; import com.jayway.jsonpath.DocumentContext; +import com.jayway.jsonpath.JsonPath; import com.jayway.jsonpath.spi.json.JacksonJsonProvider; import eu.eudat.logic.proxy.config.DataUrlConfiguration; import eu.eudat.logic.proxy.config.ExternalUrlCriteria; import eu.eudat.logic.proxy.fetching.entities.Results; +import io.swagger.models.auth.In; import net.minidev.json.JSONArray; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -17,6 +21,7 @@ import java.util.stream.Collectors; public class RemoteFetcherUtils { private final static Logger logger = LoggerFactory.getLogger(RemoteFetcherUtils.class); + private static final ObjectMapper mapper = new ObjectMapper(); public static Results getFromJson(DocumentContext jsonContext, DataUrlConfiguration jsonDataPath) { return new Results(parseData(jsonContext, jsonDataPath), @@ -60,9 +65,36 @@ public class RemoteFetcherUtils { try { String value = ((String) getterMethod.invoke(jsonDataPath.getFieldsUrlConfiguration())); if (value != null) { - value = value.replace("'", ""); - if (stringObjectMap.containsKey(value)) { - parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + if (field.getName().equals("pid") || field.getName().equals("pidTypeField")) { + String pid = null; + Object pidObj = stringObjectMap.get(value.split("\\.")[0]); + if(pidObj != null){ + if(pidObj instanceof Map){ + pid = ((Map) pidObj).get(value.split("\\.")[1]); + } + else if(pidObj instanceof List){ + Object o = ((List>) pidObj).get(0).get(value.split("\\.")[1]); + if(o instanceof String){ + pid = (String)o; + } + else if(o instanceof Integer){ + pid = String.valueOf(o); + } + } + } + if(pid != null) { + if ((field.getName().equals("pid"))){ + parsedData.get(parsedData.size() - 1).put("pid", pid); + } + else{ + parsedData.get(parsedData.size() - 1).put("pidTypeField", pid); + } + } + } else { + value = value.replace("'", ""); + if (stringObjectMap.containsKey(value)) { + parsedData.get(parsedData.size() - 1).put(field.getName().equals("types") ? "tags" : value, normalizeValue(stringObjectMap.get(value), (field.getName().equals("types") || field.getName().equals("uri")))); + } } } } catch (IllegalAccessException | InvocationTargetException e) { @@ -84,7 +116,15 @@ public class RemoteFetcherUtils { } else { for (Object o : jarr) { if ((o instanceof Map) && ((Map) o).containsKey("content")) { - return ((Map) o).get("content"); + try { + return ((Map) o).get("content"); + } + catch (ClassCastException e){ + if(((Map) o).get("content") instanceof Integer) { + return String.valueOf(((Map) o).get("content")); + } + return null; + } } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/CertificateInfo.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/CertificateInfo.java new file mode 100644 index 000000000..fbbd333d3 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/CertificateInfo.java @@ -0,0 +1,68 @@ +package eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2; + +import com.fasterxml.jackson.annotation.JsonValue; + +public class CertificateInfo { + + public enum KeyFormat { + JKS("JKS"), PKCS12("PKCS12"); + + private String type; + KeyFormat(String type) { + this.type = type; + } + @JsonValue + public String getType() { return type; } + + public static KeyFormat fromType(String type) { + for (KeyFormat t: KeyFormat.values()) { + if (type.equals(t.getType())) { + return t; + } + } + throw new IllegalArgumentException("Unsupported Keystore format " + type); + } + } + + private String alias; + private String password; + private String keystorePath; + private String keystorePassword; + private KeyFormat keyFormat; + + public String getAlias() { + return alias; + } + public void setAlias(String alias) { + this.alias = alias; + } + + public String getPassword() { + return password; + } + public void setPassword(String password) { + this.password = password; + } + + public String getKeystorePath() { + return keystorePath; + } + public void setKeystorePath(String keystorePath) { + this.keystorePath = keystorePath; + } + + public String getKeystorePassword() { + return keystorePassword; + } + public void setKeystorePassword(String keystorePassword) { + this.keystorePassword = keystorePassword; + } + + public KeyFormat getKeyFormat() { + return keyFormat; + } + public void setKeyFormat(KeyFormat keyFormat) { + this.keyFormat = keyFormat; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/Saml2ConfigurableProvider.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/Saml2ConfigurableProvider.java index ed3ddfbf7..3280e1575 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/Saml2ConfigurableProvider.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/customproviders/ConfigurableProvider/entities/saml2/Saml2ConfigurableProvider.java @@ -47,49 +47,24 @@ public class Saml2ConfigurableProvider extends ConfigurableProvider { } } - public enum KeyFormat { - JKS("JKS"), PKCS12("PKCS12"); - - private String type; - KeyFormat(String type) { - this.type = type; - } - @JsonValue - public String getType() { return type; } - - public static KeyFormat fromType(String type) { - for (KeyFormat t: KeyFormat.values()) { - if (type.equals(t.getType())) { - return t; - } - } - throw new IllegalArgumentException("Unsupported Keystore format " + type); - } - } - private String spEntityId; private String idpEntityId; private String idpUrl; private String idpArtifactUrl; private String idpMetadataUrl; private boolean assertionEncrypted; - private KeyFormat keyFormat; - private String keyAlias; - private String credentialPath; - private String archivePassword; - private String keyPassword; + private CertificateInfo encryptionCert; + private CertificateInfo signingCert; private boolean responseSigned; private boolean assertionSigned; private boolean signatureRequired; - private String signatureKeyAlias; - private String signaturePath; - private String signatureKeyStorePassword; - private String signatureKeyPassword; private SAML2UsingFormat usingFormat; private Map attributeTypes; private Map configurableUserFromAttributes; private String binding; private String assertionConsumerServiceUrl; + private boolean wantAssertionsSigned; + private boolean authnRequestsSigned; public String getSpEntityId() { return spEntityId; @@ -133,39 +108,18 @@ public class Saml2ConfigurableProvider extends ConfigurableProvider { this.assertionEncrypted = assertionEncrypted; } - public KeyFormat getKeyFormat() { - return keyFormat; + public CertificateInfo getEncryptionCert() { + return encryptionCert; } - public void setKeyFormat(KeyFormat keyFormat) { - this.keyFormat = keyFormat; + public void setEncryptionCert(CertificateInfo encryptionCert) { + this.encryptionCert = encryptionCert; } - public String getKeyAlias() { - return keyAlias; + public CertificateInfo getSigningCert() { + return signingCert; } - public void setKeyAlias(String keyAlias) { - this.keyAlias = keyAlias; - } - - public String getCredentialPath() { - return credentialPath; - } - public void setCredentialPath(String credentialPath) { - this.credentialPath = credentialPath; - } - - public String getArchivePassword() { - return archivePassword; - } - public void setArchivePassword(String archivePassword) { - this.archivePassword = archivePassword; - } - - public String getKeyPassword() { - return keyPassword; - } - public void setKeyPassword(String keyPassword) { - this.keyPassword = keyPassword; + public void setSigningCert(CertificateInfo signingCert) { + this.signingCert = signingCert; } public boolean isResponseSigned() { @@ -189,34 +143,6 @@ public class Saml2ConfigurableProvider extends ConfigurableProvider { this.signatureRequired = signatureRequired; } - public String getSignatureKeyAlias() { - return signatureKeyAlias; - } - public void setSignatureKeyAlias(String signatureKeyAlias) { - this.signatureKeyAlias = signatureKeyAlias; - } - - public String getSignaturePath() { - return signaturePath; - } - public void setSignaturePath(String signaturePath) { - this.signaturePath = signaturePath; - } - - public String getSignatureKeyStorePassword() { - return signatureKeyStorePassword; - } - public void setSignatureKeyStorePassword(String signatureKeyStorePassword) { - this.signatureKeyStorePassword = signatureKeyStorePassword; - } - - public String getSignatureKeyPassword() { - return signatureKeyPassword; - } - public void setSignatureKeyPassword(String signatureKeyPassword) { - this.signatureKeyPassword = signatureKeyPassword; - } - public SAML2UsingFormat getUsingFormat() { return usingFormat; } @@ -252,4 +178,17 @@ public class Saml2ConfigurableProvider extends ConfigurableProvider { this.assertionConsumerServiceUrl = assertionConsumerServiceUrl; } + public boolean isWantAssertionsSigned() { + return wantAssertionsSigned; + } + public void setWantAssertionsSigned(boolean wantAssertionsSigned) { + this.wantAssertionsSigned = wantAssertionsSigned; + } + + public boolean isAuthnRequestsSigned() { + return authnRequestsSigned; + } + public void setAuthnRequestsSigned(boolean authnRequestsSigned) { + this.authnRequestsSigned = authnRequestsSigned; + } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java index 2997f534c..b6f1cc533 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/repositorydeposit/mapper/DMPToDepositMapper.java @@ -1,29 +1,46 @@ package eu.eudat.logic.security.repositorydeposit.mapper; +import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.databind.JsonMappingException; +import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.entities.*; import eu.eudat.depositinterface.models.*; -import org.springframework.http.ResponseEntity; +import eu.eudat.logic.utilities.builders.XmlBuilder; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import javax.xml.xpath.*; import java.io.File; +import java.util.ArrayList; +import java.util.HashMap; +import java.util.List; +import java.util.Map; import java.util.stream.Collectors; public class DMPToDepositMapper { - public static DMPDepositModel fromDMP(DMP entity, File pdfFile, String fileName, ResponseEntity jsonFile, File supportingFilesZip, String previousDOI) { + private static final Logger logger = LoggerFactory.getLogger(DMPToDepositMapper.class); + private static final ObjectMapper mapper = new ObjectMapper(); + + public static DMPDepositModel fromDMP(DMP entity, FileEnvelope pdfFile, FileEnvelope 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.setDatasets(entity.getDataset().stream().map(DMPToDepositMapper::fromDataset).collect(Collectors.toList())); 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.setRdaJsonFile(jsonFile); deposit.setSupportingFilesZip(supportingFilesZip); deposit.setPreviousDOI(previousDOI); @@ -31,6 +48,70 @@ public class DMPToDepositMapper { return deposit; } + private static DatasetDepositModel fromDataset(Dataset entity){ + DatasetDepositModel deposit = new DatasetDepositModel(); + deposit.setLabel(entity.getLabel()); + deposit.setDescription(entity.getDescription()); + deposit.setProfileDefinition(entity.getProfile().getDefinition()); + deposit.setProperties(entity.getProperties()); + deposit.setFields(fromDefinitionAndProperties(deposit.getProfileDefinition(), deposit.getProperties())); + return deposit; + } + + private static List fromDefinitionAndProperties(String definition, String properties){ + List deposit = new ArrayList<>(); + try { + + Map datasetAnswers = mapper.readValue(properties, HashMap.class); + + Document document = XmlBuilder.fromXml(definition); + XPathFactory xpathFactory = XPathFactory.newInstance(); + XPath xpath = xpathFactory.newXPath(); + XPathExpression expr = xpath.compile("//schematics"); + NodeList schematics = (NodeList) expr.evaluate(document, XPathConstants.NODESET); + for (int i = 0; i < schematics.getLength(); i++) { + Node schematicsNode = schematics.item(i); + NodeList schematicsList = schematicsNode.getChildNodes(); + DatasetFieldsDepositModel fieldDeposit = new DatasetFieldsDepositModel(); + List schematicsDeposit = new ArrayList<>(); + if(schematicsList != null){ + for(int j = 0; j < schematicsList.getLength(); j++){ + Node schematic = schematicsList.item(j); + if(schematic.getTextContent().matches(".*\\w+.*")) { + schematicsDeposit.add(schematic.getTextContent()); + } + } + } + fieldDeposit.setSchematics(schematicsDeposit); + String fieldId = schematicsNode.getParentNode().getAttributes().getNamedItem("id").getNodeValue(); + Object value = datasetAnswers.get(fieldId); + fieldDeposit.setValue(value); + Element field = (Element) schematicsNode.getParentNode(); + Element viewStyle = (Element) field.getElementsByTagName("viewStyle").item(0); + String renderStyle = viewStyle.getAttribute("renderstyle"); + fieldDeposit.setRenderStyleType(renderStyle); + Element data = (Element) field.getElementsByTagName("data").item(0); + String multipleSelection = data.getAttribute("multiList"); + String multipleAutoComplete = data.getAttribute("multiAutoComplete"); + if(!multipleSelection.isEmpty()){ + fieldDeposit.setMultiple(Boolean.parseBoolean(multipleSelection)); + } + else if(!multipleAutoComplete.isEmpty()){ + fieldDeposit.setMultiple(Boolean.parseBoolean(multipleAutoComplete)); + } + else{ + fieldDeposit.setMultiple(false); + } + deposit.add(fieldDeposit); + } + } + catch (XPathExpressionException | JsonProcessingException ex){ + logger.error(ex.getMessage(), ex); + return null; + } + return deposit; + } + private static UserDMPDepositModel fromUserDMP(UserDMP entity){ UserDMPDepositModel deposit = new UserDMPDepositModel(); deposit.setUser(fromUserInfo(entity.getUser())); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java index b6f413dc6..5f31b65a2 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/security/validators/configurableProvider/Saml2SSOUtils.java @@ -1,6 +1,8 @@ package eu.eudat.logic.security.validators.configurableProvider; +import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.CertificateInfo; import eu.eudat.logic.security.customproviders.ConfigurableProvider.entities.saml2.Saml2ConfigurableProvider; +import eu.eudat.logic.utilities.builders.XmlBuilder; import jakarta.xml.soap.*; import net.shibboleth.utilities.java.support.component.ComponentInitializationException; import net.shibboleth.utilities.java.support.resolver.CriteriaSet; @@ -32,6 +34,7 @@ import org.opensaml.core.xml.config.XMLObjectProviderRegistry; import org.opensaml.core.xml.io.*; import org.opensaml.core.xml.schema.*; import org.opensaml.saml.common.SAMLObject; +import org.opensaml.saml.common.SAMLObjectContentReference; import org.opensaml.saml.common.SAMLVersion; import org.opensaml.saml.common.xml.SAMLConstants; import org.opensaml.saml.criterion.EntityRoleCriterion; @@ -40,7 +43,7 @@ import org.opensaml.saml.metadata.resolver.impl.HTTPMetadataResolver; import org.opensaml.saml.metadata.resolver.impl.PredicateRoleDescriptorResolver; import org.opensaml.saml.saml2.core.*; import org.opensaml.saml.saml2.encryption.Decrypter; -import org.opensaml.saml.saml2.metadata.IDPSSODescriptor; +import org.opensaml.saml.saml2.metadata.*; import org.opensaml.saml.security.impl.MetadataCredentialResolver; import org.opensaml.security.credential.Credential; import org.opensaml.security.credential.CredentialSupport; @@ -55,10 +58,14 @@ import org.opensaml.xml.util.Base64; import org.opensaml.xmlsec.config.impl.DefaultSecurityConfigurationBootstrap; import org.opensaml.xmlsec.encryption.EncryptedKey; import org.opensaml.xmlsec.keyinfo.KeyInfoCredentialResolver; +import org.opensaml.xmlsec.keyinfo.KeyInfoGenerator; import org.opensaml.xmlsec.keyinfo.impl.StaticKeyInfoCredentialResolver; +import org.opensaml.xmlsec.keyinfo.impl.X509KeyInfoGeneratorFactory; import org.opensaml.xmlsec.signature.KeyInfo; import org.opensaml.xmlsec.signature.Signature; import org.opensaml.xmlsec.signature.X509Data; +import org.opensaml.xmlsec.signature.impl.SignatureBuilder; +import org.opensaml.xmlsec.signature.support.SignatureConstants; import org.opensaml.xmlsec.signature.support.SignatureValidator; import org.opensaml.xmlsec.signature.support.Signer; import org.slf4j.Logger; @@ -85,6 +92,7 @@ import java.net.UnknownHostException; import java.nio.charset.StandardCharsets; import java.security.*; import java.security.cert.CertificateEncodingException; +import java.security.cert.CertificateException; import java.security.cert.X509Certificate; import java.time.Instant; import java.util.*; @@ -264,7 +272,7 @@ public class Saml2SSOUtils { ArtifactResolve artifactResolve = createArtifactResolveObject(samlArtReceived, saml2Provider.getSpEntityId()); if (saml2Provider.isSignatureRequired()) { - signArtifactResolveReq(artifactResolve, saml2Provider); + signArtifactResolveReq(artifactResolve, saml2Provider.getSigningCert()); } return artifactResolve; @@ -290,14 +298,14 @@ public class Saml2SSOUtils { } - private static void signArtifactResolveReq(ArtifactResolve artifactResolve, Saml2ConfigurableProvider saml2Provider) throws Exception { + private static void signArtifactResolveReq(ArtifactResolve artifactResolve, CertificateInfo singingCertificateInfo) throws Exception { try { KeyStore ks = KeyStore.getInstance("JKS"); - String archivePassword = saml2Provider.getSignatureKeyStorePassword(); + String archivePassword = singingCertificateInfo.getKeystorePassword(); char[] pwdArray = (archivePassword != null) ? archivePassword.toCharArray() : "changeit".toCharArray(); - ks.load(new FileInputStream(saml2Provider.getSignaturePath()), pwdArray); - X509Credential cred = new KeyStoreX509CredentialAdapter(ks, saml2Provider.getSignatureKeyAlias(), saml2Provider.getSignatureKeyPassword().toCharArray()); + ks.load(new FileInputStream(singingCertificateInfo.getKeystorePath()), pwdArray); + X509Credential cred = new KeyStoreX509CredentialAdapter(ks, singingCertificateInfo.getAlias(), singingCertificateInfo.getPassword().toCharArray()); Signature signature = setSignatureRaw(XMLSignature.ALGO_ID_SIGNATURE_RSA, cred); artifactResolve.setSignature(signature); @@ -541,7 +549,7 @@ public class Saml2SSOUtils { if (!CollectionUtils.isEmpty(encryptedAssertions)) { encryptedAssertion = encryptedAssertions.get(0); try { - assertion = getDecryptedAssertion(encryptedAssertion, saml2Provider); + assertion = getDecryptedAssertion(encryptedAssertion, saml2Provider.getEncryptionCert()); } catch (Exception e) { throw new Exception("Unable to decrypt the SAML2 Assertion"); } @@ -601,15 +609,15 @@ public class Saml2SSOUtils { } - private static Assertion getDecryptedAssertion(EncryptedAssertion encryptedAssertion, Saml2ConfigurableProvider saml2Provider) throws Exception { + private static Assertion getDecryptedAssertion(EncryptedAssertion encryptedAssertion, CertificateInfo encryptionCertificateInfo) throws Exception { try { - KeyStore ks = (saml2Provider.getKeyFormat().getType().equals("JKS")) ? KeyStore.getInstance("JKS") : KeyStore.getInstance("PKCS12"); - String archivePassword = saml2Provider.getArchivePassword(); + KeyStore ks = (encryptionCertificateInfo.getKeyFormat().getType().equals("JKS")) ? KeyStore.getInstance("JKS") : KeyStore.getInstance("PKCS12"); + String archivePassword = encryptionCertificateInfo.getKeystorePassword(); char[] pwdArray = (archivePassword != null) ? archivePassword.toCharArray() : "changeit".toCharArray(); - ks.load(new FileInputStream(saml2Provider.getCredentialPath()), pwdArray); - X509Certificate cert = (X509Certificate)ks.getCertificate(saml2Provider.getKeyAlias()); - PrivateKey pk = (PrivateKey) ks.getKey(saml2Provider.getKeyAlias(), saml2Provider.getKeyPassword().toCharArray()); + ks.load(new FileInputStream(encryptionCertificateInfo.getKeystorePath()), pwdArray); + X509Certificate cert = (X509Certificate)ks.getCertificate(encryptionCertificateInfo.getAlias()); + PrivateKey pk = (PrivateKey) ks.getKey(encryptionCertificateInfo.getAlias(), encryptionCertificateInfo.getPassword().toCharArray()); KeyInfoCredentialResolver keyResolver = new StaticKeyInfoCredentialResolver( new BasicX509Credential(cert, pk)); EncryptedKey key = encryptedAssertion.getEncryptedData().getKeyInfo().getEncryptedKeys().get(0); @@ -685,4 +693,186 @@ public class Saml2SSOUtils { } } + private static Credential getCredential(CertificateInfo certificateInfo) throws KeyStoreException, IOException, CertificateException, NoSuchAlgorithmException, UnrecoverableKeyException { + KeyStore ks = (certificateInfo.getKeyFormat().getType().equals("JKS")) ? KeyStore.getInstance("JKS") : KeyStore.getInstance("PKCS12"); + String archivePassword = certificateInfo.getKeystorePassword(); + char[] pwdArray = (archivePassword != null) ? archivePassword.toCharArray() : "changeit".toCharArray(); + ks.load(new FileInputStream(certificateInfo.getKeystorePath()), pwdArray); + X509Certificate cert = (X509Certificate)ks.getCertificate(certificateInfo.getAlias()); + PrivateKey pk = (PrivateKey) ks.getKey(certificateInfo.getAlias(), certificateInfo.getPassword().toCharArray()); + return new BasicX509Credential(cert, pk); + } + + public static String getMetadata(Saml2ConfigurableProvider provider) throws Exception { + + EntityDescriptor spEntityDescriptor = (EntityDescriptor) buildXMLObject(EntityDescriptor.DEFAULT_ELEMENT_NAME); + spEntityDescriptor.setEntityID(provider.getSpEntityId()); + SPSSODescriptor spSSODescriptor = (SPSSODescriptor) buildXMLObject(SPSSODescriptor.DEFAULT_ELEMENT_NAME); + + spSSODescriptor.setWantAssertionsSigned(provider.isWantAssertionsSigned()); spSSODescriptor.setAuthnRequestsSigned(provider.isAuthnRequestsSigned()); + + X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); + keyInfoGeneratorFactory.setEmitEntityCertificate(true); + KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); + + if (provider.isAssertionEncrypted()) { + + KeyDescriptor encKeyDescriptor = (KeyDescriptor) buildXMLObject(KeyDescriptor.DEFAULT_ELEMENT_NAME); + + encKeyDescriptor.setUse(UsageType.ENCRYPTION); //Set usage + + // Generating key info. The element will contain the public key. The key is used to by the IDP to encrypt data + try { + encKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(getCredential(provider.getEncryptionCert()))); + } catch (SecurityException e) { + logger.error(e.getMessage(), e); + } + + spSSODescriptor.getKeyDescriptors().add(encKeyDescriptor); + + } + + if (provider.isWantAssertionsSigned()) { + + KeyDescriptor signKeyDescriptor = (KeyDescriptor) buildXMLObject(KeyDescriptor.DEFAULT_ELEMENT_NAME); + + signKeyDescriptor.setUse(UsageType.SIGNING); //Set usage + + // Generating key info. The element will contain the public key. The key is used to by the IDP to verify signatures + try { + signKeyDescriptor.setKeyInfo(keyInfoGenerator.generate(getCredential(provider.getSigningCert()))); + } catch (SecurityException e) { + logger.error(e.getMessage(), e); + } + + spSSODescriptor.getKeyDescriptors().add(signKeyDescriptor); + + } + + NameIDFormat nameIDFormat = (NameIDFormat) buildXMLObject(NameIDFormat.DEFAULT_ELEMENT_NAME); + nameIDFormat.setFormat("urn:oasis:names:tc:SAML:2.0:nameid-format:transient"); + spSSODescriptor.getNameIDFormats().add(nameIDFormat); + + + AssertionConsumerService assertionConsumerService = (AssertionConsumerService) buildXMLObject(AssertionConsumerService.DEFAULT_ELEMENT_NAME); + assertionConsumerService.setIndex(0); + switch (provider.getBinding()) { + case "Redirect": + assertionConsumerService.setBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + break; + case "Artifact": + assertionConsumerService.setBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI); + break; + case "Post": + assertionConsumerService.setBinding(SAMLConstants.SAML2_POST_BINDING_URI); + break; + } + + assertionConsumerService.setLocation(provider.getAssertionConsumerServiceUrl()); + spSSODescriptor.getAssertionConsumerServices().add(assertionConsumerService); + + + spSSODescriptor.addSupportedProtocol(SAMLConstants.SAML20P_NS); + + spEntityDescriptor.getRoleDescriptors().add(spSSODescriptor); + + + String metadataXML = null; + try { + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + DocumentBuilder builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + Marshaller out = registry.getMarshallerFactory().getMarshaller(spEntityDescriptor); + out.marshall(spEntityDescriptor, document); + + metadataXML = XmlBuilder.generateXml(document); + } + catch (MarshallingException | ParserConfigurationException e) { + logger.error(e.getMessage(), e); + } + return metadataXML; + + } + + public static String getAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { + + AuthnRequest authnRequest = buildAuthnRequest(provider); + + String authnRequestXml = null; + DocumentBuilder builder; + DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); + try { + Signature signature = (Signature) buildXMLObject(Signature.DEFAULT_ELEMENT_NAME); + if(provider.isAuthnRequestsSigned()){ + + Credential credential = getCredential(provider.getSigningCert()); + signature.setSigningCredential(credential); + signature.setSignatureAlgorithm(SignatureConstants.ALGO_ID_SIGNATURE_RSA_SHA256); + signature.setCanonicalizationAlgorithm(SignatureConstants.ALGO_ID_C14N_EXCL_OMIT_COMMENTS); + + X509KeyInfoGeneratorFactory keyInfoGeneratorFactory = new X509KeyInfoGeneratorFactory(); + keyInfoGeneratorFactory.setEmitEntityCertificate(true); + KeyInfoGenerator keyInfoGenerator = keyInfoGeneratorFactory.newInstance(); + signature.setKeyInfo(keyInfoGenerator.generate(getCredential(provider.getSigningCert()))); + + authnRequest.setSignature(signature); + } + + builder = factory.newDocumentBuilder(); + Document document = builder.newDocument(); + Marshaller out = registry.getMarshallerFactory().getMarshaller(authnRequest); + out.marshall(authnRequest, document); + + if(provider.isAuthnRequestsSigned()) { + Signer.signObject(signature); + } + + authnRequestXml = XmlBuilder.generateXml(document); + + } + catch (MarshallingException | ParserConfigurationException e) { + logger.error(e.getMessage(), e); + } + return authnRequestXml; + + } + + private static AuthnRequest buildAuthnRequest(Saml2ConfigurableProvider provider) throws Exception { + AuthnRequest authnRequest = (AuthnRequest) buildXMLObject(AuthnRequest.DEFAULT_ELEMENT_NAME); + authnRequest.setIssueInstant(Instant.now()); + authnRequest.setDestination(provider.getIdpUrl()); + switch (provider.getBinding()) { + case "Redirect": + authnRequest.setProtocolBinding(SAMLConstants.SAML2_REDIRECT_BINDING_URI); + break; + case "Artifact": + authnRequest.setProtocolBinding(SAMLConstants.SAML2_ARTIFACT_BINDING_URI); + break; + case "Post": + authnRequest.setProtocolBinding(SAMLConstants.SAML2_POST_BINDING_URI); + break; + } + authnRequest.setAssertionConsumerServiceURL(provider.getAssertionConsumerServiceUrl()); + authnRequest.setID('_' + UUID.randomUUID().toString()); + authnRequest.setIssuer(buildIssuer(provider.getSpEntityId())); + authnRequest.setNameIDPolicy(buildNameIdPolicy()); + + return authnRequest; + } + + private static NameIDPolicy buildNameIdPolicy() throws Exception { + NameIDPolicy nameIDPolicy = (NameIDPolicy) buildXMLObject(NameIDPolicy.DEFAULT_ELEMENT_NAME); + nameIDPolicy.setAllowCreate(true); + nameIDPolicy.setFormat(NameIDType.TRANSIENT); + + return nameIDPolicy; + } + + private static Issuer buildIssuer(String spEntityId) throws Exception { + Issuer issuer = (Issuer) buildXMLObject(Issuer.DEFAULT_ELEMENT_NAME); + issuer.setValue(spEntityId); + + return issuer; + } + } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailService.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailService.java index 108550ec5..dfb712d0f 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailService.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailService.java @@ -12,7 +12,11 @@ public interface ConfirmationEmailService { public void createMergeConfirmationEmail(EmailConfirmationDao loginConfirmationEmailDao, MailService mailService, String email, UUID userId, Principal principal, Integer provider); + public void createUnlinkConfirmationEmail(EmailConfirmationDao loginConfirmationEmailDao, MailService mailService, String email, UUID userId, Principal principal, Integer provider); + public CompletableFuture sentConfirmationEmail(EmailConfirmation confirmationEmail, MailService mailService); public CompletableFuture sentMergeConfirmationEmail(EmailConfirmation confirmationEmail, MailService mailService, String userName); + + public CompletableFuture sentUnlinkConfirmationEmail(EmailConfirmation confirmationEmail, MailService mailService); } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailServiceImpl.java b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailServiceImpl.java index f089d15c0..52400bc01 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailServiceImpl.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/services/utilities/ConfirmationEmailServiceImpl.java @@ -1,6 +1,7 @@ package eu.eudat.logic.services.utilities; import com.fasterxml.jackson.core.JsonProcessingException; +import com.fasterxml.jackson.core.type.TypeReference; import com.fasterxml.jackson.databind.ObjectMapper; import eu.eudat.data.dao.entities.EmailConfirmationDao; import eu.eudat.data.entities.EmailConfirmation; @@ -84,6 +85,30 @@ public class ConfirmationEmailServiceImpl implements ConfirmationEmailService { }); } + @Override + public CompletableFuture sentUnlinkConfirmationEmail(EmailConfirmation confirmationEmail, MailService mailService) { + String email = null; + try { + Map map = new ObjectMapper().readValue(confirmationEmail.getData(), new TypeReference>() {}); + email = (String) map.get("email"); + } + catch (JsonProcessingException e){ + logger.error(e.getMessage(), e); + } + String finalEmail = email; + return CompletableFuture.runAsync(() -> { + SimpleMail mail = new SimpleMail(); + mail.setSubject(environment.getProperty("conf_email.subject")); + mail.setContent(createUnlinkContent(confirmationEmail.getToken(), mailService, finalEmail)); + mail.setTo(confirmationEmail.getEmail()); + try { + mailService.sendSimpleMail(mail); + } catch (Exception ex) { + logger.error(ex.getMessage(), ex); + } + }); + } + private String createMergeContent(UUID confirmationToken, MailService mailService, String userName) { String content = mailService.getMailTemplateContent(this.environment.getProperty("email.merge")); content = content.replace("{userName}", userName); @@ -94,6 +119,16 @@ public class ConfirmationEmailServiceImpl implements ConfirmationEmailService { return content; } + private String createUnlinkContent(UUID confirmationToken, MailService mailService, String email) { + String content = mailService.getMailTemplateContent(this.environment.getProperty("email.unlink")); + content = content.replace("{confirmationToken}", confirmationToken.toString()); + content = content.replace("{expiration_time}", secondsToTime(Integer.parseInt(this.environment.getProperty("conf_email.expiration_time_seconds")))); + content = content.replace("{host}", this.environment.getProperty("dmp.domain")); + content = content.replace("{email}", email); + + return content; + } + private String secondsToTime(int seconds) { int sec = seconds % 60; int hour = seconds / 60; @@ -128,4 +163,30 @@ public class ConfirmationEmailServiceImpl implements ConfirmationEmailService { sentMergeConfirmationEmail(confirmationEmail, mailService, principal.getName()); } + + @Override + public void createUnlinkConfirmationEmail(EmailConfirmationDao loginConfirmationEmailDao, MailService mailService, + String email, UUID userId, Principal principal, Integer provider) { + EmailConfirmation confirmationEmail = new EmailConfirmation(); + confirmationEmail.setEmail(principal.getEmail()); + confirmationEmail.setExpiresAt(Date + .from(new Date() + .toInstant() + .plusSeconds(Long.parseLong(this.environment.getProperty("conf_email.expiration_time_seconds"))) + ) + ); + confirmationEmail.setUserId(userId); + try { + Map map = new HashMap<>(); + map.put("email", email); + map.put("provider", provider.toString()); + confirmationEmail.setData(new ObjectMapper().writeValueAsString(map)); + } catch (JsonProcessingException e) { + logger.error(e.getMessage(), e); + } + confirmationEmail.setIsConfirmed(false); + confirmationEmail.setToken(UUID.randomUUID()); + confirmationEmail = loginConfirmationEmailDao.createOrUpdate(confirmationEmail); + sentUnlinkConfirmationEmail(confirmationEmail, mailService); + } } \ No newline at end of file diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/ExportXmlBuilder.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/ExportXmlBuilder.java index 9c8a591b4..ae8c43490 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/ExportXmlBuilder.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/ExportXmlBuilder.java @@ -86,6 +86,11 @@ public class ExportXmlBuilder { composite.appendChild(title); } composite.appendChild(createFields(compositeField.getFields(), visibilityRuleService, element)); + if(compositeField.getHasCommentField()){ + Element comment = element.createElement("comment"); + comment.setTextContent(compositeField.getCommentFieldValue()); + composite.appendChild(comment); + } elementComposites.appendChild(composite); } 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 2cf12e68d..60f2da9e1 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 @@ -164,10 +164,14 @@ public class ExportXmlBuilderDatasetProfile { numbering.setTextContent(field.getNumbering()); elementField.appendChild(numbering); } - if (field.getRdaProperty() != null) { - Element rdaProperty = element.createElement("rdaProperty"); - rdaProperty.setTextContent(field.getRdaProperty()); - elementField.appendChild(rdaProperty); + if (field.getSchematics() != null) { + Element schematics = element.createElement("schematics"); + field.getSchematics().forEach(schematic -> { + Element schematicChild = element.createElement("schematic"); + schematicChild.setTextContent(schematic); + schematics.appendChild(schematicChild); + }); + elementField.appendChild(schematics); } if (field.getValidations() != null) { Element validations = element.createElement("validations"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java index 89e66e869..f6436a446 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Field.java @@ -29,7 +29,7 @@ public class Field { private Object data; - private String rdaProperty; + private Schematics schematics; @XmlAttribute(name = "id") public String getId() { @@ -103,16 +103,15 @@ public class Field { this.data = data; } - @XmlElement(name = "rdaProperty") - public String getRdaProperty() { - return rdaProperty; + @XmlElement(name = "schematics") + public Schematics getSchematics() { + return schematics; } - public void setRdaProperty(String rdaProperty) { - this.rdaProperty = rdaProperty; + public void setSchematics(Schematics schematics) { + this.schematics = schematics; } - public eu.eudat.models.data.admin.components.datasetprofile.Field toAdminCompositeModelSection() { eu.eudat.models.data.admin.components.datasetprofile.Field fieldEntity =new eu.eudat.models.data.admin.components.datasetprofile.Field(); fieldEntity.setId(this.id); @@ -131,7 +130,14 @@ public class Field { if (data != null) { fieldEntity.setData(data.toMap((Element) this.data)); } - fieldEntity.setRdaCommonStandard(this.rdaProperty); + List schematicsList = new LinkedList<>(); + if (this.schematics != null && this.schematics.getSchematics() != null) { + for (Schematic schematic : this.schematics.getSchematics()) { + if (schematic != null && schematic.getSchematic() != null && !schematic.getSchematic().isEmpty()) + schematicsList.add(schematic.getSchematic()); + } + } + fieldEntity.setSchematics(schematicsList); return fieldEntity; } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematic.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematic.java new file mode 100644 index 000000000..f960693e8 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematic.java @@ -0,0 +1,19 @@ +package eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.Fields; + +import javax.xml.bind.annotation.XmlRootElement; +import javax.xml.bind.annotation.XmlValue; + +@XmlRootElement(name = "schematic") +public class Schematic { + + private String schematic; + + @XmlValue + public String getSchematic() { + return schematic; + } + public void setSchematic(String schematic) { + this.schematic = schematic; + } + +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematics.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematics.java new file mode 100644 index 000000000..e098752ca --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/documents/xml/datasetProfileXml/datasetProfileModel/Fields/Schematics.java @@ -0,0 +1,20 @@ +package eu.eudat.logic.utilities.documents.xml.datasetProfileXml.datasetProfileModel.Fields; + +import javax.xml.bind.annotation.XmlElement; +import javax.xml.bind.annotation.XmlRootElement; +import java.util.List; + +@XmlRootElement(name = "schematics") +public class Schematics { + + private List schematics; + + @XmlElement(name = "schematic") + public List getSchematics() { + return schematics; + } + + public void setSchematics(List schematics) { + this.schematics = schematics; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/json/JsonSearcher.java b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/json/JsonSearcher.java index 6e53aed30..d5cab1d19 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/json/JsonSearcher.java +++ b/dmp-backend/web/src/main/java/eu/eudat/logic/utilities/json/JsonSearcher.java @@ -29,6 +29,18 @@ public class JsonSearcher { } found++; } + else if(node.get(fieldName).isArray()){ + for(JsonNode item: node.get(fieldName)){ + if(item.asText().equals(value) || item.asText().startsWith(value)){ + if (parent) { + nodes.add(root); + } else { + nodes.add(node); + } + found++; + } + } + } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java index f9c29e236..63bd89b6d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/admin/components/datasetprofile/Field.java @@ -45,7 +45,7 @@ public class Field implements ViewStyleDefinition schematics; private String value; private ViewStyle viewStyle; private String datatype; @@ -70,11 +70,12 @@ public class Field implements ViewStyleDefinition getSchematics() { + return schematics; } - public void setRdaCommonStandard(String rdaCommonStandard) { - this.rdaCommonStandard = rdaCommonStandard; + public void setSchematics(List schematics) { + this.schematics = schematics; } public String getValue() { @@ -152,7 +153,7 @@ public class Field implements ViewStyleDefinition { private String id; private int ordinal; - private String rdaCommonStandard; + private List schematics; private String numbering; private ViewStyle viewStyle; private DefaultValue defaultValue; @@ -42,11 +42,11 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable getSchematics() { + return schematics; } - public void setRdaCommonStandard(String rdaCommonStandard) { - this.rdaCommonStandard = rdaCommonStandard; + public void setSchematics(List schematics) { + this.schematics = schematics; } public ViewStyle getViewStyle() { @@ -105,8 +105,14 @@ public class Field implements DatabaseViewStyleDefinition, XmlSerializable(); + Element schematics = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "schematics"); + if(schematics != null){ + NodeList schematicElements = schematics.getChildNodes(); + for (int temp = 0; temp < schematicElements.getLength(); temp++) { + Node schematicElement = schematicElements.item(temp); + if (schematicElement.getNodeType() == Node.ELEMENT_NODE) { + this.schematics.add(schematicElement.getTextContent()); + } + } + } Element dataElement = (Element) XmlBuilder.getNodeFromListByTagName(element.getChildNodes(), "data"); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java index f874fa74e..693da5fdc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/externaldataset/ExternalDatasetListingModel.java @@ -18,6 +18,7 @@ public class ExternalDatasetListingModel implements DataModel ids; private String name; private String pid; + private String pidTypeField; private String abbreviation; private String uri; private Date created; @@ -100,6 +101,14 @@ public class PublicationModel implements DataModel multiplicityItems; private List validations; private Visibility visible; - private String rdaProperty; + private List schematics; private Boolean export; @@ -154,12 +154,12 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin this.numbering = numbering; } - public String getRdaProperty() { - return rdaProperty; + public List getSchematics() { + return schematics; } - public void setRdaProperty(String rdaProperty) { - this.rdaProperty = rdaProperty; + public void setSchematics(List schematics) { + this.schematics = schematics; } public Boolean getExport() { @@ -181,7 +181,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin newField.defaultValue = this.defaultValue; newField.data = this.data; newField.validations = this.validations; - newField.rdaProperty = this.rdaProperty; + newField.schematics = this.schematics; newField.numbering = "mult" + index + "_" + this.numbering; newField.export = this.export; return newField; @@ -196,7 +196,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin field.setDefaultValue(this.defaultValue); field.setVisible(this.visible); field.setValidations(this.validations); - field.setRdaCommonStandard(this.rdaProperty); + field.setSchematics(this.schematics); field.setExport(this.export); return field; } @@ -211,7 +211,7 @@ public class Field implements Comparable, PropertiesModelBuilder, ViewStyleDefin this.defaultValue = item.getDefaultValue(); this.visible = item.getVisible(); this.validations = item.getValidations(); - this.rdaProperty = item.getRdaCommonStandard(); + this.schematics = item.getSchematics(); this.export = item.getExport(); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserUnlinkRequestModel.java b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserUnlinkRequestModel.java new file mode 100644 index 000000000..5ce0b0c77 --- /dev/null +++ b/dmp-backend/web/src/main/java/eu/eudat/models/data/userinfo/UserUnlinkRequestModel.java @@ -0,0 +1,30 @@ +package eu.eudat.models.data.userinfo; + +import java.util.UUID; + +public class UserUnlinkRequestModel { + private UUID userId; + private String email; + private Integer provider; + + public UUID getUserId() { + return userId; + } + public void setUserId(UUID userId) { + this.userId = userId; + } + + public String getEmail() { + return email; + } + public void setEmail(String email) { + this.email = email; + } + + public Integer getProvider() { + return provider; + } + public void setProvider(Integer provider) { + this.provider = provider; + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java index aa76750d7..0c6a340f8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/CostRDAMapper.java @@ -31,7 +31,19 @@ public class CostRDAMapper { public static List toRDAList(List nodes) throws JsonProcessingException { Map rdaMap = new HashMap<>(); for(JsonNode node: nodes){ - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dmp.cost")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String rdaValue = node.get("value").asText(); if(rdaValue == null || (rdaValue.isEmpty() && !node.get("value").isArray())){ continue; diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java index 345fdebff..f3e690e75 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetIdRDAMapper.java @@ -27,7 +27,19 @@ public class DatasetIdRDAMapper { public static DatasetId toRDA(List nodes) { DatasetId data = new DatasetId(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.dataset_id")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String rdaValue = node.get("value").asText(); if(rdaValue == null || rdaValue.isEmpty()){ continue; @@ -77,20 +89,25 @@ public class DatasetIdRDAMapper { public static Map toProperties(DatasetId rda, JsonNode node) { Map properties = new HashMap<>(); - List idNodes = JsonSearcher.findNodes(node, "rdaProperty", "dataset.dataset_id"); + List idNodes = JsonSearcher.findNodes(node, "schematics", "rda.dataset.dataset_id"); for (JsonNode idNode: idNodes) { for (DatasetIdProperties datasetIdProperties : DatasetIdProperties.values()) { - if (idNode.get("rdaProperty").asText().endsWith(datasetIdProperties.getName())) { - switch (datasetIdProperties) { - case IDENTIFIER: - properties.put(idNode.get("id").asText(), rda.getIdentifier()); - break; - case TYPE: - properties.put(idNode.get("id").asText(), rda.getType().value()); + JsonNode schematics = idNode.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().endsWith(datasetIdProperties.getName())){ + switch (datasetIdProperties) { + case IDENTIFIER: + properties.put(idNode.get("id").asText(), rda.getIdentifier()); + break; + case TYPE: + properties.put(idNode.get("id").asText(), rda.getType().value()); + break; + } break; + } } - } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java index 39b4187c3..c1a2d9dbc 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DatasetRDAMapper.java @@ -59,32 +59,32 @@ public class DatasetRDAMapper { ObjectMapper mapper = new ObjectMapper(); String datasetDescriptionJson = mapper.writeValueAsString(datasetWizardModel.getDatasetProfileDefinition()); JsonNode datasetDescriptionObj = mapper.readTree(datasetDescriptionJson); - List idNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.dataset_id"); + List idNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.dataset_id"); if (!idNodes.isEmpty()) { rda.setDatasetId(DatasetIdRDAMapper.toRDA(idNodes)); } if (rda.getDatasetId() == null) { rda.setDatasetId(new DatasetId(dataset.getId().toString(), DatasetId.Type.OTHER)); } - List typeNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.type"); + List typeNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.type"); if (!typeNodes.isEmpty() && !typeNodes.get(0).get("value").asText().isEmpty()) { rda.setType(typeNodes.get(0).get("value").asText()); } else { rda.setType("DMP Dataset"); } - List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.language"); + List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.language"); if (!languageNodes.isEmpty() && !languageNodes.get(0).get("value").asText().isEmpty()) { rda.setLanguage(Language.fromValue(languageNodes.get(0).get("value").asText())); } else { rda.setLanguage(LanguageRDAMapper.mapLanguageIsoToRDAIso(dataset.getProfile().getLanguage())); } - List metadataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.metadata"); + List metadataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.metadata"); if (!metadataNodes.isEmpty()) { rda.setMetadata(MetadataRDAMapper.toRDAList(metadataNodes)); }else{ rda.setMetadata(new ArrayList<>()); } - List qaNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.data_quality_assurance"); + List qaNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.data_quality_assurance"); if (!qaNodes.isEmpty()) { /*rda.setDataQualityAssurance(qaNodes.stream().map(qaNode -> qaNode.get("value").asText()).collect(Collectors.toList())); for (int i = 0; i < qaNodes.size(); i++) { @@ -115,17 +115,17 @@ public class DatasetRDAMapper { }else{ rda.setDataQualityAssurance(new ArrayList<>()); } - List preservationNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.preservation_statement"); + List preservationNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.preservation_statement"); if (!preservationNodes.isEmpty() && !preservationNodes.get(0).get("value").asText().isEmpty()) { rda.setPreservationStatement(preservationNodes.get(0).get("value").asText()); } - List distributionNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.distribution"); + List distributionNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.distribution"); if (!distributionNodes.isEmpty()) { rda.setDistribution(DistributionRDAMapper.toRDAList(distributionNodes)); }else{ rda.setDistribution(new ArrayList<>()); } - List keywordNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.keyword"); + List keywordNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.keyword"); if (!keywordNodes.isEmpty()) { rda.setKeyword(keywordNodes.stream().map(keywordNode -> { JsonNode value = keywordNode.get("value"); @@ -142,7 +142,7 @@ public class DatasetRDAMapper { List tags = apiContext.getOperationsContext().getElasticRepository().getDatasetRepository().findDocument(dataset.getId().toString()).getTags().stream().map(Tag::getName).collect(Collectors.toList()); rda.setKeyword(tags); } - List personalDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.personal_data"); + List personalDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.personal_data"); if (!personalDataNodes.isEmpty()) { try{ rda.setPersonalData(personalDataNodes.stream().map(personalDataNode -> Dataset.PersonalData.fromValue(personalDataNode.get("value").asText())).findFirst().get()); @@ -152,13 +152,13 @@ public class DatasetRDAMapper { } else { rda.setPersonalData(Dataset.PersonalData.UNKNOWN); } - List securityAndPrivacyNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.security_and_privacy"); + List securityAndPrivacyNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.security_and_privacy"); if (!securityAndPrivacyNodes.isEmpty()) { rda.setSecurityAndPrivacy(SecurityAndPrivacyRDAMapper.toRDAList(securityAndPrivacyNodes)); }else{ rda.setSecurityAndPrivacy(new ArrayList<>()); } - List sensitiveDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.sensitive_data"); + List sensitiveDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.sensitive_data"); if (!sensitiveDataNodes.isEmpty()) { try{ rda.setSensitiveData(sensitiveDataNodes.stream().map(sensitiveDataNode -> Dataset.SensitiveData.fromValue(sensitiveDataNode.get("value").asText())).findFirst().get()); @@ -168,35 +168,47 @@ public class DatasetRDAMapper { } else { rda.setSensitiveData(Dataset.SensitiveData.UNKNOWN); } - List technicalResourceNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.technical_resource"); + List technicalResourceNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.technical_resource"); if (!technicalResourceNodes.isEmpty()) { rda.setTechnicalResource(TechnicalResourceRDAMapper.toRDAList(technicalResourceNodes)); }else{ rda.setTechnicalResource(new ArrayList<>()); } - List issuedNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.issued"); + List issuedNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.issued"); if (!issuedNodes.isEmpty() && !issuedNodes.get(0).get("value").asText().isEmpty()) { rda.setIssued(issuedNodes.get(0).get("value").asText()); } - List contributorNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dmp.contributor"); + List contributorNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dmp.contributor"); if (!contributorNodes.isEmpty()) { dmp.getContributor().addAll(contributorNodes.stream().map(contributorNode -> { JsonNode value = contributorNode.get("value"); if (value.isArray()) { return StreamSupport.stream(value.spliterator(), false).map(node -> ContributorRDAMapper.toRDA(node.asText())).collect(Collectors.toList()); } else { - return Collections.singletonList(new Contributor()); // return null kalutera + return Collections.singletonList(new Contributor()); } }).flatMap(Collection::stream).collect(Collectors.toList())); } - List costNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dmp.cost"); + List costNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dmp.cost"); if (!costNodes.isEmpty()) { dmp.getCost().addAll(CostRDAMapper.toRDAList(costNodes)); } - List ethicsNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dmp.ethical_issues"); + List ethicsNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dmp.ethical_issues"); if (!ethicsNodes.isEmpty()) { for(JsonNode node: ethicsNodes){ - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dmp.ethical_issues")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String rdaValue = node.get("value").asText(); if(rdaValue == null || rdaValue.isEmpty()){ continue; @@ -276,12 +288,12 @@ public class DatasetRDAMapper { String datasetDescriptionJson = mapper.writeValueAsString(datasetWizardModel.getDatasetProfileDefinition()); JsonNode datasetDescriptionObj = mapper.readTree(datasetDescriptionJson); - List typeNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.type"); + List typeNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.type"); if (!typeNodes.isEmpty()) { properties.put(typeNodes.get(0).get("id").asText(), rda.getType()); } - List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.language"); + List languageNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.language"); if (!languageNodes.isEmpty() && rda.getLanguage() != null) { properties.put(languageNodes.get(0).get("id").asText(), rda.getLanguage().value()); } @@ -298,7 +310,7 @@ public class DatasetRDAMapper { for (int i = 0; i < qaIds.size(); i++) { properties.put(qaIds.get(i), rda.getDataQualityAssurance().get(i)); }*/ - List qaNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.data_quality_assurance"); + List qaNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.data_quality_assurance"); if (!qaNodes.isEmpty() && rda.getDataQualityAssurance() != null && !rda.getDataQualityAssurance().isEmpty()) { ObjectMapper m = new ObjectMapper(); List qas = new ArrayList<>(rda.getDataQualityAssurance()); @@ -310,12 +322,12 @@ public class DatasetRDAMapper { } } - List preservationNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.preservation_statement"); + List preservationNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.preservation_statement"); if (!preservationNodes.isEmpty()) { properties.put(preservationNodes.get(0).get("id").asText(), rda.getPreservationStatement()); } - List issuedNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.issued"); + List issuedNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.issued"); if (!issuedNodes.isEmpty()) { properties.put(issuedNodes.get(0).get("id").asText(), rda.getIssued()); } @@ -351,7 +363,7 @@ public class DatasetRDAMapper { } } - List personalDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.personal_data"); + List personalDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.personal_data"); if (!personalDataNodes.isEmpty()) { properties.put(personalDataNodes.get(0).get("id").asText(), rda.getPersonalData().value()); } @@ -360,7 +372,7 @@ public class DatasetRDAMapper { properties.putAll(SecurityAndPrivacyRDAMapper.toProperties(rda.getSecurityAndPrivacy())); } - List sensitiveDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "rdaProperty", "dataset.sensitive_data"); + List sensitiveDataNodes = JsonSearcher.findNodes(datasetDescriptionObj, "schematics", "rda.dataset.sensitive_data"); if (!sensitiveDataNodes.isEmpty()) { properties.put(sensitiveDataNodes.get(0).get("id").asText(), rda.getSensitiveData().value()); } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java index f5bc36f34..547927c94 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/DistributionRDAMapper.java @@ -24,7 +24,10 @@ public class DistributionRDAMapper { Map rdaMap = new HashMap<>(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = getRdaDistributionProperty(node); + if(rdaProperty.isEmpty()){ + continue; + } String rdaValue = node.get("value").asText(); //if(rdaValue == null || rdaValue.isEmpty()){ if(rdaValue == null || (rdaValue.isEmpty() && !node.get("value").isArray())){ @@ -79,7 +82,16 @@ public class DistributionRDAMapper { rda.setAdditionalProperty(ImportPropertyName.BYTE_SIZE.getName(), node.get("id").asText()); break; case LICENSE: - List licenseNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("license")).collect(Collectors.toList()); + List licenseNodes = nodes.stream().filter(lnode -> { + if(lnode.get("schematics").isArray()){ + for(JsonNode schematic: lnode.get("schematics")){ + if(schematic.asText().startsWith("rda.dataset.distribution.license")){ + return true; + } + } + } + return false; + }).collect(Collectors.toList()); License license = LicenseRDAMapper.toRDA(licenseNodes); rda.setLicense(license != null? Collections.singletonList(license): new ArrayList<>()); break; @@ -182,71 +194,77 @@ public class DistributionRDAMapper { public static Map toProperties(Distribution rda, JsonNode root) { Map properties = new HashMap<>(); - List distributionNodes = JsonSearcher.findNodes(root, "rdaProperty", "dataset.distribution"); + List distributionNodes = JsonSearcher.findNodes(root, "schematics", "rda.dataset.distribution"); for (JsonNode distributionNode: distributionNodes) { for (ExportPropertyName exportPropertyName: ExportPropertyName.values()) { - if (distributionNode.get("rdaProperty").asText().contains(exportPropertyName.getName())) { - switch (exportPropertyName) { - case ACCESS_URL: - properties.put(distributionNode.get("id").asText(), rda.getAccessUrl()); - break; - case DESCRIPTION: - properties.put(distributionNode.get("id").asText(), rda.getDescription()); - break; - case TITLE: - properties.put(distributionNode.get("id").asText(), rda.getTitle()); - break; - case AVAILABLE_UNTIL: - properties.put(distributionNode.get("id").asText(), rda.getAvailableUntil()); - break; - case DOWNLOAD_URL: - if (rda.getDownloadUrl() != null) { - properties.put(distributionNode.get("id").asText(), rda.getDownloadUrl().toString()); - } - break; - case DATA_ACCESS: - properties.put(distributionNode.get("id").asText(), rda.getDataAccess().value()); - break; - case BYTE_SIZE: - if (rda.getByteSize() != null) { - properties.put(distributionNode.get("id").asText(), rda.getByteSize().toString()); - } - break; - case FORMAT: - if (rda.getFormat() != null && !rda.getFormat().isEmpty()) { - String style = distributionNode.get("viewStyle").get("renderStyle").asText(); - if(style.equals("combobox")) { - if (distributionNode.get("data").get("type").asText().equals("autocomplete")) { - Map additionalProperties = rda.getAdditionalProperties(); - List standardFormats = new ArrayList<>(); - rda.getAdditionalProperties().forEach((key, value) -> { - try { - if (key.matches("format\\d+")) { - standardFormats.add(additionalProperties.get(key)); - properties.put(distributionNode.get("id").asText(), mapper.writeValueAsString(standardFormats)); - } - } catch (JsonProcessingException e) { - logger.error(e.getMessage(), e); - } - }); + JsonNode schematics = distributionNode.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().contains(exportPropertyName.getName())){ + switch (exportPropertyName) { + case ACCESS_URL: + properties.put(distributionNode.get("id").asText(), rda.getAccessUrl()); + break; + case DESCRIPTION: + properties.put(distributionNode.get("id").asText(), rda.getDescription()); + break; + case TITLE: + properties.put(distributionNode.get("id").asText(), rda.getTitle()); + break; + case AVAILABLE_UNTIL: + properties.put(distributionNode.get("id").asText(), rda.getAvailableUntil()); + break; + case DOWNLOAD_URL: + if (rda.getDownloadUrl() != null) { + properties.put(distributionNode.get("id").asText(), rda.getDownloadUrl().toString()); } - } - else if(style.equals("freetext")){ - properties.put(distributionNode.get("id").asText(), String.join(", ", rda.getFormat())); - } - } - break; - case LICENSE: - if (rda.getLicense() != null && !rda.getLicense().isEmpty()) { - properties.putAll(LicenseRDAMapper.toProperties(rda.getLicense().get(0), root)); - } - break; - case HOST: - if (rda.getHost() != null) { - properties.putAll(HostRDAMapper.toProperties(rda.getHost())); + break; + case DATA_ACCESS: + properties.put(distributionNode.get("id").asText(), rda.getDataAccess().value()); + break; + case BYTE_SIZE: + if (rda.getByteSize() != null) { + properties.put(distributionNode.get("id").asText(), rda.getByteSize().toString()); + } + break; + case FORMAT: + if (rda.getFormat() != null && !rda.getFormat().isEmpty()) { + String style = distributionNode.get("viewStyle").get("renderStyle").asText(); + if(style.equals("combobox")) { + if (distributionNode.get("data").get("type").asText().equals("autocomplete")) { + Map additionalProperties = rda.getAdditionalProperties(); + List standardFormats = new ArrayList<>(); + rda.getAdditionalProperties().forEach((key, value) -> { + try { + if (key.matches("format\\d+")) { + standardFormats.add(additionalProperties.get(key)); + properties.put(distributionNode.get("id").asText(), mapper.writeValueAsString(standardFormats)); + } + } catch (JsonProcessingException e) { + logger.error(e.getMessage(), e); + } + }); + } + } + else if(style.equals("freetext")){ + properties.put(distributionNode.get("id").asText(), String.join(", ", rda.getFormat())); + } + } + break; + case LICENSE: + if (rda.getLicense() != null && !rda.getLicense().isEmpty()) { + properties.putAll(LicenseRDAMapper.toProperties(rda.getLicense().get(0), root)); + } + break; + case HOST: + if (rda.getHost() != null) { + properties.putAll(HostRDAMapper.toProperties(rda.getHost())); + } + break; } break; + } } } } @@ -258,7 +276,10 @@ public class DistributionRDAMapper { public static Distribution toRDA(List nodes) { Distribution rda = new Distribution(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = getRdaDistributionProperty(node); + if(rdaProperty.isEmpty()){ + continue; + } String rdaValue = node.get("value").asText(); for (ExportPropertyName exportPropertyName: ExportPropertyName.values()) { if (rdaProperty.contains(exportPropertyName.getName())) { @@ -288,11 +309,29 @@ public class DistributionRDAMapper { rda.setFormat(Collections.singletonList(rdaValue)); break; case LICENSE: - List licenseNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("license")).collect(Collectors.toList()); + List licenseNodes = nodes.stream().filter(lnode -> { + if(lnode.get("schematics").isArray()){ + for(JsonNode schematic: lnode.get("schematics")){ + if(schematic.asText().startsWith("rda.dataset.distribution.license")){ + return true; + } + } + } + return false; + }).collect(Collectors.toList()); rda.setLicense(Collections.singletonList(LicenseRDAMapper.toRDA(licenseNodes))); break; case HOST: - List hostNodes = nodes.stream().filter(lnode -> lnode.get("rdaProperty").asText().toLowerCase().contains("host")).collect(Collectors.toList()); + List hostNodes = nodes.stream().filter(lnode -> { + if(lnode.get("schematics").isArray()){ + for(JsonNode schematic: lnode.get("schematics")){ + if(schematic.asText().startsWith("rda.dataset.distribution.host")){ + return true; + } + } + } + return false; + }).collect(Collectors.toList()); rda.setHost(HostRDAMapper.toRDA(hostNodes, "0")); break; } @@ -333,6 +372,20 @@ public class DistributionRDAMapper { return rda; } + private static String getRdaDistributionProperty(JsonNode node) { + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.distribution")){ + rdaProperty = schematic.asText(); + break; + } + } + } + return rdaProperty; + } + private static Distribution getRelative( Map rdaMap, String numbering) { return rdaMap.entrySet().stream().filter(entry -> MyStringUtils.getFirstDifference(entry.getKey(), numbering) > 0) .max(Comparator.comparingInt(entry -> MyStringUtils.getFirstDifference(entry.getKey(), numbering))).map(Map.Entry::getValue).orElse(new Distribution()); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java index 5fb92aab1..ca69c5cfb 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/HostRDAMapper.java @@ -19,7 +19,19 @@ public class HostRDAMapper { public static Host toRDA(List nodes, String numbering) { Host rda = new Host(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.distribution.host")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } if (rdaProperty.contains("host")) { int firstDiff = MyStringUtils.getFirstDifference(numbering, node.get("numbering").asText()); if (firstDiff == -1 || firstDiff >= 2) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java index b23ff204b..8b2cc84e3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/LicenseRDAMapper.java @@ -17,7 +17,19 @@ public class LicenseRDAMapper { public static License toRDA(List nodes) { License rda = new License(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.distribution.license")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String value = node.get("value").asText(); if(value == null || value.isEmpty()){ continue; @@ -78,20 +90,26 @@ public class LicenseRDAMapper { public static Map toProperties(License rda, JsonNode root) { Map properties = new HashMap<>(); - List licenseNodes = JsonSearcher.findNodes(root, "rdaProperty", "dataset.distribution.license"); + List licenseNodes = JsonSearcher.findNodes(root, "schematics", "rda.dataset.distribution.license"); for (JsonNode licenseNode: licenseNodes) { for (LicenceProperties licenceProperty: LicenceProperties.values()) { - if (licenseNode.get("rdaProperty").asText().endsWith(licenceProperty.getName())) { - switch (licenceProperty) { - case LICENSE_REF: - if (rda.getLicenseRef() != null) { - properties.put(licenseNode.get("id").asText(), rda.getLicenseRef().toString()); + JsonNode schematics = licenseNode.get("schematics"); + if(schematics.isArray()) { + for (JsonNode schematic : schematics) { + if (schematic.asText().endsWith(licenceProperty.getName())) { + switch (licenceProperty) { + case LICENSE_REF: + if (rda.getLicenseRef() != null) { + properties.put(licenseNode.get("id").asText(), rda.getLicenseRef().toString()); + } + break; + case START_DATE: + properties.put(licenseNode.get("id").asText(), rda.getStartDate()); + break; } - break; - case START_DATE: - properties.put(licenseNode.get("id").asText(), rda.getStartDate()); - break; + } + break; } } } diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java index f8b7fdf28..fd9eb1d13 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/MetadataRDAMapper.java @@ -20,7 +20,19 @@ public class MetadataRDAMapper { Map rdaMap = new HashMap<>(); List rdas = new ArrayList<>(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.metadata")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } JsonNode rdaValue = node.get("value"); for (PropertyName propertyName: PropertyName.values()) { @@ -119,7 +131,16 @@ public class MetadataRDAMapper { public static Metadatum toRDA(JsonNode node) { Metadatum rda = new Metadatum(); - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.metadata")){ + rdaProperty = schematic.asText(); + break; + } + } + } JsonNode rdaValue = node.get("value"); if (rdaProperty.contains("metadata_standard_id")) { if (rdaValue instanceof ArrayNode) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java index a178b6802..85f494917 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/SecurityAndPrivacyRDAMapper.java @@ -16,7 +16,19 @@ public class SecurityAndPrivacyRDAMapper { Map rdaMap = new HashMap<>(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.security_and_privacy")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String rdaValue = node.get("value").asText(); if(rdaValue == null || rdaValue.isEmpty()){ continue; @@ -69,8 +81,17 @@ public class SecurityAndPrivacyRDAMapper { public static SecurityAndPrivacy toRDA(JsonNode node) { SecurityAndPrivacy rda = new SecurityAndPrivacy(); - String rdaProperty = node.get("rdaProperty").asText(); - String value =node.get("value").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.security_and_privacy")){ + rdaProperty = schematic.asText(); + break; + } + } + } + String value = node.get("value").asText(); if (rdaProperty.contains("description")) { rda.setDescription(value); diff --git a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java index d38788e4a..709ee5ef3 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java +++ b/dmp-backend/web/src/main/java/eu/eudat/models/rda/mapper/TechnicalResourceRDAMapper.java @@ -16,7 +16,19 @@ public class TechnicalResourceRDAMapper { Map rdaMap = new HashMap<>(); for (JsonNode node: nodes) { - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.technical_resource")){ + rdaProperty = schematic.asText(); + break; + } + } + } + else{ + continue; + } String rdaValue = node.get("value").asText(); if(rdaValue == null || rdaValue.isEmpty()){ continue; @@ -70,7 +82,16 @@ public class TechnicalResourceRDAMapper { public static TechnicalResource toRDA(JsonNode node) { TechnicalResource rda = new TechnicalResource(); - String rdaProperty = node.get("rdaProperty").asText(); + String rdaProperty = ""; + JsonNode schematics = node.get("schematics"); + if(schematics.isArray()){ + for(JsonNode schematic: schematics){ + if(schematic.asText().startsWith("rda.dataset.technical_resource")){ + rdaProperty = schematic.asText(); + break; + } + } + } String value = node.get("value").asText(); if (rdaProperty.contains("description")) { diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java index f30b2dfd0..98d7db4ac 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/controllers/PublicDmpsDocumentation.java @@ -47,6 +47,7 @@ public class PublicDmpsDocumentation extends BaseController { "4.6. version: integer, version of dmp\n" + "4.7. groupId: uuid, group id in which dmp belongs\n" + "4.8. users: list of UserInfoPublicModel, user who collaborated on the dmp\n" + + "4.9. researchers: list of ResearcherPublicModel, researchers involved in the dmp\n" + "4.9. finalizedAt: date, finalization date\n" + "4.10. publishedAt: date, publication date\n"; private static final String getPagedResponseExample = "{\n" + @@ -94,13 +95,16 @@ public class PublicDmpsDocumentation extends BaseController { " 1. periodStart: date, dmps created date greater than periodStart\n" + " 2. periodEnd: date, dmps created date less than periodEnd\n" + " 3. grants: list of uuids, dmps with the corresponding grants\n" + - " 4. funders: list of uuids, dmps with the corresponding funders\n" + - " 5. datasetTemplates: list of uuids, dataset templates which are described in the dmps\n" + - " 6. dmpOrganisations: list of strings, dmps belonging to these organisations\n" + - " 7. collaborators: list of uuids, user who collaborated on the creation/modification of dmps\n" + - " 8. allVersions: boolean, if dmps should be fetched with all their versions\n" + - " 9. groupIds: list of uuids, in which groups the dmps are\n" + - "10. like: string, dmps fetched have this string matched in their label or description\n"; + " 4. grantsLike: list of strings, dmps fetched having their grant matching any of the strings provided\n" + + " 5. funders: list of uuids, dmps with the corresponding funders\n" + + " 6. fundersLike: list of strings, dmps fetched having their funders matching any of the strings provided\n" + + " 7. datasetTemplates: list of uuids, dataset templates which are described in the dmps\n" + + " 8. dmpOrganisations: list of strings, dmps belonging to these organisations\n" + + " 9. collaborators: list of uuids, user who collaborated on the creation/modification of dmps\n" + + "10. collaboratorsLike: list of strings, dmps fetched having their collaborators matching any of the strings provided\n" + + "11. allVersions: boolean, if dmps should be fetched with all their versions\n" + + "12. groupIds: list of uuids, in which groups the dmps are\n" + + "13. like: string, dmps fetched have this string matched in their label or description\n"; private static final String getPagedRequestParamDescription = "The fieldsGroup is a string which indicates if the returned objects would have all their properties\n" + "There are two available values: 1) listing and 2) autocomplete\n" + "**listing**: returns objects with all their properties completed\n" + diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/criteria/dmp/DataManagementPlanPublicCriteria.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/criteria/dmp/DataManagementPlanPublicCriteria.java index b5079eb27..6a430deb1 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/criteria/dmp/DataManagementPlanPublicCriteria.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/criteria/dmp/DataManagementPlanPublicCriteria.java @@ -15,14 +15,20 @@ public class DataManagementPlanPublicCriteria extends Criteria { private Date periodEnd; @ApiModelProperty(value = "grants", name = "grants", dataType = "List", example = "[]") private List grants; + @ApiModelProperty(value = "grantsLike", name = "grantsLike", dataType = "List", example = "[]") + private List grantsLike; @ApiModelProperty(value = "funders", name = "funders", dataType = "List", example = "[]") private List funders; + @ApiModelProperty(value = "fundersLike", name = "fundersLike", dataType = "List", example = "[]") + private List fundersLike; @ApiModelProperty(value = "datasetTemplates", name = "datasetTemplates", dataType = "List", example = "[]") private List datasetTemplates; @ApiModelProperty(value = "dmpOrganisations", name = "dmpOrganisations", dataType = "List", example = "[]") private List dmpOrganisations; @ApiModelProperty(value = "collaborators", name = "collaborators", dataType = "List", example = "[]") private List collaborators; + @ApiModelProperty(value = "collaboratorsLike", name = "collaboratorsLike", dataType = "List", example = "[]") + private List collaboratorsLike; @ApiModelProperty(value = "allVersions", name = "allVersions", dataType = "Boolean", example = "false") private boolean allVersions; @ApiModelProperty(value = "groupIds", name = "groupIds", dataType = "List", example = "[]") @@ -49,6 +55,13 @@ public class DataManagementPlanPublicCriteria extends Criteria { this.grants = grants; } + public List getGrantsLike() { + return grantsLike; + } + public void setGrantsLike(List grantsLike) { + this.grantsLike = grantsLike; + } + public List getFunders() { return funders; } @@ -56,6 +69,13 @@ public class DataManagementPlanPublicCriteria extends Criteria { this.funders = funders; } + public List getFundersLike() { + return fundersLike; + } + public void setFundersLike(List fundersLike) { + this.fundersLike = fundersLike; + } + public List getDatasetTemplates() { return datasetTemplates; } @@ -77,6 +97,13 @@ public class DataManagementPlanPublicCriteria extends Criteria { this.collaborators = collaborators; } + public List getCollaboratorsLike() { + return collaboratorsLike; + } + public void setCollaboratorsLike(List collaboratorsLike) { + this.collaboratorsLike = collaboratorsLike; + } + public boolean getAllVersions() { return allVersions; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DataManagementPlanPublicManager.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DataManagementPlanPublicManager.java index 5c8b67824..bf8a6339d 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DataManagementPlanPublicManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DataManagementPlanPublicManager.java @@ -57,8 +57,6 @@ public class DataManagementPlanPublicManager { dataTable.setTotalCount(count); }); CompletableFuture.allOf(itemsFuture, countFuture).join(); - if(dataTable.getTotalCount() > dmpTableRequest.getLength()) - dataTable.setTotalCount((long)dmpTableRequest.getLength()); return dataTable; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java index 216c8814e..e94db3db8 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/managers/DatasetPublicManager.java @@ -113,11 +113,7 @@ public class DatasetPublicManager { select(this::mapPublicModel); dataTable.setData(datasetLists.stream().filter(Objects::nonNull).collect(Collectors.toList())); - if(count <= datasetTableRequest.getLength()) - dataTable.setTotalCount(count); - else - dataTable.setTotalCount((long)datasetTableRequest.getLength()); - //CompletableFuture.allOf(countFuture).join(); + dataTable.setTotalCount(count); return dataTable; } diff --git a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/listingmodels/DataManagementPlanPublicListingModel.java b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/listingmodels/DataManagementPlanPublicListingModel.java index 2c0b65c69..074212935 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/listingmodels/DataManagementPlanPublicListingModel.java +++ b/dmp-backend/web/src/main/java/eu/eudat/publicapi/models/listingmodels/DataManagementPlanPublicListingModel.java @@ -3,12 +3,10 @@ package eu.eudat.publicapi.models.listingmodels; import eu.eudat.data.entities.DMP; import eu.eudat.data.entities.Grant; import eu.eudat.models.DataModel; +import eu.eudat.publicapi.models.researcher.ResearcherPublicModel; import eu.eudat.publicapi.models.user.UserInfoPublicModel; -import java.util.ArrayList; -import java.util.Date; -import java.util.List; -import java.util.UUID; +import java.util.*; import java.util.stream.Collectors; public class DataManagementPlanPublicListingModel implements DataModel { @@ -20,6 +18,7 @@ public class DataManagementPlanPublicListingModel implements DataModel users; + private List researchers; private Date finalizedAt; private Date publishedAt; @@ -79,6 +78,13 @@ public class DataManagementPlanPublicListingModel implements DataModel getResearchers() { + return researchers; + } + public void setResearchers(List researchers) { + this.researchers = researchers; + } + public Date getFinalizedAt() { return finalizedAt; } @@ -125,9 +131,11 @@ public class DataManagementPlanPublicListingModel implements DataModel new UserInfoPublicModel().fromDataModel(x)).collect(Collectors.toList()) : new ArrayList<>(); + this.researchers = entity.getResearchers() != null ? entity.getResearchers().stream().map(x -> new ResearcherPublicModel().fromDataModel(x)).collect(Collectors.toList()) : new ArrayList<>(); } catch(Exception ex){ this.users = new ArrayList<>(); + this.researchers = new ArrayList<>(); } this.finalizedAt = entity.getFinalizedAt(); this.publishedAt = entity.getPublishedAt(); @@ -151,11 +159,12 @@ public class DataManagementPlanPublicListingModel implements DataModel { @@ -27,8 +27,36 @@ public class DataManagmentPlanPublicTableRequest extends TableQuery builder.lessThan(root.get("created"), this.getCriteria().getPeriodEnd())); if (this.getCriteria().getGrants() != null && !this.getCriteria().getGrants().isEmpty()) query.where(((builder, root) -> root.get("grant").get("id").in(this.getCriteria().getGrants()))); + if (this.getCriteria().getGrantsLike() != null && !this.getCriteria().getGrantsLike().isEmpty()) { + query.where(((builder, root) -> { + List predicates = new ArrayList<>(); + for(String grantLike: this.getCriteria().getGrantsLike()){ + String pattern = "%" + grantLike.toUpperCase() + "%"; + predicates.add(builder.like(builder.upper(root.get("grant").get("label")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("abbreviation")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("reference")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("definition")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("description")), pattern)); + } + return builder.or(predicates.toArray(new Predicate[0])); + } + )); + } if (this.getCriteria().getFunders() != null && !this.getCriteria().getFunders().isEmpty()) query.where(((builder, root) -> root.get("grant").get("funder").get("id").in(this.getCriteria().getFunders()))); + if (this.getCriteria().getFundersLike() != null && !this.getCriteria().getFundersLike().isEmpty()) { + query.where(((builder, root) -> { + List predicates = new ArrayList<>(); + for(String funderLike: this.getCriteria().getFundersLike()){ + String pattern = "%" + funderLike.toUpperCase() + "%"; + predicates.add(builder.like(builder.upper(root.get("grant").get("funder").get("label")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("funder").get("reference")), pattern)); + predicates.add(builder.like(builder.upper(root.get("grant").get("funder").get("definition")), pattern)); + } + return builder.or(predicates.toArray(new Predicate[0])); + } + )); + } //query.where((builder, root) -> builder.lessThan(root.get("grant").get("enddate"), new Date())); // GrantStateType.FINISHED query.where((builder, root) -> @@ -41,6 +69,19 @@ public class DataManagmentPlanPublicTableRequest extends TableQuery root.join("organisations").get("reference").in(this.getCriteria().getDmpOrganisations()))); if (this.getCriteria().getCollaborators() != null && !this.getCriteria().getCollaborators().isEmpty()) query.where(((builder, root) -> root.join("researchers").get("id").in(this.getCriteria().getCollaborators()))); + if (this.getCriteria().getCollaboratorsLike() != null && !this.getCriteria().getCollaboratorsLike().isEmpty()) { + query.where(((builder, root) -> { + List predicates = new ArrayList<>(); + for(String collaboratorLike: this.getCriteria().getCollaboratorsLike()){ + String pattern = "%" + collaboratorLike.toUpperCase() + "%"; + predicates.add(builder.like(builder.upper(root.join("researchers").get("label")), pattern)); + predicates.add(builder.like(builder.upper(root.join("researchers").get("uri")), pattern)); + predicates.add(builder.like(builder.upper(root.join("researchers").get("primaryEmail")), pattern)); + } + return builder.or(predicates.toArray(new Predicate[0])); + } + )); + } if (!this.getCriteria().getAllVersions()) { query.initSubQuery(String.class).where((builder, root) -> builder.equal(root.get("version"), query.subQueryMax((builder1, externalRoot, nestedRoot) -> builder1.and(builder1.equal(externalRoot.get("groupId"), @@ -49,6 +90,7 @@ public class DataManagmentPlanPublicTableRequest extends TableQuery root.get("groupId").in(this.getCriteria().getGroupIds())); } + query.where((builder, root) -> builder.notEqual(root.get("status"), DMP.DMPStatus.DELETED.getValue())); return query; } diff --git a/dmp-backend/web/src/main/resources/DOI_Funder.json b/dmp-backend/web/src/main/resources/DOI_Funder.json deleted file mode 100644 index 9f1c4856d..000000000 --- a/dmp-backend/web/src/main/resources/DOI_Funder.json +++ /dev/null @@ -1,70 +0,0 @@ -[ - { - "Funder": "Australian Research Council", - "DOI": "10.13039/501100000923" - }, - { - "Funder": "Austrian Science Fund", - "DOI": "10.13039/501100002428" - }, - { - "Funder": "European Commission", - "DOI": "10.13039/501100000780" - }, - { - "Funder": "European Environment Agency", - "DOI": "10.13039/501100000806" - }, - { - "Funder": "Academy of Finland", - "DOI": "10.13039/501100002341" - }, - { - "Funder": "Hrvatska Zaklada za Znanost", - "DOI": "10.13039/501100004488" - }, - { - "Funder": "Fundação para a Ciência e a Tecnologia", - "DOI": "10.13039/501100001871" - }, - { - "Funder": "Ministarstvo Prosvete, Nauke i Tehnološkog Razvoja", - "DOI": "10.13039/501100004564" - }, - { - "Funder": "Ministarstvo Znanosti, Obrazovanja i Sporta", - "DOI": "10.13039/501100006588" - }, - { - "Funder": "National Health and Medical Research Council", - "DOI": "10.13039/501100000925" - }, - { - "Funder": "National Institutes of Health", - "DOI": "10.13039/100000002" - }, - { - "Funder": "National Science Foundation", - "DOI": "10.13039/100000001" - }, - { - "Funder": "Nederlandse Organisatie voor Wetenschappelijk Onderzoek", - "DOI": "10.13039/501100003246" - }, - { - "Funder": "Research Councils", - "DOI": "10.13039/501100000690" - }, - { - "Funder": "Schweizerischer Nationalfonds zur Förderung der wissenschaftlichen Forschung", - "DOI": "10.13039/501100001711" - }, - { - "Funder": "Science Foundation Ireland", - "DOI": "10.13039/501100001602" - }, - { - "Funder": "Wellcome Trust", - "DOI": "10.13039/100004440" - } -] \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/Semantics.json b/dmp-backend/web/src/main/resources/Semantics.json new file mode 100644 index 000000000..39034c3a7 --- /dev/null +++ b/dmp-backend/web/src/main/resources/Semantics.json @@ -0,0 +1,458 @@ +[ + { + "category": "rda", + "name": "rda.dataset.data_quality_assurance" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.access_url" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.available_until" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.byte_size" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.data_access" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.description" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.download_url" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.format" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.availability" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.backup_frequency" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.backup_type" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.certified_with" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.description" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.geo_location" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.pid_system" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.storage_type" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.supports_versioning" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.title" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.host.url" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.license.license_ref" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.license.start_date" + }, + { + "category": "rda", + "name": "rda.dataset.distribution.title" + }, + { + "category": "rda", + "name": "rda.dataset.keyword" + }, + { + "category": "rda", + "name": "rda.dataset.language" + }, + { + "category": "rda", + "name": "rda.dataset.metadata.description" + }, + { + "category": "rda", + "name": "rda.dataset.metadata.language" + }, + { + "category": "rda", + "name": "rda.dataset.metadata.metadata_standard_id" + }, + { + "category": "rda", + "name": "rda.dataset.metadata.metadata_standard_id.identifier" + }, + { + "category": "rda", + "name": "rda.dataset.metadata.metadata_standard_id.type" + }, + { + "category": "rda", + "name": "rda.dataset.personal_data" + }, + { + "category": "rda", + "name": "rda.dataset.preservation_statement" + }, + { + "category": "rda", + "name": "rda.dataset.security_and_privacy" + }, + { + "category": "rda", + "name": "rda.dataset.security_and_privacy.description" + }, + { + "category": "rda", + "name": "rda.dataset.security_and_privacy.title" + }, + { + "category": "rda", + "name": "rda.dataset.sensitive_data" + }, + { + "category": "rda", + "name": "rda.dataset.technical_resource.description" + }, + { + "category": "rda", + "name": "rda.dataset.technical_resource.name" + }, + { + "category": "rda", + "name": "rda.dataset.title" + }, + { + "category": "rda", + "name": "rda.dataset.type" + }, + { + "category": "rda", + "name": "rda.dataset.issued" + }, + { + "category": "rda", + "name": "rda.dataset.dataset_id" + }, + { + "category": "rda", + "name": "rda.dataset.dataset_id.identifier" + }, + { + "category": "rda", + "name": "rda.dataset.dataset_id.type" + }, + { + "category": "rda", + "name": "rda.dataset.description" + }, + { + "category": "rda", + "name": "rda.dmp.contact" + }, + { + "category": "rda", + "name": "rda.dmp.contact.contact_id.identifier" + }, + { + "category": "rda", + "name": "rda.dmp.contact.contact_id.type" + }, + { + "category": "rda", + "name": "rda.dmp.contact.mbox" + }, + { + "category": "rda", + "name": "rda.dmp.contact.name" + }, + { + "category": "rda", + "name": "rda.dmp.contributor" + }, + { + "category": "rda", + "name": "rda.dmp.contributor.contributor_id.identifier" + }, + { + "category": "rda", + "name": "rda.dmp.contributor.contributor_id.type" + }, + { + "category": "rda", + "name": "rda.dmp.contributor.mbox" + }, + { + "category": "rda", + "name": "rda.dmp.contributor.name" + }, + { + "category": "rda", + "name": "rda.dmp.contributor.role" + }, + { + "category": "rda", + "name": "rda.dmp.cost" + }, + { + "category": "rda", + "name": "rda.dmp.cost.currency_code" + }, + { + "category": "rda", + "name": "rda.dmp.cost.description" + }, + { + "category": "rda", + "name": "rda.dmp.cost.title" + }, + { + "category": "rda", + "name": "rda.dmp.cost.value" + }, + { + "category": "rda", + "name": "rda.dmp.created" + }, + { + "category": "rda", + "name": "rda.dmp.description" + }, + { + "category": "rda", + "name": "rda.dmp.dmp_id" + }, + { + "category": "rda", + "name": "rda.dmp.dmp_id.identifier" + }, + { + "category": "rda", + "name": "rda.dmp.dmp_id.type" + }, + { + "category": "rda", + "name": "rda.dmp.ethical_issues_description" + }, + { + "category": "rda", + "name": "rda.dmp.ethical_issues_exist" + }, + { + "category": "rda", + "name": "rda.dmp.ethical_issues_report" + }, + { + "category": "rda", + "name": "rda.dmp.language" + }, + { + "category": "rda", + "name": "rda.dmp.modified" + }, + { + "category": "rda", + "name": "rda.dmp.project" + }, + { + "category": "rda", + "name": "rda.dmp.project.description" + }, + { + "category": "rda", + "name": "rda.dmp.project.end" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding.funder_id.identifier" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding.funder_id.type" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding.funding_status" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding.grant_id.identifier" + }, + { + "category": "rda", + "name": "rda.dmp.project.funding.grant_id.type" + }, + { + "category": "rda", + "name": "rda.dmp.project.start" + }, + { + "category": "rda", + "name": "rda.dmp.dmp.project.title" + }, + { + "category": "rda", + "name": "rda.dmp.title" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isCitedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.cites" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isSupplementTo" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isSupplementedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isContinuedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.continues" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isDescribedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.describes" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.hasMetadata" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isMetadataFor" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isNewVersionOf" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isPreviousVersionOf" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isPartOf" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.hasPart" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isReferencedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.references" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isDocumentedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.documents" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isCompiledBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.compiles" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isVariantFormOf" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isOriginalFormof" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isIdenticalTo" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isAlternateIdentifier" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isReviewedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.reviews" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isDerivedFrom" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isSourceOf" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.requires" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isRequiredBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.isObsoletedBy" + }, + { + "category": "zenodo", + "name": "zenodo.related_identifiers.obsoletes" + } +] \ No newline at end of file diff --git a/dmp-backend/web/src/main/resources/config/application-devel.properties b/dmp-backend/web/src/main/resources/config/application-devel.properties index 3b9d687c5..7156a62d5 100644 --- a/dmp-backend/web/src/main/resources/config/application-devel.properties +++ b/dmp-backend/web/src/main/resources/config/application-devel.properties @@ -23,16 +23,16 @@ pdf.converter.url=http://localhost:3000/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=externalUrls/ExternalUrls.xml -configuration.rda=RDACommonStandards.txt +configuration.semantics=Semantics.json configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json -configuration.doi_funder=DOI_Funder.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=classpath:templates/email/email.html email.confirmation=classpath:templates/email/emailConfirmation.html email.merge=classpath:templates/email/emailMergeConfirmation.html +email.unlink=classpath:templates/email/emailUnlinkConfirmation.html #############FACEBOOK LOGIN CONFIGURATIONS######### facebook.login.clientId= @@ -78,8 +78,6 @@ conf_email.expiration_time_seconds=14400 conf_email.subject=OpenDMP email confirmation #############ZENODO CONFIGURATIONS######### -zenodo.url=https://sandbox.zenodo.org/api/ -zenodo.access_token= zenodo.login.access_token_url=https://sandbox.zenodo.org/oauth/token zenodo.login.client_id= zenodo.login.client_secret= diff --git a/dmp-backend/web/src/main/resources/config/application-docker.properties b/dmp-backend/web/src/main/resources/config/application-docker.properties index 1bb017e6e..caeec702f 100644 --- a/dmp-backend/web/src/main/resources/config/application-docker.properties +++ b/dmp-backend/web/src/main/resources/config/application-docker.properties @@ -23,16 +23,15 @@ pdf.converter.url=http://opendmp-pdf:3000/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=externalUrls/ExternalUrls.xml -configuration.rda=RDACommonStandards.txt configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json -configuration.doi_funder=DOI_Funder.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=classpath:templates/email/email.html email.confirmation=classpath:templates/email/emailConfirmation.html email.merge=classpath:templates/email/emailMergeConfirmation.html +email.unlink=classpath:templates/email/emailUnlinkConfirmation.html email.dataset.template=classpath:templates/email/emailAdmin.html ####################INVITATION MAIL CONFIGURATIONS############## @@ -100,14 +99,11 @@ conf_email.expiration_time_seconds=14400 conf_email.subject=OpenDMP email confirmation #############ZENODO CONFIGURATIONS######### -zenodo.url=https://sandbox.zenodo.org/api/ -zenodo.access_token= zenodo.login.access_token_url=https://sandbox.zenodo.org/oauth/token zenodo.login.client_id= zenodo.login.client_secret= zenodo.login.redirect_uri=http://localhost:8080/login/external/zenodo - #############CONTACT EMAIL CONFIGURATIONS######### contact_email.mail= logging.config=classpath:logging/logback-${spring.profiles.active}.xml diff --git a/dmp-backend/web/src/main/resources/config/application-production.properties b/dmp-backend/web/src/main/resources/config/application-production.properties index 296798080..61118ce55 100644 --- a/dmp-backend/web/src/main/resources/config/application-production.properties +++ b/dmp-backend/web/src/main/resources/config/application-production.properties @@ -17,7 +17,6 @@ pdf.converter.url=http://docsbox-web/ ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=externalUrls/ExternalUrls.xml -configuration.rda=RDACommonStandards.txt configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=ConfigurableLoginProviders.json diff --git a/dmp-backend/web/src/main/resources/config/application.properties b/dmp-backend/web/src/main/resources/config/application.properties index 6829aed8a..0135ef7d6 100644 --- a/dmp-backend/web/src/main/resources/config/application.properties +++ b/dmp-backend/web/src/main/resources/config/application.properties @@ -49,16 +49,16 @@ elasticsearch.certKey= ####################CONFIGURATION FILES OVERRIDES CONFIGURATIONS########## configuration.externalUrls=externalUrls/ExternalUrls.xml -configuration.rda=RDACommonStandards.txt +configuration.semantics=Semantics.json configuration.h2020template=documents/h2020.docx configuration.h2020datasettemplate=documents/h2020_dataset.docx configuration.configurable_login_providers=configurableLoginProviders.json -configuration.doi_funder=DOI_Funder.json ####################EMAIL FILE TEMPLATES OVERRIDES CONFIGURATIONS########## email.invite=file:templates/email/email.html email.confirmation=file:templates/email/emailConfirmation.html email.merge=file:templates/email/emailMergeConfirmation.html +email.unlink=classpath:templates/email/emailUnlinkConfirmation.html email.dataset.template=file:templates/email/emailAdmin.html #############LOGIN CONFIGURATIONS######### @@ -111,7 +111,19 @@ database.lock-fail-interval=120000 ##########################MISC########################################## #############USER GUIDE######### -userguide.path=user-guide/ +userguide.path=dmp-backend/web/src/main/resources/material/user-guide + +#############ABOUT######### +about.path=dmp-backend/web/src/main/resources/material/about + +#############TERMS OF SERVICE######### +termsofservice.path=dmp-backend/web/src/main/resources/material/terms-of-service + +#############GLOSSARY######### +glossary.path=dmp-backend/web/src/main/resources/material/glossary + +#############FAQ######### +faq.path=dmp-backend/web/src/main/resources/material/faq #############NOTIFICATION######### notification.rateInterval=30000 diff --git a/dmp-backend/web/src/main/resources/configurableLoginProviders.json b/dmp-backend/web/src/main/resources/configurableLoginProviders.json index c569f0dd6..b2cd6b9ee 100644 --- a/dmp-backend/web/src/main/resources/configurableLoginProviders.json +++ b/dmp-backend/web/src/main/resources/configurableLoginProviders.json @@ -30,6 +30,43 @@ "type": "saml2", "configurableLoginId": "", "name": "" + "name": "", + "spEntityId": "", + "idpEntityId": "", + "idpUrl": "", + "idpMetadataUrl": "", + "idpArtifactUrl": "", + "binding": "Redirect", + "logoUrl": "", + "responseSigned": true, + "assertionSigned": true, + "assertionEncrypted": true, + "encryptionCert" : { + "alias": "", + "password": "", + "keystorePath": "encryptionkeystore.jks", + "keystorePassword": "", + "keyFormat": "JKS" + }, + "signingCert" : { + "alias": "", + "password": "", + "keystorePath": "signingkeystore.jks", + "keystorePassword": "", + "keyFormat": "JKS" + }, + "assertionConsumerServiceUrl": "", + "wantAssertionsSigned": true, + "authnRequestsSigned": true, + "usingFormat": "friendly_name", + "configurableUserFromAttributes": { + "email": "email", + "name": "givenName" + }, + "attributeTypes": { + "email": "XSString", + "givenName": "XSString" + } } ] } diff --git a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml index 665a6ed56..5107fdb99 100644 --- a/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml +++ b/dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml @@ -772,6 +772,8 @@ but not $['results'][*]['result']['metadata']['oaf:entity']['oaf:result'] 'originalId' + pid.content + pid.classid 'title' 'count' @@ -1017,6 +1019,8 @@ but not $['results'][*]['result']['metadata']['oaf:entity']['oaf:organization'] 'originalId' + pid.content + pid.classid 'legalname' 'count' @@ -1098,6 +1102,8 @@ but not 'originalId' 'title' + pid.content + pid.classid 'count' diff --git a/dmp-backend/web/src/main/resources/material/about/About_en.html b/dmp-backend/web/src/main/resources/material/about/About_en.html new file mode 100644 index 000000000..2f0fc37ac --- /dev/null +++ b/dmp-backend/web/src/main/resources/material/about/About_en.html @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + +
+
+
+

About

+
+
+
+
+

ARGOS is an online tool in support of automated processes to creating, managing, sharing and linking DMPs with research artifacts they correspond to. It is the joint effort of OpenAIRE and EUDAT to deliver an open platform for Data Management Planning that addresses FAIR and Open best practices and assumes no barriers for its use and adoption. It does so by applying common standards for machine-actionable DMPs as defined by the global research data community of RDA and by communicating and consulting with researchers, research communities and funders to better reflect on their needs. +

ARGOS provides a flexible environment and an easy interface for users to navigate and use.

+
+
+
+ + + diff --git a/dmp-backend/web/src/main/resources/material/faq/Faq_en.html b/dmp-backend/web/src/main/resources/material/faq/Faq_en.html new file mode 100644 index 000000000..82600bf1d --- /dev/null +++ b/dmp-backend/web/src/main/resources/material/faq/Faq_en.html @@ -0,0 +1,749 @@ + + + + + + + + + + + + + + + + + +
+
+
+

About ARGOS

+

What is ARGOS?

+

Argos is an open and collaborative platform developed by OpenAIRE to facilitate + Research Data Management (RDM) activities concerning the implementation of Data + Management Plans. It uses OpenAIRE guides created by the RDM Task Force to + familiarize users with basic RDM concepts and guide them throughout the process of + writing DMPs. It also utilises the OpenAIRE pool of services and inferred sources to + make DMPs more dynamic in use and easier to be completed and published. Argos is + based on the OpenDMP open source software and is available through the OpenAIRE + Service catalogue and the EOSC.

+ +
+

Is Argos designed for one specific funder, e.g. the EC/Horizon Europe?

+

+ Argos is a flexible tool, designed to accommodate all research performing + and research funding organisations’ policies and Research Data Management (RDM) needs. + It already supports templates for different authorities. + These templates are created by Admin users in Argos. + In addition, we currently work to provide non-administrative users with the capability + to modify templates according to their own needs. +

+
+

Why use Argos?

+

Argos is easy to use and navigate around. It familiarises users with the DMP process + and provides guidance on basic RDM concepts so that users find useful resources to + learn from without having to leave the Argos environment. Users can invite their + colleagues and collaboratively work on completing a DMP. Moreover, Argos is an + integral part of the OpeAIRE ecosystem and the Research + Graph. Argos integrates + other services of the ecosystem to enable contextualisation of information, which is + especially useful when data are re-used, for example to understand how/ if they can + be repurposed.

+
+

Who is Argos for?

+

Argos is designed as a tool for inclusive use by researchers, students, funders, + research communities and institutions. It can be used in the context of research + projects’ conduct to comply with funders’ RDM requirements, as a tool in support of + literacy programmes in academia or can be independently deployed to meet given + stakeholder demands. Also, it is available in native languages, thanks to the help + of OpenAIRE NOADs, which strengthens common understanding of all researchers + involved in the DMP writing process. + By using Argos, researchers and students are able to create their DMPs in + collaboration with other colleagues, learn basic RDM concepts throughout the process + and publish DMPs as outputs in an open and FAIR manner, among other things by + assigning DOIs and licenses and by maintaining DMPs as living documents through + versioning. + At the same time, Argos can be configured and deployed by funders, institutions and + research communities. They can plug in their own services and/ or make use of + OpenAIRE underlying services that Argos is built with ad-hoc.

+
+

Using Argos

+

+ Argos consists of two main functionalities: DMPs and Datasets. + Argos can be used for: +

+ A. Viewing/ consulting publicly released DMPs and Datasets or Projects + corresponding to + DMPs +

+ Argos offers options for publishing DMPs in two modes, private or public. To view + public DMPs and Datasets, there is no need for login to the platform. +

+ B. Writing and publishing a DMP +

+ Argos helps researchers comply with mandates that may be attached to their grant + proposal/ project funding. They can therefore choose from the most suitable to their + needs template from the Datasets collection and proceed with answering the + corresponding questions. Once finalized, researchers can assign a DOI to their DMP, + publish and eventually cite it. +

+ C. Practicing on writing DMPs and Dataset Descriptions +

+ Argos may be used for educational purposes. The process of Data Management Planning + reflects the data management lifecycle, hence the tool can be used in response to + global RDM training demands. Examples may refer to embedding DMPs and DMP tools in + specific curricula or be embedded in library instructions’ sessions to familiarize + researchers and students the processes of RDM and DMP. +

+
+

Can I exploit ARGOS DMPs?

+

+ Of course. If you want to compare DMPs or analyse DMP data, then we advise you to export the records in .xml. + This schema is the most complete as it includes all information held in a DMP: information provided by the Admin + when structuring the template and input provided by researchers when completing their DMPs. +

+
+

Manage Account

+

Log in and out of Argos

+

+ You can log in Argos by selecting one of the providers from the Login page. Argos + does not require Sign Up. +

+
+

Create an administrator account

+

+ If you are interested in becoming an administrator in Argos and benefit from extra + features relevant to creating tailored templates, please email argos@openaire.eu . +

+ +
+

+ Switch from administrator account +

+

+ There is no need to switch from your administrator account to use Argos. The only + difference between regular users and administrators profiles in Argos is an extra + set of tools at the bottom of the main tool bar that is positioned on the left + handside. +

+
+

+ Change your email +

+

+ Argos does not have Sign Up. To change email, please see “Switch between accounts”. + Alternatevily, you can add more email addresses to your user account by selecting + the “Add alternative email” from your profile. +

+
+

+ Switch between accounts +

+

+ You can switch between email accounts by loging in with different providers from the + Login page. The change depends on whether you have used different email addresses to + sign up with those providers. On the occassion that only one email address is used + for all providers offered by Argos, then no change is expected. You can always add + new email accounts in your profile from the “Add alternative email” in your profile + page. +

+
+

+ Delete your account +

+

+ If you want to delete your Argos profile, please email argos@openaire.eu . +

+
+

+ Accounts access and safety +

+

+ How can I access my account and edit my profile? +

+

+ You can access your profile page and make desired edits from clicking on the avatar + at the very top of the toolbar located on the right handside. +

+
+

+ Can’t login to ARGOS +

+

+ Please try using a different provider from the Login page and contact us at: + argos@openaire.eu . +

+
+

+ Accessing Argos +

+

+ If you are reading this right now, you probably know the answer already! One way to + access Argos is through the OpenAIRE Service + catalogue. Another way is through the + EOSC + Catalogue. But, you can always find Argos at + argos.openaire.eu . + To access Argos software, please visit + https://code-repo.d4science.org/MaDgiK-CITE/argos/src/branch/master + . +

+
+

Argos User Roles

+

+ Who is the author of a DMP? +

+

+ Author of the DMP is everyone contributing to writing the DMP. Both Argos owners and + Argos members are DMP authors. Researchers, however, are not DMP authors. +

+
+

+ What is the difference between owners and + members? +

+

+ Argos DMP owner is the person initiating the DMP. People who are invited to join the + DMP process are members who contribute to writing the DMP. DMP owners have extra + editing rights and they are the ones to finalize the DMP process. Members can view + and edit DMPs and Datasets, but can not perform further actions for its validation + or finalization. +

+
+

+ What is the role of a researcher in Argos? +

+

+ Researchers in Argos are project contributors and usually those who own or have + managed data described in respective DMPs. +

+
+

+ Can a researcher be a DMP author? +

+

+ Of course! This depends on whether the researcher has also been involved in the DMP + writing process. +

+
+

+ What does an Admin user do? +

+

+ Not everyone can become an Admin user in Argos. This happens upon request at + argos@openaire.eu. Admin users are able to create + their own tailored templates from + a specialised editor, configure their own APIs and integrate services with Argos in + collaboration with and support of the Argos development team. Fees may apply + according to the type of requests. +

+
+

Creating DMPs

+

+ I can’t find my project in the list. What should + I do? +

+

+ DMPs that are created as part of the project proposal are not included in Argos. + Only accepted project proposals are listed in the platform. If you can’t find your + project in the list (drop-down menu), please use the “Insert manually” + functionality. +

+
+

+ I can’t find my grant in the list. What should I + do? +

+

+ If you can’t find your grant in the list (drop-down menu), please use the “Insert + manually” functionality. +

+
+

+ How do I edit and design my own DMP + template? +

+

+ You have to be an Admin user to design your own template in Argos. To learn more + about Admin users, check “What does an Admin user do?”. +

+
+

+ Can I create my own templates in Argos? +

+

+ Yes, you can, provided that you are an Admin user. To learn more about Admin users, + check “What does an Admin user do?”. +

+
+

+ What is the difference between “Save”, “Save & + Close”, “Save & Add New”? +

+
+

They all perform the same action, but the difference lies in where you are directed + after you have saved your DMP or Dataset.

+
    +
  • + When choosing Save, information that you have added in the editor is kept + and you + can continue adding more from the same page you were working on. +
  • +
  • + When choosing Save & Close, information that you have added is kept, but the + editor’s window closes and you are redirected to your dashboard. +
  • +
  • + [only for datasets] When choosing Save & Add New, information that you have + added is + kept, and you are redirected to another editor to start a new dataset. +
  • +
+
+
+

+ Can I modify things once I have finalized + them? +

+

+ Yes, you can, as long as you haven’t assigned a DOI to your DMP. You just select + “Undo Finalization”. +

+
+

+ How do I invite collaborators? +

+

+ You may use the “Invite” button to share DMPs with your colleagues and start working + on them together. +

+
+

+ Can scientists collaborate on the same DMP even though they may belong to different institutions (e.g. a hospital, a University, etc, collaborating on a project) and the dataset also "belongs" to different institutions? +

+

+ Of course. Argos supports collaborations across diverse teams. There are two most frequent ways that can address this question: +

+ A. Everyone works on the same DMP, but on different dataset descriptions +

+ In this case, each organisation makes its own dataset description(s) in a single DMP. + That means that the manager (i.e. person responsible for the DMP activity) creates a DMP in ARGOS + and shares it with everyone. If the DMP is shared with co-ownership rights, + then the people will be able to edit it and add their dataset descriptions at any time during the project. + If there is the need to control editing rights of people writing the DMPs, then the manager can create the dataset description(s) + and share these each time with the team members that are responsible for adding input for the specified datasets. +

+ B. Everyone works on their own DMP and content is later merged into one single DMP +

+ In this case, each organisation might work on their own DMP for the same project. + At one point, you need to decide which DMP is going to be the core for the work you perform, share co-ownership + between managers of all DMPs so they can copy all dataset descriptions of their DMPs in this single DMP document. +

+
+

+ How do I create an identical DMP or Dataset as a + copy? +

+

+ DMPs and Datasets can be cloned and used in different research contexts. + Existing DMPs presenting similarities with new ones, can be cloned, changed name and + then edited according to the new project data requirements. + Existing Datasets can be cloned and used in new DMPs that are reusing data described + in their context. +

+
+

+ What is the DMP version? How is it set? +

+

+ Versioning in Argos is both an internal and an external process. That means that + versioning happens both in the Argos environment when editing the DMP, and outside + of Argos when a DMP output is published in Zenodo. At every stage of the DMP + lifecycle, users have the option of keeping versions of the DMPs they are editing. + In Argos, users can create new versions of their DMPs by selecting the “Start New + Version” option to keep track of the evolution of their DMP throughout the writing + process. When published, versioning is associated with a DOI. Published DMPs are + automatically versioned every time a newer version of the same output is uploaded in + Zenodo. +

+
+

+ DMPs and Datasets +

+

+ What is the DMP? +

+

+ A DMP in Argos consists of vital information about the research project on behalf of + which the DMP is created and of more in depth information about the management, + handling and curation of datasets collected, produced or reused during the research + lifetime. A DMP in Argos accommodates documentation of more than one datasets. That + way datasets are provided with the flexibility to be described separately, following + different templates per type of dataset or research community concerned each time, + also possible to be copied and used in multiple DMPs. Datasets are then bundled up + in a DMP and can be shared more broadly. Special attention is given to the handling + of data that are being re-used via OpenAIRE APIs. +

+
+

+ How do I find which Dataset template to use? +

+

+ This depends on the reason why you are creating a DMP in the first place. If it is + for compliance matters with funders, institutions or research communities RDM + policies, then you may select the dataset template of that particular stakeholder. + If you are creating a DMP for training purposes, you may select and work on any + template from the Argos collection. +

+
+

+ How do I create my own Dataset template? +

+

+ Currently, it is not possible for all Argos users to create dataset templates of + their own, so they have to work on predefined templates. Additional rights for + editing Dataset templates according to tailored needs have Admin users. This is + expected to change in the near future. To learn more about Admin users, check “What + does an Admin user do?”. +

+
+

+ Can I create smaller versions of a template for project proposals? +

+

+ Yes, it is possible in Argos to create short versions of templates that can be used + for grant proposals, such as for Horizon Europe. + If you are interested in working with us to create this short version of any ARGOS template, + please contact us: argos@openaire.eu. +

+
+

+ Can I customise an existing template (e.g. for a specific institution)? +

+

+ Yes, you can. In the current version, this is possible for Admin users who have their own deployment on-premises or cloud. + Please note that this subject to change in the near future as we are working on a feature that will allow all users + to customise (remove/add/extend) specific questions on the template they are working on. +

+
+

+ What is a Dataset? +

+

+ A Dataset in Argos is an editor with set up questions that support the creation of + descriptions of how data are / have been handled, managed and curated throughout the + research data lifecycle. The editor holds a collection of Dataset templates each one + with different sets of predefined questions as per funders, institutions, research + communities RDM policy requirements. Researchers and students can choose the + template that corresponds to their RDM needs in order to get funding or get their + degree, respectively. A DMP in Argos may consist of one or more datasets. +

+
+

+ Why do I need more than one Dataset? +

+

+ You don’t necessarily need to have many Datasets in a DMP. However, you might be + producing a plethora of data during your research that are diverse in type and/ or + scope of collection/ re-use, thus presenting diverse management needs. Argos gives + you the flexibility to describe all data produced and/ or re-used in your research + separately. That way it is easy to perform the mapping of information provided in a + DMP to the respective data types or data collections they correspond to. Equally, + reuse of particular datasets in different DMPs is easier. For the latter, please + check “How do I create an identical DMP or Dataset as a copy?”. +

+
+

+ It is not very clear to me when one should choose to add a dataset or to describe several "data products" in the same description. +

+

+ This is something that has to be tackled conceptually, from the author of the DMP. + If those "products" have their own lifetime and rules (IPR, Access rights, etc), they should be described as different datasets. + Alternative formats should not be treated as different datasets, unless they have other differences due to the format, too. + But, for instance, if you have datasets in CSV and JSON formats and under the same terms, they could be seen as one dataset description in the DMP. +

+
+

+ Can I add to my DMP information about datasets published on Zenodo? +

+

+ Argos offers a search to Zenodo for prefilling the DMP you are working with dataset metadata. + This search has been developed according to the rules set by Zenodo + and therefore has the same behaviour as when you are using the search bar on the Zenodo interface. + However, we understand the need to be able to find records with their PID, + hence we introduced some changes and now support searching DOIs from the Argos interface. +

+
+

+ Is it possible to describe a dataset that is not yet in a repository? +

+

+ Of course! You can choose to manually describe your dataset, e.g. for a dataset you are planning to produce, + instead of pre-filling the template with available metadata from a dataset that has already been shared and preserved in a repository. +

+
+

+ What are public DMPs and Datasets? +

+

+ Public DMPs and Public Datasets are collections of openly available Argos outputs. + That means that DMP owners and members are making their DMP and/or Dataset outputs + available to all Argos and non-Argos users who might want to consult or re-use them + under the framework provided by the assigned DMP license. Please also check “Is all + the information I create visible by default?”. +

+
+

+ Is all information I create visible by + default? +

+

+ No, it is not. You can choose how your DMP is displayed in Argos from the + “Visibility” option. Choosing Public will immediately locate your DMP in the “Public + DMPs” collection and make it available to all Argos and non-Argos users. + Choosing Private will keep the DMP visible only to you and to the people invited to + edit the DMP in collaboration with you. Private DMPs are not publicly displayed to + other users. +

+
+

+ What is the difference between the DMP and the dataset export? +

+

+ DMP export contains all vital information for a DMP, including funding and dataset details, + while dataset export is a subset of the DMP export containing information only about a dataset described in the DMP. + Both DMP and Dataset exports are available in .pdf, .docx, .xml. + In addition, DMP export is available in the RDA .json format + to increase interoperability of ARGOS exchanged DMPs. +

+
+

+ Is there a storage allowance limitation for the + DMPs and Dataset files? +

+

+ No, there is no storage limit or fee for either files stored in Argos. +

+
+

+ Publishing DMPs +

+

+ Is it possible to publish DMPs in different repositories (so not Zenodo)? +

+

+ Yes, it is possible. + But, to have different repositories attached to the system, you will need your own on-premises or cloud deployment. + We are already working on that for DSpace and Dataverse repositories. +

+
+

+ Do you know that Zenodo has empty DMPs from ARGOS? +

+

+ Yes, we are aware of that. + Argos has no control over the DMPs that you generate and publish and thus can not be held accountable for empty DMPs. + Please remember that, as on all other occasions where you publish content, you should do so responsinbly. + If you have any questions regarding publishing DMPs, don’t hesitate to contact us at argos@openaire.eu. +

+
+

+ Once I upload a final version of a DMP to Zenodo, do I need to update this first final version from Zenodo or from Argos? +

+

+ Both options are possible according to how you have deposited the DMP in the first place. + If you have deposited your DMP with a token (i.e. from the ARGOS account on Zenodo), + then you won’t have editing rights on the Zenodo record, but you will still be able to make changes + on ARGOS by starting and depositing a new version of the published DMP. + However, if you have deposited your DMP using your own account on Zenodo (i.e. login to Zenodo with your own credentials), + then you are able to also make minor changes, e.g. on the title of the DMP, directly from the Zenodo interface. +

+
+

Troubleshooting

+

+ Can’t finalize a DMP +

+

+ You might be experiencing this problem because there are incomplete mandatory fields + in your DMP. Please check for those fields, fill in with appropriate information and + try again. Should the problem persists, please contact argos@openaire.eu . +

+
+

+ Can’t co-edit a DMP +

+

+ DMPs can be shared with many colleagues in support of collaborative writing, but + DMPs should be worked by one person at a time. Argos will inform you if another + colleague has the DMP you are trying to edit open, so that your team avoids + information loss. +

+
+

+ Deposit is not working +

+

+ You need to have a Zenodo login to perform a deposit. Please sign up in Zenodo or + use the token option to publish your DMPs and get a DOI. +

+
+

Legal and privacy

+

+ Is Argos open source? +

+

+ Yes, it is. The OpenDMP software that Argos has deployed upon is open source code + available under Apache 2.0 license. You may find more information about the software + here. +

+
+

+ Can I contribute to Argos development? +

+

+ Of course! Please feel free to suggest new features and to actively contribute to + Argos development via pull requests in Gitea. +

+
+

+ Is Argos GDPR compliant? +

+

+ Argos takes all necessary steps in handling and protecting personal and sensitive + information. Please check the Argos Terms of Service and Privacy Policy. +

+
+

+ Which is the Argos data policy? +

+

+ Please find all information about Argos Terms of Service and Privacy, here. + Additionally, you may find Argos Cookies policy, here. +

+
+

+ What is the work ownership of information + created in Argos? +

+

+ Unless there are any contractual or institutional agreements stating ownership of + outputs produced in the context of a project/ collaboration, owners of Argos outputs + are DMP contributors, i.e. DMP owners and DMP members, who have been involved with + writing the DMP. +

+
+

+ Which are the terms and policies of Argos? +

+

+ Please find all information about Argos Terms of Service and Privacy, here. + Additionally, you may find Argos Cookies policy, here. +

+ + +
+
+
+ + + diff --git a/dmp-backend/web/src/main/resources/material/glossary/Glossary_en.html b/dmp-backend/web/src/main/resources/material/glossary/Glossary_en.html new file mode 100644 index 000000000..e1ee6253c --- /dev/null +++ b/dmp-backend/web/src/main/resources/material/glossary/Glossary_en.html @@ -0,0 +1,94 @@ + + + + + + + + + + + + + + + + + +
+
+
+

Glossary

+
+
+
+
+

DMP

+

A DMP - short for Data Management Plan - is a document describing the processes that the data have undergone and the tools used for their handling and storage during a research lifecycle. Most importantly, DMPs secure provenance and enable re-use of data by appointing data managers and by including information on how data can be re-used by others in the future. Therefore, a DMP is a living document which is modified according to the data developments of a project before it’s completed and handed over at the end of the project. + Public funders increasingly contain DMPs in their grant proposals or policy funding requirements. A good paradigm is the European Commission demands for the production and delivery of DMPs for projects funded under the Horizon 2020 Funding Programme. On that note, and to encourage good data management practices uptake, many European institutions include DMPs in post-graduate researchers policies and offer relevant support to staff and students. +

+ +

DMP template

+

DMP template contains general but vital information about the name and the duration of the project that the DMP corresponds to, the contributing organisations and individuals as well as the datasets that are under the Dataset Description section. It also offers the possibility of describing datasets other than primary data generated, under “External References” section. A DMP template can have many Dataset Descriptions. +

+ +

Dataset Description

+

Dataset Description documents the management processes of datasets following funder’s or institution’s requirements. A dataset description is essentially a questionnaire template with underlying added value services for interoperability and machine readability of information which is developed based on the given requirements. Management requirements differ from funder to funder and from institution to institution, hence the growing collection of Dataset Descriptions to select from. + Moreover, a Dataset Description links to the documentation of one dataset, hence a DMP template may contain more than one dataset descriptions on the occasion when multiple datasets were used during the project. When documentation of some of the project’s datasets falls under additional requirements (e.g. projects receiving multiple grants from different sources), there is the possibility of describing datasets with more than one Dataset Description template. +

+
+
+
+ + + diff --git a/dmp-backend/web/src/main/resources/material/terms-of-service/TermsOfService_en.html b/dmp-backend/web/src/main/resources/material/terms-of-service/TermsOfService_en.html new file mode 100644 index 000000000..2bcaaeb33 --- /dev/null +++ b/dmp-backend/web/src/main/resources/material/terms-of-service/TermsOfService_en.html @@ -0,0 +1,115 @@ + + + + + + + + + + + + + + + + + +
+
+
+

Terms of Service

+
+
+
+
+

The OpenDMP service was developed to provide a more flexible, collaborative environment with machine actionable solutions in writing, sharing and publishing Data Management Plans (DMPs). It is a product of cooperation between OpenAIRE AMKE and EUDAT CDI and is offered both as a software “OpenDMP '' and as an online service under the name “ARGOS”.

+

+
    +
  1. OpenDMP software is offered under the Free Open Source Software license  Apache 2.0, for further development and use by institutions and interested parties.
  2. +
  3. ARGOS service is offered by OpenAIRE as part of its mission to support Open Science in the European Research Area, focusing on information linking and contextualisation that enriches its Research Graph. Use of ARGOS denotes agreement with the following terms: +
      +
    1. ARGOS is a software interface and a database with no storage capacity to store or preserve research data. The DMPs created are hosted in the OpenAIRE production environment for the sole purpose of exposing the DMP records once finalised (“published”). If assigned a DOI, the DMP records are linked to and preserved in Zenodo, the OpenAIRE’s repository service. The ARGOS service is made available for use free-of-charge for research, educational and informational purposes.
    2. +
    3. Login to ARGOS is possible through a variety of external providers, among which Google, Facebook, Twitter, B2Access and OpenAIRE Login, that share information of their user profiles with ARGOS, according to the rights that have been granted to the given provider by the user. External email addresses that are used in invitations for collaborations are held in ARGOS database that stores information about only the name, surname and email address of the DMP creator and collaborator.  Personal data is collected via the login option and via email invitations sent to external DMP contributors. This personal information as well as the activity of ARGOS users is used only for deriving usage metrics and assessing the service quality. They are stored in ARGOS database for as long as the account is active and they are accessible only from people in the team in charge of quality and risk assessment. They will not be used for other purposes other than the ones stated in this document and they can be deleted at any time should the user claim a relevant request. The aforementioned processes are also facilitated by the use of cookies (see below the “Cookie policy”).
    4. +
    5. Data concerning DMP information will be used by OpenAIRE for research and development purposes, such as identifying DMP models, and for ensuring compliance with policy requirements and monitoring of DMPs uptake linked to OpenAIRE’s Monitoring Dashboards and the Open Science Observatory.
    6. +
    7. The DMP Manager, i.e. the person who creates and manages a DMP, and/ or the contributor, i.e. the person who is invited to collaborate on a DMP, shall ensure that content is accurate and presented in a way that adheres to these Terms of Service and applicable laws, including, but not limited to, privacy, data protection and intellectual property rights.
    8. +
    9. ARGOS service is provided by OpenAIRE “as is”. Although OpenAIRE and its partners take measures for the availability, dependability, and accuracy of the service, access to ARGOS, utilisation of its features and preservation of the data deposited or produced by the service are not guaranteed. OpenAIRE cannot be held responsible for any data loss regarding DMPs, ethical or financial damage or any other direct or indirect impact that any failure of ARGOS service may have on its users.  
    10. +
    11. ARGOS users are exclusively responsible for their use of content, and shall hold OpenAIRE free and harmless in connection with their download and/or use.
    12. +
    13. OpenAIRE may not be held responsible for the content provided or statements made in Data Management Plans created and managed by its users.
    14. +
    15. All content is provided “as-is”. Users of content (“Users”) shall respect applicable license conditions. Download and use of content from ARGOS does not transfer any intellectual property rights in the content to the User.
    16. +
    17. In the case any content is reported as violating third party rights or other legal provisions, ARGOS reserves the right to remove the content from the service until the dispute is legally settled. Any such incidents should be reported at noticeandtakedown@openaire.eu 
    18. +
    19. ARGOS users are held responsible for the data and information they provide in the service. Users may not add information, data or any other type of artifact that may be malicious, intentionally erroneous and potentially harmful for other ARGOS users, IPR owners and/or the general public.
    20. +
    21. In case a user of ARGOS identifies a potential infringement of copyright, harmful or malicious operation, function, code, information or data, shall inform OpenAIRE providing sufficient evidence for the identification of the case and the information and/or data challenged.
    22. +
    23. OpenAIRE reserves the right, without notice, at its sole discretion and without liability, (i) to alter or delete inappropriate content, and (ii) to restrict or remove User access where it considers that use of ARGOS interferes with its operations or violates these Terms of Service or applicable laws.
    24. +
    25. These Terms of Service are subject to change by OpenAIRE at any time and without notice, other than through posting the updated Terms of Service on the OpenAIRE website and indicating the version and date of last update.
    26. +
    +
  4. +
+

For any questions or comments you may have about the current Terms of Service, please contact us: argos@openaire.eu 

+
+
+
+ + + diff --git a/user-guide/UserGuide_de.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_de.html similarity index 100% rename from user-guide/UserGuide_de.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_de.html diff --git a/user-guide/UserGuide_en.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_en.html similarity index 100% rename from user-guide/UserGuide_en.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_en.html diff --git a/user-guide/UserGuide_es.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_es.html similarity index 100% rename from user-guide/UserGuide_es.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_es.html diff --git a/user-guide/UserGuide_gr.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_gr.html similarity index 100% rename from user-guide/UserGuide_gr.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_gr.html diff --git a/user-guide/UserGuide_pt.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_pt.html similarity index 100% rename from user-guide/UserGuide_pt.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_pt.html diff --git a/user-guide/UserGuide_sk.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_sk.html similarity index 100% rename from user-guide/UserGuide_sk.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_sk.html diff --git a/user-guide/UserGuide_sr.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_sr.html similarity index 100% rename from user-guide/UserGuide_sr.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_sr.html diff --git a/user-guide/UserGuide_tr.html b/dmp-backend/web/src/main/resources/material/user-guide/UserGuide_tr.html similarity index 100% rename from user-guide/UserGuide_tr.html rename to dmp-backend/web/src/main/resources/material/user-guide/UserGuide_tr.html diff --git a/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html new file mode 100644 index 000000000..7f6ce7c8d --- /dev/null +++ b/dmp-backend/web/src/main/resources/templates/email/emailUnlinkConfirmation.html @@ -0,0 +1,304 @@ + + + + + + Simple Transactional Email + + + + + + + + + +
  +
+ + + This is preheader text. Some clients will show this text as a preview. + + + + + + + + +
+ + + + +
+ OpenDMP +

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

+

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

+ + + + + + +
+ + + + + + +
Confirm Unlink Request
+
+
+
+ + + + + + +
+
 
+ + \ No newline at end of file diff --git a/dmp-frontend/angular.json b/dmp-frontend/angular.json index c1a3f7752..4c12d5745 100644 --- a/dmp-frontend/angular.json +++ b/dmp-frontend/angular.json @@ -30,7 +30,6 @@ "scripts": [ "node_modules/cookieconsent/build/cookieconsent.min.js", "node_modules/tinymce/tinymce.min.js" - ], "vendorChunk": true, "extractLicenses": false, diff --git a/dmp-frontend/src/app/app-routing.module.ts b/dmp-frontend/src/app/app-routing.module.ts index 120a88ec1..3cba707ac 100644 --- a/dmp-frontend/src/app/app-routing.module.ts +++ b/dmp-frontend/src/app/app-routing.module.ts @@ -224,6 +224,13 @@ const appRoutes: Routes = [ title: 'GENERAL.TITLES.INDEX-MANAGMENT' }, }, + { + path: 'maintenance-tasks', + loadChildren: () => import('./ui/admin/maintenance-tasks/maintenance-tasks.module').then(m => m.MaintenanceTasksModule), + data: { + breadcrumb: true + }, + }, { path: 'login/admin', loadChildren: () => import('./ui/auth/admin-login/admin-login.module').then(m => m.AdminLoginModule), diff --git a/dmp-frontend/src/app/app.module.ts b/dmp-frontend/src/app/app.module.ts index 58c45d346..fac755393 100644 --- a/dmp-frontend/src/app/app.module.ts +++ b/dmp-frontend/src/app/app.module.ts @@ -22,7 +22,7 @@ import { SidebarModule } from '@app/ui/sidebar/sidebar.module'; import { MomentUtcDateAdapter } from '@common/date/moment-utc-date-adapter'; import { CommonHttpModule } from '@common/http/common-http.module'; import { CommonUiModule } from '@common/ui/common-ui.module'; -import { TranslateLoader, TranslateModule } from '@ngx-translate/core'; +import { TranslateCompiler, TranslateLoader, TranslateModule } from '@ngx-translate/core'; import { DragulaModule } from 'ng2-dragula'; import { CookieService } from 'ngx-cookie-service'; import { NgcCookieConsentConfig, NgcCookieConsentModule } from 'ngx-cookieconsent'; @@ -32,6 +32,7 @@ import { CultureService } from './core/services/culture/culture-service'; import { TranslateServerLoader } from './core/services/language/server.loader'; import { MatomoService } from './core/services/matomo/matomo-service'; import { GuidedTourModule } from './library/guided-tour/guided-tour.module'; +import { OpenDMPCustomTranslationCompiler } from './utilities/translate/opendmp-custom-translation-compiler'; import { Oauth2DialogModule } from './ui/misc/oauth2-dialog/oauth2-dialog.module'; // AoT requires an exported function for factories @@ -84,6 +85,7 @@ const appearance: MatFormFieldDefaultOptions = { AppRoutingModule, CommonUiModule, TranslateModule.forRoot({ + compiler: { provide: TranslateCompiler, useClass: OpenDMPCustomTranslationCompiler }, loader: { provide: TranslateLoader, useFactory: HttpLoaderFactory, diff --git a/dmp-frontend/src/app/core/core-service.module.ts b/dmp-frontend/src/app/core/core-service.module.ts index b36cf42f8..5186586e6 100644 --- a/dmp-frontend/src/app/core/core-service.module.ts +++ b/dmp-frontend/src/app/core/core-service.module.ts @@ -47,6 +47,11 @@ 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'; +import { AboutService } from './services/about/about.service'; +import { FaqService } from './services/faq/faq.service'; +import { GlossaryService } from './services/glossary/glossary.service'; +import { TermsOfServiceService } from './services/terms-of-service/terms-of-service.service'; +import { UnlinkAccountEmailConfirmationService } from './services/unlink-account-email-confirmation/unlink-account-email-confirmation.service'; // // // This is shared module that provides all the services. Its imported only once on the AppModule. @@ -112,8 +117,13 @@ export class CoreServiceModule { LanguageService, LockService, UserGuideService, + AboutService, + FaqService, + GlossaryService, + TermsOfServiceService, CurrencyService, MergeEmailConfirmationService, + UnlinkAccountEmailConfirmationService, ConfigurationService, { provide: APP_INITIALIZER, 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 01890e243..8f8ec30d7 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 @@ -59,7 +59,7 @@ export interface Field { data: any; visible: Visibility; validations: ValidationType[]; - rdaCommonStandard: string; + schematics: string[]; export: boolean; } diff --git a/dmp-frontend/src/app/core/model/unlink-account/unlink-account.ts b/dmp-frontend/src/app/core/model/unlink-account/unlink-account.ts new file mode 100644 index 000000000..89c6aa33a --- /dev/null +++ b/dmp-frontend/src/app/core/model/unlink-account/unlink-account.ts @@ -0,0 +1,5 @@ +export class UnlinkAccountRequestModel { + userId: String; + email: String; + provider: number; +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/about/about.service.ts b/dmp-frontend/src/app/core/services/about/about.service.ts new file mode 100644 index 000000000..404563c3e --- /dev/null +++ b/dmp-frontend/src/app/core/services/about/about.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@angular/core"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { HttpClient, HttpResponse } from "@angular/common/http"; +import { Observable } from "rxjs"; + +@Injectable() +export class AboutService { + private aboutUrl : string; + + constructor( + private http: HttpClient, + private configurationService: ConfigurationService + ) { + this.aboutUrl = `${configurationService.server}material/about`; + } + + public getAbout(lang: string): Observable> { + return this.http.get(`${this.aboutUrl}/${lang}`, { responseType: 'blob', observe: 'response', headers: {'Content-type': 'text/html', + 'Accept': 'text/html', + 'Access-Control-Allow-Origin': this.configurationService.app, + 'Access-Control-Allow-Credentials': 'true'} }); + } +} \ No newline at end of file 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 64082cb55..469f1fce9 100644 --- a/dmp-frontend/src/app/core/services/configuration/configuration.service.ts +++ b/dmp-frontend/src/app/core/services/configuration/configuration.service.ts @@ -41,6 +41,11 @@ export class ConfigurationService extends BaseComponent { return this._defaultLanguage; } + private _availableLanguages: any[] = []; + get availableLanguages(): any[] { + return this._availableLanguages; + } + private _loginProviders: LoginProviders; get loginProviders(): LoginProviders { return this._loginProviders; @@ -127,6 +132,7 @@ export class ConfigurationService extends BaseComponent { this._helpService = HelpService.parseValue(config.HelpService); this._defaultCulture = config.defaultCulture; this._defaultLanguage = config.defaultLanguage; + this._availableLanguages = config.availableLanguages; this._loginProviders = LoginProviders.parseValue(config.loginProviders); this._logging = Logging.parseValue(config.logging); this._lockInterval = config.lockInterval; diff --git a/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts b/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts index 66208bd08..521b71da7 100644 --- a/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts +++ b/dmp-frontend/src/app/core/services/dataset-profile/dataset-profile.service.ts @@ -19,9 +19,6 @@ import { ConfigurationService } from '../configuration/configuration.service'; @Injectable() export class DatasetProfileService extends BaseService { - private rdaCommonStandards: String[]; - private rdaCommonStandardsLoading: boolean; - private actionUrl: string; private headers = new HttpHeaders(); @@ -68,26 +65,20 @@ export class DatasetProfileService extends BaseService { return this.httpClient.get(this.actionUrl + 'getXml/' + id, { responseType: 'blob', observe: 'response', headers: headerXml }); } - uploadFile(file: FileList, labelSent: string): Observable> { + uploadFile(file: FileList, labelSent: string, datasetProfileId?: string): Observable> { const params = new BaseHttpParams(); params.interceptorContext = { excludedInterceptors: [InterceptorType.JSONContentType] }; const formData = new FormData(); formData.append('file', file[0], labelSent); - return this.http.post(this.actionUrl + "upload", formData, { params: params }); + return (datasetProfileId === undefined || datasetProfileId == null) + ? this.http.post(this.actionUrl + "upload", formData, { params: params }) + : this.http.post(this.actionUrl + "upload/" + datasetProfileId, formData, { params: params }); + } - getRDACommonStandards(): String[] { - if (!this.rdaCommonStandards && !this.rdaCommonStandardsLoading) { this.getRDACommonStandardsInternal(); } - return this.rdaCommonStandards; - } - - private getRDACommonStandardsInternal() { - this.rdaCommonStandardsLoading = true; - return this.http.get(this.actionUrl + "getRDACommonStandards").pipe(takeUntil(this._destroyed)).subscribe(x => { - this.rdaCommonStandards = x; - this.rdaCommonStandardsLoading = false; - }); + searchSemantics(like: string): Observable { + return this.http.get(this.actionUrl + "getSemantics?query=" + like); } } diff --git a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts index ce1bc9d0d..c85650c00 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -114,10 +114,6 @@ export class DmpService { return this.http.post(`${this.actionUrl}updateusers/${id}`, users, { headers: this.headers }); } - getDoi(id: string): Observable { - return this.http.post(this.actionUrl + 'createZenodoDoi/' + id, { headers: this.headers }); - } - getDynamicField(requestItem: RequestItem): any { return this.http.post(this.actionUrl + 'dynamic', requestItem, { headers: this.headers }); } diff --git a/dmp-frontend/src/app/core/services/faq/faq.service.ts b/dmp-frontend/src/app/core/services/faq/faq.service.ts new file mode 100644 index 000000000..c59cfe9cd --- /dev/null +++ b/dmp-frontend/src/app/core/services/faq/faq.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@angular/core"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { HttpClient, HttpResponse } from "@angular/common/http"; +import { Observable } from "rxjs"; + +@Injectable() +export class FaqService { + private faqUrl : string; + + constructor( + private http: HttpClient, + private configurationService: ConfigurationService + ) { + this.faqUrl = `${configurationService.server}material/faq`; + } + + public getFaq(lang: string): Observable> { + return this.http.get(`${this.faqUrl}/${lang}`, { responseType: 'blob', observe: 'response', headers: {'Content-type': 'text/html', + 'Accept': 'text/html', + 'Access-Control-Allow-Origin': this.configurationService.app, + 'Access-Control-Allow-Credentials': 'true'} }); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/glossary/glossary.service.ts b/dmp-frontend/src/app/core/services/glossary/glossary.service.ts new file mode 100644 index 000000000..c346074bd --- /dev/null +++ b/dmp-frontend/src/app/core/services/glossary/glossary.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@angular/core"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { HttpClient, HttpResponse } from "@angular/common/http"; +import { Observable } from "rxjs"; + +@Injectable() +export class GlossaryService { + private glossaryUrl : string; + + constructor( + private http: HttpClient, + private configurationService: ConfigurationService + ) { + this.glossaryUrl = `${configurationService.server}material/glossary`; + } + + public getGlossary(lang: string): Observable> { + return this.http.get(`${this.glossaryUrl}/${lang}`, { responseType: 'blob', observe: 'response', headers: {'Content-type': 'text/html', + 'Accept': 'text/html', + 'Access-Control-Allow-Origin': this.configurationService.app, + 'Access-Control-Allow-Credentials': 'true'} }); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/language/language.service.ts b/dmp-frontend/src/app/core/services/language/language.service.ts index b37a36b20..4b343591d 100644 --- a/dmp-frontend/src/app/core/services/language/language.service.ts +++ b/dmp-frontend/src/app/core/services/language/language.service.ts @@ -7,8 +7,6 @@ import { BaseHttpService } from '../http/base-http.service'; import { Language } from '@app/models/language/Language'; import { ConfigurationService } from '../configuration/configuration.service'; -const availableLanguages: any[] = require('../../../../assets/resources/language.json'); - @Injectable() export class LanguageService { private currentLanguage: string; @@ -43,7 +41,7 @@ export class LanguageService { public getCurrentLanguageName() { let result: string = ''; - availableLanguages.forEach(language => { + this.configurationService.availableLanguages.forEach(language => { if (language.value === this.currentLanguage) { result = this.translate.instant(language.label); } diff --git a/dmp-frontend/src/app/core/services/logging/logging-service.ts b/dmp-frontend/src/app/core/services/logging/logging-service.ts index b8d8a2629..24b9d2645 100644 --- a/dmp-frontend/src/app/core/services/logging/logging-service.ts +++ b/dmp-frontend/src/app/core/services/logging/logging-service.ts @@ -44,17 +44,17 @@ export class LoggingService { switch (level) { case LogLevel.Debug: // tslint:disable-next-line:no-console - console.debug(objects.join(', ')); + // console.debug(objects.join(', ')); break; case LogLevel.Info: // tslint:disable-next-line:no-console - console.info(objects.join(', ')); + // console.info(objects.join(', ')); break; case LogLevel.Warning: - console.warn(objects.join(', ')); + // console.warn(objects.join(', ')); break; case LogLevel.Error: - console.error(objects.join(', ')); + // console.error(objects.join(', ')); break; } }); diff --git a/dmp-frontend/src/app/core/services/maintenance-tasks/maintenance-tasks.service.ts b/dmp-frontend/src/app/core/services/maintenance-tasks/maintenance-tasks.service.ts new file mode 100644 index 000000000..01062cd55 --- /dev/null +++ b/dmp-frontend/src/app/core/services/maintenance-tasks/maintenance-tasks.service.ts @@ -0,0 +1,24 @@ +import { Injectable } from "@angular/core"; +import { BaseService } from "@common/base/base.service"; +import { Observable } from "rxjs"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { BaseHttpService } from "../http/base-http.service"; + +@Injectable() +export class MaintenanceTasksService extends BaseService { + + private actionUrl: string; + + constructor(private http: BaseHttpService, configurationService: ConfigurationService) { + super(); + this.actionUrl = configurationService.server + 'management/'; + } + + migrateSemantics(): Observable { + return this.http.post(this.actionUrl + 'addSemantics/', null); + } + + addRdaInSemantics(): Observable { + return this.http.post(this.actionUrl + 'addRdaInSemantics/', null); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/saml-login.service.ts b/dmp-frontend/src/app/core/services/saml-login.service.ts index b0802de76..c3db23658 100644 --- a/dmp-frontend/src/app/core/services/saml-login.service.ts +++ b/dmp-frontend/src/app/core/services/saml-login.service.ts @@ -1,18 +1,21 @@ +import { HttpHeaders, HttpClient } from '@angular/common/http'; import { Injectable } from '@angular/core'; -import { Guid } from '@common/types/guid'; -import * as pk from 'pako'; +import { ConfigurationService } from './configuration/configuration.service'; +import { BaseHttpService } from './http/base-http.service'; +import { Observable } from 'rxjs'; +import { BaseComponent } from '@common/base/base.component'; @Injectable() -export class SamlLoginService { +export class SamlLoginService extends BaseComponent { - constructor() {} + private actionUrl: string; + private headers = new HttpHeaders(); + + constructor(private http: BaseHttpService, private httpClient: HttpClient, private configurationService: ConfigurationService) { + super(); + this.actionUrl = configurationService.server + 'saml2/'; + } - buildRelayState(spId: string, configurableLoginId: string): string { - let uri = 'spId=' + spId; - uri += '&configurableLoginId=' + configurableLoginId; - return encodeURIComponent(uri); - } - resolveConfigurableLoginId(relayState: string): string { const decoded = decodeURIComponent(relayState); const routeParams = new URLSearchParams(decoded); @@ -23,30 +26,9 @@ export class SamlLoginService { const routeParams = new URLSearchParams(decoded); return routeParams.has('spId') ? routeParams.get('spId') : ''; } - - getSamlLoginUrl(spEntityID: string, idpUrl: string, binding: string, assertionConsumerServiceUrl: string, configurableLoginId: string) { - const now = new Date(); - let protocolBinding = ''; - switch (binding) { - case "Redirect": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect" '; break; - case "Artifact": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Artifact" '; break; - case "Post": protocolBinding = 'ProtocolBinding="urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST" '; break; - } - const authenticationRequest = '' + - '' + spEntityID + '' + - ''; - const uint = new Uint8Array(authenticationRequest.length); - for (let i = 0, j = authenticationRequest.length; i < j; ++i) { - uint[i] = authenticationRequest.charCodeAt(i); - } - const base64String = btoa(pk.deflateRaw(uint, { to: 'string' })); - const relayState = this.buildRelayState(spEntityID, configurableLoginId); - const url = idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String); - return url; + + getAuthnRequest(configurableLoginId: string): Observable { + return this.http.get(this.actionUrl + 'authnRequest/' + configurableLoginId, { headers: this.headers }); } } \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/terms-of-service/terms-of-service.service.ts b/dmp-frontend/src/app/core/services/terms-of-service/terms-of-service.service.ts new file mode 100644 index 000000000..5ebe6a573 --- /dev/null +++ b/dmp-frontend/src/app/core/services/terms-of-service/terms-of-service.service.ts @@ -0,0 +1,23 @@ +import { Injectable } from "@angular/core"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { HttpClient, HttpResponse } from "@angular/common/http"; +import { Observable } from "rxjs"; + +@Injectable() +export class TermsOfServiceService { + private termsOfServiceUrl : string; + + constructor( + private http: HttpClient, + private configurationService: ConfigurationService + ) { + this.termsOfServiceUrl = `${configurationService.server}material/termsofservice`; + } + + public getTermsOfService(lang: string): Observable> { + return this.http.get(`${this.termsOfServiceUrl}/${lang}`, { responseType: 'blob', observe: 'response', headers: {'Content-type': 'text/html', + 'Accept': 'text/html', + 'Access-Control-Allow-Origin': this.configurationService.app, + 'Access-Control-Allow-Credentials': 'true'} }); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/unlink-account-email-confirmation/unlink-account-email-confirmation.service.ts b/dmp-frontend/src/app/core/services/unlink-account-email-confirmation/unlink-account-email-confirmation.service.ts new file mode 100644 index 000000000..40846c568 --- /dev/null +++ b/dmp-frontend/src/app/core/services/unlink-account-email-confirmation/unlink-account-email-confirmation.service.ts @@ -0,0 +1,23 @@ +import { HttpHeaders } from "@angular/common/http"; +import { Injectable } from "@angular/core"; +import { BaseHttpService } from "../http/base-http.service"; +import { ConfigurationService } from "../configuration/configuration.service"; +import { UnlinkAccountRequestModel } from "@app/core/model/unlink-account/unlink-account"; + +@Injectable() +export class UnlinkAccountEmailConfirmationService { + private actioUrl: string; + private headers: HttpHeaders; + + constructor(private http: BaseHttpService, private configurationService: ConfigurationService) { + this.actioUrl = configurationService.server + 'emailUnlinkConfirmation/'; + } + + public emailConfirmation(token: string) { + return this.http.get(this.actioUrl + token, { headers: this.headers }); + } + + public sendConfirmationEmail(unlinkRequest: UnlinkAccountRequestModel) { + return this.http.post(this.actioUrl, unlinkRequest, { headers: this.headers }); + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/core/services/user/user.service.ts b/dmp-frontend/src/app/core/services/user/user.service.ts index 6f387e813..b190322da 100644 --- a/dmp-frontend/src/app/core/services/user/user.service.ts +++ b/dmp-frontend/src/app/core/services/user/user.service.ts @@ -57,11 +57,6 @@ export class UserService { return this.http.post(this.actionUrl + 'find', email, {headers: this.headers}); } - public hasDOIToken(): Observable { - const url = this.actionUrl + 'hasDOIToken'; - return this.http.get(url, { headers: this.headers }); - } - public registerDOIToken(code: string, redirectUri: string): Observable { const url = this.actionUrl + 'registerDOIToken'; return this.http.post(url, {zenodoRequest: {code: code}, redirectUri: redirectUri}, { headers: this.headers }); diff --git a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html index c09a78590..730b5691f 100644 --- a/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html +++ b/dmp-frontend/src/app/library/auto-complete/multiple/multiple-auto-complete.component.html @@ -17,7 +17,6 @@ [placeholder]="placeholder" [matAutocomplete]="autocomplete" [value]="inputValue" (keyup)="onKeyUp($event)" (keydown)="onKeyDown($event)" [disabled]="disabled" (focus)="_onInputFocus()" (blur)="onBlur($event)" [matChipInputFor]="chipList" [matChipInputSeparatorKeyCodes]="separatorKeysCodes" - [matChipInputAddOnBlur]="autoSelectFirstOptionOnBlur" (matChipInputTokenEnd)="_addItem($event)" [matAutocompleteConnectedTo]="origin"> - + - - + diff --git a/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss b/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss index 71232d8f8..42b9098f9 100644 --- a/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss +++ b/dmp-frontend/src/app/library/guided-tour/guided-tour.component.scss @@ -211,9 +211,9 @@ ngx-guided-tour { // float: right; min-width: 133px; height: 40px; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); background: #ffffff 0% 0% no-repeat padding-box; - color: #129d99; + color: var(--primary-color); } .next-button { @@ -231,7 +231,7 @@ ngx-guided-tour { padding-left: 1em; padding-right: 1em; min-width: 101px; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; } /*custom add*/ @@ -245,16 +245,5 @@ ngx-guided-tour { border-radius: 30px; } } - - /*custom add*/ - .argos-present-img { - background: url("../../../assets/splash/assets/img/2_Sign_in/Svg/Sign\ In.svg") no-repeat; - min-width: 176px; - height: 220px; - position: relative; - top: 110px; - left: -85px; - border-top: none; - } } } diff --git a/dmp-frontend/src/app/ui/about/about.component.html b/dmp-frontend/src/app/ui/about/about.component.html index 16d8dfe91..f51042fc1 100644 --- a/dmp-frontend/src/app/ui/about/about.component.html +++ b/dmp-frontend/src/app/ui/about/about.component.html @@ -1,33 +1,5 @@ -
+
-
-

{{ 'ABOUT.TITLE' | translate}}

-
+
-
-
-

ARGOS is an online tool in support of automated processes to creating, managing, sharing and linking DMPs with research artifacts they correspond to. It is the joint effort of OpenAIRE and EUDAT to deliver an open platform for Data Management Planning that addresses FAIR and Open best practices and assumes no barriers for its use and adoption. It does so by applying common standards for machine-actionable DMPs as defined by the global research data community of RDA and by communicating and consulting with researchers, research communities and funders to better reflect on their needs. -

ARGOS provides a flexible environment and an easy interface for users to navigate and use.

-
-
- - - -
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/about/about.component.scss b/dmp-frontend/src/app/ui/about/about.component.scss index 38187f826..30a2f8b8b 100644 --- a/dmp-frontend/src/app/ui/about/about.component.scss +++ b/dmp-frontend/src/app/ui/about/about.component.scss @@ -8,6 +8,9 @@ img { width: 100%; } -// .about-component { -// margin-top: 80px; -// } +.iframe { + width: 100%; + height: calc(100vh - 80px); + margin: 0px; + border: none; +} diff --git a/dmp-frontend/src/app/ui/about/about.component.ts b/dmp-frontend/src/app/ui/about/about.component.ts index 4bc1ca7b6..ff9740a7b 100644 --- a/dmp-frontend/src/app/ui/about/about.component.ts +++ b/dmp-frontend/src/app/ui/about/about.component.ts @@ -1,21 +1,43 @@ -import { HttpClient } from '@angular/common/http'; import { Component, OnInit } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { Router } from '@angular/router'; +import { AboutService } from '@app/core/services/about/about.service'; +import { LanguageService } from '@app/core/services/language/language.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { BaseComponent } from '@common/base/base.component'; +import { TranslateService, LangChangeEvent } from '@ngx-translate/core'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-about-componet', templateUrl: './about.component.html', styleUrls: ['./about.component.scss'] }) -export class AboutComponent implements OnInit { +export class AboutComponent extends BaseComponent implements OnInit { + + aboutHTMLUrl: SafeResourceUrl; + sanitizedGuideUrl: any; constructor( - private httpClient: HttpClient, - private matomoService: MatomoService) { - } + private aboutService: AboutService, + private sanitizer: DomSanitizer, + private languageService: LanguageService, + private matomoService: MatomoService, + private translate: TranslateService, + private router: Router + ) { super(); } ngOnInit() { this.matomoService.trackPageView('About'); + this.translate.onLangChange.subscribe((event: LangChangeEvent) => { + this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/about'])); + }); + this.aboutService.getAbout(this.languageService.getCurrentLanguage()) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'text/html' }); + this.aboutHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); + }); } } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts index 59afcd724..2ef81df2e 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/admin/field-editor-model.ts @@ -47,7 +47,7 @@ export class FieldEditorModel extends BaseFormModel { public visible: VisibilityEditorModel = new VisibilityEditorModel(); public data: FieldDataEditorModel; public validations: ValidationType[] = []; - public rdaCommonStandard: string; + public schematics: string[]; public export: boolean = true; fromModel(item: Field): FieldEditorModel { @@ -58,7 +58,7 @@ export class FieldEditorModel extends BaseFormModel { this.validations = item.validations; this.viewStyle = new ViewStyleEditorModel().fromModel(item.viewStyle); this.visible = new VisibilityEditorModel().fromModel(item.visible); - this.rdaCommonStandard = item.rdaCommonStandard; + this.schematics = item.schematics; this.export = item.export; if (item.data) { @@ -105,7 +105,7 @@ export class FieldEditorModel extends BaseFormModel { page: [{ value: this.page, disabled: (disabled && !skipDisable.includes('FieldEditorModel.page')) }], ordinal: [{ value: this.ordinal, disabled: (disabled && !skipDisable.includes('FieldEditorModel.ordinal')) }], validations: [{ value: this.validations, disabled: (disabled && !skipDisable.includes('FieldEditorModel.validations')) }], - rdaCommonStandard: [{value: this.rdaCommonStandard, disabled: (disabled && !skipDisable.includes('FieldSetEditorModel.rdaCommonStandard')) }], + schematics: [{ value: this.schematics, disabled: (disabled && !skipDisable.includes('FieldEditorModel.schematics')) }], export: [{value: this.export, disabled: (disabled && !skipDisable.includes('FieldSetEditorModel.export'))}] }); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.scss index a53d303c5..121ec9530 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/composite-field/dataset-profile-editor-composite-field.component.scss @@ -15,7 +15,7 @@ //Palete -$blue-color : #129D99; +$blue-color : var(--primary-color); $blue-color-light: #5cf7f2; .actions-list{ 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 44c1e2c4e..4f5e7b641 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 @@ -360,13 +360,19 @@ export class DatasetProfileEditorCompositeFieldComponent extends BaseComponent i const minControl = multiplicity.get('min'); const maxControl = multiplicity.get('max'); + const placeholder = multiplicity.get('placeholder'); + const tableView = multiplicity.get('tableView'); if (isMultiplicityEnabled.checked) { minControl.setValue(0); maxControl.setValue(1); + placeholder.setValue(''); + tableView.setValue(false); }else{ minControl.setValue(0); maxControl.setValue(0); + placeholder.setValue(null); + tableView.setValue(null); } this.isMultiplicityEnabled = isMultiplicityEnabled.checked; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html index ffed9ee2f..f924390b4 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.html @@ -227,13 +227,9 @@ --> - {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.RDA-COMMON-STANDARDS' | translate}} - - -- - - {{property}} - - + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.SEMANTICS' | translate}} + + {{'DATASET-PROFILE-EDITOR.STEPS.FORM.COMPOSITE-FIELD.FIELDS.EXPORT' | translate}} diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss index 5f5900f93..7dfc9b224 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.scss @@ -14,7 +14,7 @@ mat-radio-button{ } li.list-inline-item{ - color: #129D99; + color: var(--primary-color); .mat-icon{ vertical-align: bottom; } @@ -27,7 +27,7 @@ li.list-inline-item{ color: #212121; } .mat-slide-toggle.mat-checked .mat-slide-toggle-thumb { - background-color:#129D99 ; + background-color:var(--primary-color) ; } .mat-slide-toggle.mat-checked .mat-slide-toggle-bar { background-color:rgba(0,178,159,0.34); diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts index 17663e5aa..b6ae07746 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/field/dataset-profile-editor-field.component.ts @@ -6,7 +6,7 @@ import {DatasetProfileService} from '@app/core/services/dataset-profile/dataset- import {EnumUtils} from '@app/core/services/utilities/enum-utils.service'; import {RuleEditorModel} from '@app/ui/admin/dataset-profile/admin/rule-editor-model'; import {BaseComponent} from '@common/base/base.component'; -import {Subscription} from 'rxjs'; +import {Observable, Subscription} from 'rxjs'; import {ViewStyleType} from './view-style-enum'; import {DatasetProfileComboBoxType} from '@app/core/common/enum/dataset-profile-combo-box-type'; import {ErrorStateMatcher} from '@angular/material/core'; @@ -44,6 +44,9 @@ import { WordListFieldData } from '@app/core/model/dataset-profile-definition/field-data/field-data'; import {ConfigurationService} from "@app/core/services/configuration/configuration.service"; +import { MultipleAutoCompleteConfiguration } from '@app/library/auto-complete/multiple/multiple-auto-complete-configuration'; +import { map } from 'rxjs/operators'; +import { COMMA, ENTER } from '@angular/cdk/keycodes'; @Component({ selector: 'app-dataset-profile-editor-field-component', @@ -70,9 +73,19 @@ export class DatasetProfileEditorFieldComponent extends BaseComponent implements @Output() delete = new EventEmitter(); + readonly separatorKeysCodes: number[] = [ENTER, COMMA]; - //rdaCommonStandards = this.datasetProfileService.getRDACommonStandards(); //GK: Don't do that again. The service has a weird async behaviour. + semanticsAutoCompleteConfiguration: MultipleAutoCompleteConfiguration = { + filterFn: this.filterSemantics.bind(this), + initialItems: (excludedItems: any[]) => this.filterSemantics('').pipe(map(result => result.filter(resultItem => (excludedItems || []).map(x => x !== resultItem)))), + displayFn: (item) => item, + titleFn: (item) => item + } + filterSemantics(value: string): Observable { + return this.datasetProfileService.searchSemantics(value); + } + constructor( public enumUtils: EnumUtils, public datasetProfileService: DatasetProfileService, diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.scss index c10761262..4870b869e 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/editor/components/section-fieldset/dataset-profile-editor-section-fieldset.component.scss @@ -1,4 +1,4 @@ -$blue-color : #129D99; +$blue-color : var(--primary-color); $blue-color-light: #5cf7f2; @@ -33,7 +33,7 @@ $blue-color-light: #5cf7f2; } .actions-list{ // border: 1px solid $blue-color; - // box-shadow: 0px 3px 12px #129D9999; + // box-shadow: 0px 3px 12px var(--primary-color)99; border-radius: 4px; // padding-top: 1rem; padding: 1em 0.9em; @@ -59,7 +59,7 @@ $blue-color-light: #5cf7f2; margin-right: 0.5em; margin-left: -.09em; height: auto; - color: #129D99;; + color: var(--primary-color);; } .input_icon{ width: 14px; 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 6a9648d6e..cd066b05f 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 @@ -72,7 +72,7 @@ transition-timing-function: ease-out; transition-delay: 50ms; box-shadow: 0px 1px 2px #bfbfbf; - background-color: #F7DD72; + background-color: var(--secondary-color); } #progress-container{ box-shadow: 1px 1px 6px #00000029;; @@ -81,8 +81,8 @@ // .import-btn { // background: #ffffff 0% 0% no-repeat padding-box; // border-radius: 30px; -// // color: #129d99; -// // border: 1px solid #129d99; +// // color: var(--primary-color); +// // border: 1px solid var(--primary-color); // padding-left: 2em; // padding-right: 2em; // color: #000; @@ -90,7 +90,7 @@ // } .navigate-btn { border-radius: 30px; - background-color: #f7dd72; + background-color: var(--secondary-color); border: 1px solid transparent; padding-left: 2em; padding-right: 2em; @@ -108,7 +108,7 @@ color: #FFF; .create-section-btn { border-radius: 30px; - background-color: #f7dd72; + background-color: var(--secondary-color); border: 1px solid transparent; padding-left: 1em; padding-right: 1em; @@ -117,21 +117,21 @@ color: #FFF; } -$blue-color : #129D99; +$blue-color : var(--primary-color); $blue-color-light: #5cf7f2; .finalize-btn { border-radius: 30px; - border: 1px solid #129D99; + border: 1px solid var(--primary-color); background: transparent; padding-left: 2em; padding-right: 2em; box-shadow: 0px 3px 6px #1E202029; - color: #129D99; + color: var(--primary-color); } .template_action_btn{ border-radius: 30px; - border: 1px solid #129D99; + border: 1px solid var(--primary-color); background: transparent; //padding-left: 2em; //padding-right: 2em; @@ -139,10 +139,10 @@ $blue-color-light: #5cf7f2; min-width: 110px; width: auto; box-shadow: 0px 3px 6px #1E202029; - color: #129D99; + color: var(--primary-color); flex: 0 0 auto; &.save-btn{ - background-color: #f7dd72; + background-color: var(--secondary-color); border: 1px solid transparent; //padding-left: 2em; //padding-right: 2em; @@ -196,7 +196,7 @@ $blue-color-light: #5cf7f2; .actions-list{ // border: 1px solid $blue-color; - box-shadow: 0px 3px 12px #129D9999; + box-shadow: 0px 3px 12px var(--primary-color)99; border-radius: 4px; // padding-top: 1rem; padding: 1em 0.9em; @@ -220,7 +220,7 @@ $blue-color-light: #5cf7f2; margin-right: 0.5em; margin-left: -.09em; height: auto; - color: #129D99;; + color: var(--primary-color);; } .input_icon{ width: 14px; @@ -322,7 +322,7 @@ $blue-color-light: #5cf7f2; position: fixed; bottom: 20em; right: 2em; - color: #129D99 !important; + color: var(--primary-color) !important; cursor: pointer; font-size: 1rem; font-weight: 400; diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss index 179e7eb4b..c79fa2851 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss @@ -15,12 +15,12 @@ min-width: 101px; .next-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } @@ -34,7 +34,7 @@ min-width: 101px; } .next-btn:not([disabled]):hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } @@ -86,15 +86,15 @@ min-width: 101px; width: 156px; height: 44px; color: #ffffff; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; } .attach-file:hover { background-color: #ffffff; - border: 1px solid #129d99; - color: #129d99; + border: 1px solid var(--primary-color); + color: var(--primary-color); } .close-btn:hover{ diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html index ca7500119..c1036626b 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.html @@ -60,6 +60,9 @@ + diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss index 456be7372..d6013801d 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.scss @@ -104,8 +104,8 @@ mat-row:hover { .import-btn { background: #ffffff 0% 0% no-repeat padding-box; border-radius: 30px; - // color: #129d99; - // border: 1px solid #129d99; + // color: var(--primary-color); + // border: 1px solid var(--primary-color); padding-left: 2em; padding-right: 2em; color: #000; @@ -113,7 +113,7 @@ mat-row:hover { } .create-btn { border-radius: 30px; - background-color: #f7dd72; + background-color: var(--secondary-color); padding-left: 2em; padding-right: 2em; } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts index 4a9246688..cfb0315f6 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/listing/dataset-profile-listing.component.ts @@ -123,6 +123,35 @@ export class DatasetProfileListingComponent extends BaseComponent implements OnI this.router.navigate(['dataset-profiles/newversion/' + id]); } + newVersionFromFile(id: string, label: string): void { + const dialogRef = this.dialog.open(DialogConfirmationUploadDatasetProfiles, { + width: '500px', + restoreFocus: false, + data: { + message: this.language.instant('DATASET-WIZARD.NEW-VERSION-FROM-FILE.NEW-VERSION-XML-FILE-TITLE', {datasetName: label}), + confirmButton: this.language.instant('DATASET-WIZARD.NEW-VERSION-FROM-FILE.NEW-VERSION-XML'), + cancelButton: this.language.instant('DATASET-WIZARD.NEW-VERSION-FROM-FILE.NEW-VERSION-XML-FILE-CANCEL'), + name: "", + file: FileList, + sucsess: false + } + }); + dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(data => { + if (data && data.sucsess && data.name != null && data.file != null) { + this.datasetService.uploadFile(data.file, data.name, id) + .pipe(takeUntil(this._destroyed)) + .subscribe(_=>{ + this.uiNotificationService.snackBarNotification(this.language.instant('DATASET-WIZARD.NEW-VERSION-FROM-FILE.NEW-VERSION-XML-SUCCESSFUL'), SnackBarNotificationLevel.Success); + this.refresh(); + }, + error=>{ + this.uiNotificationService.snackBarNotification(error.message, SnackBarNotificationLevel.Error); + } + ); + } + }); + } + viewVersions(rowId, rowLabel) { this.router.navigate(['/dataset-profiles/versions/' + rowId], { queryParams: { groupLabel: rowLabel } }); } diff --git a/dmp-frontend/src/app/ui/admin/dataset-profile/table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section.scss b/dmp-frontend/src/app/ui/admin/dataset-profile/table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section.scss index 66b54ece1..3e4c13517 100644 --- a/dmp-frontend/src/app/ui/admin/dataset-profile/table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section.scss +++ b/dmp-frontend/src/app/ui/admin/dataset-profile/table-of-contents/table-of-contents-internal-section/table-of-contents-internal-section.scss @@ -83,9 +83,9 @@ -$blue-color : #129D99; +$blue-color : var(--primary-color); $blue-color-light: #5cf7f2; -$yellow: #f7dd72; +$yellow: var(--secondary-color); .badge-ball{ display: inline-block; border-radius: 50%; diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss index ae188ac09..b05bd906f 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/editor/dmp-profile-editor.component.scss @@ -20,7 +20,7 @@ } ::ng-deep .mat-checkbox-checked.mat-accent .mat-checkbox-background, .mat-checkbox-indeterminate.mat-accent .mat-checkbox-background { - background-color: #00b29f; + background-color: var(--primary-color-3); // background-color: #0070c0; } @@ -30,12 +30,12 @@ .finalize-btn { border-radius: 30px; - border: 1px solid #129D99; + border: 1px solid var(--primary-color); background: transparent; padding-left: 2em; padding-right: 2em; box-shadow: 0px 3px 6px #1E202029; - color: #129D99; + color: var(--primary-color); &:disabled{ background-color: #CBCBCB; color: #FFF; @@ -45,7 +45,7 @@ .action-btn { border-radius: 30px; - background-color: #f7dd72; + background-color: var(--secondary-color); border: 1px solid transparent; padding-left: 2em; padding-right: 2em; diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss index 179e7eb4b..c79fa2851 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/criteria/dialog-confirmation-upload-profile/dialog-confirmation-upload-profiles.component.scss @@ -15,12 +15,12 @@ min-width: 101px; .next-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } @@ -34,7 +34,7 @@ min-width: 101px; } .next-btn:not([disabled]):hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } @@ -86,15 +86,15 @@ min-width: 101px; width: 156px; height: 44px; color: #ffffff; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; } .attach-file:hover { background-color: #ffffff; - border: 1px solid #129d99; - color: #129d99; + border: 1px solid var(--primary-color); + color: var(--primary-color); } .close-btn:hover{ diff --git a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss index e797578ad..55aaa2ee6 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/dmp-profile/listing/dmp-profile-listing.component.scss @@ -37,7 +37,7 @@ } .create-btn { border-radius: 30px; - background-color: #f7dd72; + background-color: var(--secondary-color); padding-left: 2em; padding-right: 2em; // color: #000; @@ -50,8 +50,8 @@ .import-btn { background: #ffffff 0% 0% no-repeat padding-box; border-radius: 30px; - // color: #129d99; - // border: 1px solid #129d99; + // color: var(--primary-color); + // border: 1px solid var(--primary-color); padding-left: 2em; padding-right: 2em; color: #000; diff --git a/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html new file mode 100644 index 000000000..7e90cea4f --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.html @@ -0,0 +1,9 @@ +
+ +
Warning: Danger zone. Irreversible actions!
+
+ + +
+
+
diff --git a/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.scss b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.scss new file mode 100644 index 000000000..0faaf9e53 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.scss @@ -0,0 +1,7 @@ +.root { + padding-bottom: 2em; + + .button { + margin: 5px; + } +} \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts new file mode 100644 index 000000000..4c86f3dd6 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.component.ts @@ -0,0 +1,65 @@ +import { Component, OnInit } from '@angular/core'; +import { BaseComponent } from '@common/base/base.component'; +import { takeUntil } from 'rxjs/operators'; +import { UiNotificationService, SnackBarNotificationLevel } from '@app/core/services/notification/ui-notification-service'; +import { TranslateService } from '@ngx-translate/core'; +import { Router } from '@angular/router'; +import { MaintenanceTasksService } from '@app/core/services/maintenance-tasks/maintenance-tasks.service'; + +@Component({ + selector: 'app-maintenance-tasks', + templateUrl: './maintenance-tasks.component.html', + styleUrls: ['./maintenance-tasks.component.scss'] +}) +export class MaintenanceTasksComponent extends BaseComponent implements OnInit { + + constructor( + private maintenanceTasksService: MaintenanceTasksService, + private uiNotificationService: UiNotificationService, + private translate: TranslateService, + private router: Router, + ) { + super(); + } + + ngOnInit(): void { + } + + migrateSemantics(ev: Event) { + (ev.srcElement as HTMLButtonElement).disabled = true; + this.maintenanceTasksService.migrateSemantics().pipe(takeUntil(this._destroyed)).subscribe( + response => { + (ev.srcElement as HTMLButtonElement).disabled = false; + this.onCallbackSuccess(); + }, + error => { + (ev.srcElement as HTMLButtonElement).disabled = false; + this.onCallbackError(error); + } + ); + } + + addRdaInSemantics(ev: Event) { + (ev.srcElement as HTMLButtonElement).disabled = true; + this.maintenanceTasksService.addRdaInSemantics().pipe(takeUntil(this._destroyed)).subscribe( + response => { + (ev.srcElement as HTMLButtonElement).disabled = false; + this.onCallbackSuccess(); + }, + error => { + (ev.srcElement as HTMLButtonElement).disabled = false; + this.onCallbackError(error); + } + ); + } + + onCallbackSuccess(): void { + this.uiNotificationService.snackBarNotification( this.translate.instant('GENERAL.SNACK-BAR.SUCCESSFUL-UPDATE'), SnackBarNotificationLevel.Success); + this.router.navigate(['/reload']).then(() => this.router.navigate(['/maintenance-tasks'])); + } + + onCallbackError(error: any) { + this.uiNotificationService.snackBarNotification( error, SnackBarNotificationLevel.Error); + } + +} diff --git a/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.module.ts b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.module.ts new file mode 100644 index 000000000..fe1988755 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.module.ts @@ -0,0 +1,23 @@ +import { NgModule } from '@angular/core'; + +import { MaintenanceTasksRoutingModule } from './maintenance-tasks.routing'; +import { MaintenanceTasksComponent } from './maintenance-tasks.component'; +import { CommonUiModule } from '@common/ui/common-ui.module'; +import { CommonFormsModule } from '@common/forms/common-forms.module'; +import { ConfirmationDialogModule } from '@common/modules/confirmation-dialog/confirmation-dialog.module'; +import { MaintenanceTasksService } from '@app/core/services/maintenance-tasks/maintenance-tasks.service'; + + +@NgModule({ + declarations: [MaintenanceTasksComponent], + imports: [ + CommonUiModule, + CommonFormsModule, + ConfirmationDialogModule, + MaintenanceTasksRoutingModule + ], + providers: [ + MaintenanceTasksService + ] +}) +export class MaintenanceTasksModule { } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.routing.ts b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.routing.ts new file mode 100644 index 000000000..daec08ac0 --- /dev/null +++ b/dmp-frontend/src/app/ui/admin/maintenance-tasks/maintenance-tasks.routing.ts @@ -0,0 +1,15 @@ +import { NgModule } from '@angular/core'; +import { Routes, RouterModule } from '@angular/router'; +import { MaintenanceTasksComponent } from './maintenance-tasks.component'; +import { AdminAuthGuard } from '@app/core/admin-auth-guard.service'; + + +const routes: Routes = [ + { path: '', component: MaintenanceTasksComponent, canActivate: [AdminAuthGuard] }, +]; + +@NgModule({ + imports: [RouterModule.forChild(routes)], + exports: [RouterModule] +}) +export class MaintenanceTasksRoutingModule { } \ No newline at end of file diff --git a/dmp-frontend/src/app/ui/admin/user/listing/criteria/user-criteria.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/criteria/user-criteria.component.scss index 9b54a5539..86021d8d4 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/criteria/user-criteria.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/criteria/user-criteria.component.scss @@ -14,7 +14,7 @@ } .search-form mat-icon { - color: #129d99; + color: var(--primary-color); } } diff --git a/dmp-frontend/src/app/ui/admin/user/listing/role-editor/user-role-editor.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/role-editor/user-role-editor.component.scss index ced1b45aa..c2fc49ca7 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/role-editor/user-role-editor.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/role-editor/user-role-editor.component.scss @@ -20,7 +20,7 @@ } .row-action { - color: #129d99; + color: var(--primary-color); cursor: pointer; } .user-role{ diff --git a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss index f9e30031c..6e01f8143 100644 --- a/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss +++ b/dmp-frontend/src/app/ui/admin/user/listing/user-listing.component.scss @@ -50,8 +50,8 @@ background: #ffffff 0% 0% no-repeat padding-box; border-radius: 30px; width: 145px; - color: #129d99; - border: 1px solid #129d99; + color: var(--primary-color); + border: 1px solid var(--primary-color); } .export-icon { diff --git a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts index e0ed91f84..4997571dd 100644 --- a/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts +++ b/dmp-frontend/src/app/ui/auth/login/configurable-login/configurable-login.component.ts @@ -8,6 +8,7 @@ import { ConfigurableProvidersService } from '@app/ui/auth/login/utilities/confi import { LoginService } from '@app/ui/auth/login/utilities/login.service'; import { BaseComponent } from '@common/base/base.component'; import { environment } from 'environments/environment'; +import * as pk from 'pako'; import { takeUntil } from 'rxjs/operators'; import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; import { SamlLoginService } from '@app/core/services/saml-login.service'; @@ -86,10 +87,28 @@ export class ConfigurableLoginComponent extends BaseComponent implements OnInit } else if(this.provider.type === ConfigurableProviderType.Saml2){ let provider = this.provider as Saml2ConfigurableProvider; - window.location.href = this.samlLoginService.getSamlLoginUrl(provider.spEntityId, provider.idpUrl, provider.binding, provider.assertionConsumerServiceUrl, provider.configurableLoginId); + this.samlLoginService.getAuthnRequest(provider.configurableLoginId).pipe(takeUntil(this._destroyed)) + .subscribe( + authenticationRequest => { + const uint = new Uint8Array(authenticationRequest.length); + for (let i = 0, j = authenticationRequest.length; i < j; ++i) { + uint[i] = authenticationRequest.charCodeAt(i); + } + const base64String = btoa(pk.deflateRaw(uint, { to: 'string' })); + const relayState = this.buildRelayState(provider.spEntityId, provider.configurableLoginId); + const url = provider.idpUrl + '?RelayState=' + relayState + '&SAMLRequest=' + encodeURIComponent(base64String); + window.location.href = url; + } + ); } } + buildRelayState(spId: string, configurableLoginId: string): string { + let uri = 'spId=' + spId; + uri += '&configurableLoginId=' + configurableLoginId; + return encodeURIComponent(uri); + } + public configurableLoginUser(code: string, state: string) { if (state !== (this.provider).state) { this.router.navigate(['/login']) diff --git a/dmp-frontend/src/app/ui/auth/login/login.component.scss b/dmp-frontend/src/app/ui/auth/login/login.component.scss index 8238f27d6..e78cd7a8c 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.component.scss +++ b/dmp-frontend/src/app/ui/auth/login/login.component.scss @@ -32,13 +32,13 @@ font: Bold 38px/82px Roboto; height: 60px; letter-spacing: -0.95px; - color: #23bcba; + color: var(--primary-color-2); margin-top: 11px; margin-bottom: 21px; } .line { - border-top: 5px solid #23bcba; + border-top: 5px solid var(--primary-color-2); width: 116px; margin-bottom: 97px; } @@ -261,7 +261,7 @@ span.twitterIcon { .openaireIconButton:hover, .orcidIconMediumButton:hover, .iconmediumButton:hover { - // background-color: #129d993b; + // background-color: var(--primary-color)3b; background-color: #ececec; border-radius: 60%; } @@ -341,8 +341,7 @@ span.zenodoIcon { // } .laptop-img { - // background: url("../../../../assets/splash/assets/img/laptop.png") no-repeat; - background: url("../../../../assets/splash/assets/img/1_Main/Png/Who\ \ \ Benefits\ Small.png") no-repeat; + background: url("../../../../assets/images/login-bottom-image.png") no-repeat; width: 164px; height: 200px; position: relative; diff --git a/dmp-frontend/src/app/ui/auth/login/login.module.ts b/dmp-frontend/src/app/ui/auth/login/login.module.ts index 1feb4f4dc..8d5b84740 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.module.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.module.ts @@ -18,6 +18,7 @@ import { MergeLoginService } from './utilities/merge-login.service'; import { ZenodoLoginComponent } from './zenodo-login/zenodo-login.component'; import { SamlLoginService } from '@app/core/services/saml-login.service'; import { SamlResponseLoginComponent } from './saml/saml-login-response/saml-login-response.component'; +import { UnlinkEmailConfirmation } from './unlink-email-confirmation/unlink-email-confirmation.component'; @NgModule({ imports: [ @@ -37,6 +38,7 @@ import { SamlResponseLoginComponent } from './saml/saml-login-response/saml-logi ConfigurableLoginComponent, ZenodoLoginComponent, MergeEmailConfirmation, + UnlinkEmailConfirmation, SamlResponseLoginComponent ], exports: [ diff --git a/dmp-frontend/src/app/ui/auth/login/login.routing.ts b/dmp-frontend/src/app/ui/auth/login/login.routing.ts index 68fc9e558..2ba809b6b 100644 --- a/dmp-frontend/src/app/ui/auth/login/login.routing.ts +++ b/dmp-frontend/src/app/ui/auth/login/login.routing.ts @@ -12,6 +12,7 @@ import { ZenodoLoginComponent } from './zenodo-login/zenodo-login.component'; import { Oauth2DialogComponent } from '@app/ui/misc/oauth2-dialog/oauth2-dialog.component'; import { MergeEmailConfirmation } from './merge-email-confirmation/merge-email-confirmation.component'; import { SamlResponseLoginComponent } from './saml/saml-login-response/saml-login-response.component'; +import { UnlinkEmailConfirmation } from './unlink-email-confirmation/unlink-email-confirmation.component'; const routes: Routes = [ { path: '', component: LoginComponent }, @@ -21,6 +22,7 @@ const routes: Routes = [ { path: 'external/b2access', component: Oauth2DialogComponent }, { path: 'confirmation/:token', component: EmailConfirmation }, { path: 'merge/confirmation/:token', component: MergeEmailConfirmation }, + { path: 'unlink/confirmation/:token', component: UnlinkEmailConfirmation }, { path: 'confirmation', component: EmailConfirmation }, { path: 'openaire', component: Oauth2DialogComponent}, { path: 'configurable/:id', component: ConfigurableLoginComponent}, diff --git a/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.html b/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.html new file mode 100644 index 000000000..8b1378917 --- /dev/null +++ b/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.html @@ -0,0 +1 @@ + diff --git a/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.scss b/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.scss new file mode 100644 index 000000000..e69de29bb diff --git a/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.ts b/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.ts new file mode 100644 index 000000000..453eb754c --- /dev/null +++ b/dmp-frontend/src/app/ui/auth/login/unlink-email-confirmation/unlink-email-confirmation.component.ts @@ -0,0 +1,54 @@ +import { Component, OnInit } from '@angular/core'; +import { ActivatedRoute, Router } from '@angular/router'; +import { UnlinkAccountEmailConfirmationService } from '@app/core/services/unlink-account-email-confirmation/unlink-account-email-confirmation.service'; +import { SnackBarNotificationLevel, UiNotificationService } from '@app/core/services/notification/ui-notification-service'; +import { BaseComponent } from '@common/base/base.component'; +import { TranslateService } from '@ngx-translate/core'; +import { takeUntil } from "rxjs/operators"; + +@Component({ + selector: 'app-unlink-email-confirmation-component', + templateUrl: './unlink-email-confirmation.component.html' +}) +export class UnlinkEmailConfirmation extends BaseComponent implements OnInit { + + constructor( + private emailConfirmationService: UnlinkAccountEmailConfirmationService, + private route: ActivatedRoute, + private router: Router, + private language: TranslateService, + private uiNotificationService: UiNotificationService + ) { super(); } + + ngOnInit(): void { + this.route.params + .pipe(takeUntil(this._destroyed)) + .subscribe(params => { + const token = params['token'] + if (token != null) { + this.emailConfirmationService.emailConfirmation(token) + .pipe(takeUntil(this._destroyed)) + .subscribe( + result => this.onCallbackEmailConfirmationSuccess(), + error => this.onCallbackError(error) + ) + } + }); + } + + onCallbackEmailConfirmationSuccess() { + this.router.navigate(['home']); + } + + onCallbackError(error: any) { + if (error.status === 302) { + this.uiNotificationService.snackBarNotification(this.language.instant('EMAIL-CONFIRMATION.EMAIL-FOUND'), SnackBarNotificationLevel.Warning); + this.router.navigate(['home']); + } + else { + this.uiNotificationService.snackBarNotification(this.language.instant('EMAIL-CONFIRMATION.EXPIRED-EMAIL'), SnackBarNotificationLevel.Error); + this.router.navigate(['login']); + } + } + +} diff --git a/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.scss b/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.scss index 70089c0ca..13a78e08f 100644 --- a/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.scss +++ b/dmp-frontend/src/app/ui/contact/contact-content/contact-content.component.scss @@ -25,12 +25,12 @@ img { .send-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } diff --git a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html index 61b9e8242..795ff063d 100644 --- a/dmp-frontend/src/app/ui/dashboard/dashboard.component.html +++ b/dmp-frontend/src/app/ui/dashboard/dashboard.component.html @@ -20,35 +20,38 @@
- -
- +
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
- - - + + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
-
- - + > + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
- +
{{'DASHBOARD.LATEST-ACTIVITY' | translate}}
- - - + + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
- - + + +
{{'DASHBOARD.EMPTY-LIST' | translate}}
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -19,6 +19,9 @@
+
+ +
-
- +
+ {{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} +
+
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -23,6 +23,9 @@ +
+ +
@@ -165,8 +168,11 @@
+
+ {{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} +
- +
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 ffcf3740b..ee7d19c82 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 @@ -1,6 +1,6 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import {Component, OnInit, Output, EventEmitter, Input, ViewChild} from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Router } from '@angular/router'; +import {ActivatedRoute, Router} from '@angular/router'; import { RecentActivityType } from '@app/core/common/enum/recent-activity-type'; import { Principal } from '@app/core/model/auth/principal'; import { DataTableRequest, DataTableMultiTypeRequest } from '@app/core/model/data-table/data-table-request'; @@ -52,6 +52,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn @Output() totalCountRecentEdited: EventEmitter = new EventEmitter(); + @ViewChild("results") resultsContainer; allRecentActivities: RecentActivityModel[]; recentActivityTypeEnum = RecentActivityType; dmpModel: DmpEditorModel; @@ -60,6 +61,7 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn startIndex: number = 0; dmpOffset: number = 0; datasetOffset: number = 0; + offsetLess: number = 0; pageSize: number = 5; dmpFormGroup: FormGroup; hasMoreActivity:boolean = true; @@ -71,7 +73,11 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn order = RecentActivityOrder; + page: number = 1; + @Input() isActive: boolean = false; + constructor( + private route: ActivatedRoute, private router: Router, public enumUtils: EnumUtils, private authentication: AuthService, @@ -91,13 +97,46 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn ngOnInit() { this.matomoService.trackPageView('Recent Edited Activity'); + this.route.queryParams.subscribe(params => { + if(this.isActive) { + let page = (params['page'] === undefined) ? 1 : +params['page']; + this.page = (page <= 0) ? 1 : page; + + this.datasetOffset = (this.page-1)*this.pageSize; + this.dmpOffset = (this.page-1)*this.pageSize; + if(this.page > 1) { + this.offsetLess = (this.page-2)*this.pageSize; + } + + let order = params['order']; + if (this.isAuthenticated()) { + if(order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL && order != this.order.STATUS)) { + order = this.order.MODIFIED; + } + } else { + if(order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) { + order = this.order.PUBLISHED; + } + } + this.formGroup.get('order').setValue(order); + + let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; + this.formGroup.get("like").setValue(keyword); + + console.log("init"); + this.updateUrl(); + } + }); if (this.isAuthenticated()) { - this.formGroup.get('order').setValue(this.order.MODIFIED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); + } const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(0, 0, 5, { fields: fields }); + const allDataTableRequest: DataTableMultiTypeRequest = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, 5, { fields: fields }); allDataTableRequest.criteria = new RecentActivityCriteria(); - allDataTableRequest.criteria.like = ""; + allDataTableRequest.criteria.like = this.formGroup.get('like').value; allDataTableRequest.criteria.order = this.formGroup.get('order').value; + this.dashboardService .getRecentActivity(allDataTableRequest) .pipe(takeUntil(this._destroyed)) @@ -105,22 +144,40 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn this.allRecentActivities = response; this.allRecentActivities.forEach(recentActivity => { if (recentActivity.type === RecentActivityType.Dataset) { - this.datasetOffset = this.datasetOffset + 1; + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; } else if (recentActivity.type === RecentActivityType.Dmp) { - this.dmpOffset = this.dmpOffset + 1; + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; } }); this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if(this.allRecentActivities.length == 0 && this.page > 1) { + let queryParams = { type: "recent", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + console.log(queryParams); + this.router.navigate(["/home"], { queryParams: queryParams }) + } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) - .subscribe(x => this.refresh()); + .subscribe(x => { + console.log("like changed"); + this.refresh() + }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + .subscribe(x => { + console.log("order changed"); + this.refresh() + }); } else { this.publicMode = true; - this.formGroup.get('order').setValue(this.order.PUBLISHED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.PUBLISHED); + } const allDataTableRequest = this.setPublicDataTableRequest(); this.dashboardService .getRecentActivity(allDataTableRequest) @@ -129,22 +186,57 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn this.allRecentActivities = response; this.allRecentActivities.forEach(recentActivity => { if (recentActivity.type === RecentActivityType.Dataset) { - this.datasetOffset = this.datasetOffset + 1; + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; } else if (recentActivity.type === RecentActivityType.Dmp) { - this.dmpOffset = this.dmpOffset + 1; + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; } }); this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if(this.allRecentActivities.length == 0 && this.page > 1) { + let queryParams = { type: "recent", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + console.log(queryParams); + this.router.navigate(["/home"], { queryParams: queryParams }) + } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) - .subscribe(x => this.refresh()); + .subscribe(x => { + console.log("like changed 1"); + this.refresh() + }); this.formGroup.get('order').valueChanges .pipe(takeUntil(this._destroyed)) - .subscribe(x => this.refresh()); + .subscribe(x => { + console.log("order changed 1"); + this.refresh() + }); } } + ngOnChanges() { + if(this.isActive) { + console.log("active"); + this.updateUrl(); + } + } + + updateUrl() { + let parameters = ""; + parameters += (this.page != 1 ? "&page="+this.page : ""); + parameters += (((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order="+this.formGroup.get("order").value : ""); + parameters += (this.formGroup.get("like").value ? ("&keyword="+this.formGroup.get("like").value) : ""); + if(parameters) { + parameters = "?type=recent" + parameters; + } + console.log(parameters); + this.location.go(this.router.url.split('?')[0]+parameters); + } + getDatasets(activity: RecentDmpModel): DatasetUrlListing[] { return activity.datasets; } @@ -615,9 +707,11 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn } refresh(): void { - this.hasMoreActivity = true; this.datasetOffset = 0; this.dmpOffset = 0; + this.page = 1; + console.log("refresh"); + this.updateUrl(); const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; // const fields: Array = ["-modified"]; @@ -633,39 +727,73 @@ export class RecentEditedActivityComponent extends BaseComponent implements OnIn this.allRecentActivities = response; this.allRecentActivities.forEach(recentActivity => { if (recentActivity.type === RecentActivityType.Dataset) { - this.datasetOffset = this.datasetOffset + 1; + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page*this.pageSize; } else if (recentActivity.type === RecentActivityType.Dmp) { - this.dmpOffset = this.dmpOffset + 1; + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page*this.pageSize; } }); - if(response.length< this.pageSize) {this.hasMoreActivity = false;} + if(response.length< this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } this.totalCountRecentEdited.emit(this.allRecentActivities.length); }); } - public loadMore() { + public loadNextOrPrevious(more: boolean = true) { const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; // const fields: Array = ["-modified"]; - const request = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, this.pageSize, { fields: fields }); + let request; + if(more) { + request = new DataTableMultiTypeRequest(this.dmpOffset, this.datasetOffset, this.pageSize, {fields: fields}); + } else { + request = new DataTableMultiTypeRequest(this.offsetLess, this.offsetLess, this.pageSize, {fields: fields}); + } request.criteria = new RecentActivityCriteria(); request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; request.criteria.order = this.formGroup.get("order").value; this.dashboardService.getRecentActivity(request).pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result) { this.hasMoreActivity = false; return []; } - result.forEach(recentActivity => { - if (recentActivity.type === RecentActivityType.Dataset) { - this.datasetOffset = this.datasetOffset + 1; - } else if (recentActivity.type === RecentActivityType.Dmp) { - this.dmpOffset = this.dmpOffset + 1; + if (!result || result.length == 0) { + this.hasMoreActivity = false; + // return []; + } else { + this.page = this.page + (more ? 1 : -1); + console.log("loadNextOrPrevious"); + this.updateUrl(); + // if(more) { + // result.forEach(recentActivity => { + // if (recentActivity.type === RecentActivityType.Dataset) { + // this.datasetOffset = this.datasetOffset + 1; + this.datasetOffset = this.page * this.pageSize; + // } else if (recentActivity.type === RecentActivityType.Dmp) { + // this.dmpOffset = this.dmpOffset + 1; + this.dmpOffset = this.page * this.pageSize; + // } + // }); + // } + if (this.page > 1) { + this.offsetLess = (this.page - 2) * this.pageSize; } - }); - if(result.length 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result; - this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if(result.length < this.pageSize) { + this.hasMoreActivity = false; + } else { + this.hasMoreActivity = true; + } + + // this.allRecentActivities = this.allRecentActivities.concat(result); + // this.allRecentActivities = this.allRecentActivities.length > 0 ? this.mergeTwoSortedLists(this.allRecentActivities, result, this.formGroup.get('order').value) : result; + this.allRecentActivities = result; + this.totalCountRecentEdited.emit(this.allRecentActivities.length); + if (more) { + this.resultsContainer.nativeElement.scrollIntoView(); + } + } }); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html index 978476ec9..61a8a95c5 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.html @@ -1,4 +1,4 @@ -
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -20,6 +20,9 @@
+
+ +
-
- +
+ {{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} +
+
+
diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.scss b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.scss index 3aadd6111..3c5f10947 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.scss +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dataset-activity/recent-edited-dataset-activity.component.scss @@ -47,7 +47,7 @@ input[type="text"] { } .dmp-label { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; opacity: 1; min-width: 67px; @@ -59,7 +59,7 @@ input[type="text"] { .dataset-label { width: auto; height: 37px; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; text-align: left; line-height: 2.8; @@ -141,7 +141,7 @@ input[type="text"] { .dataset-card-actions a:hover, .dmp-card-actions a:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .dmp-dataset-descriptions-title { @@ -162,7 +162,7 @@ input[type="text"] { } .show-more:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .btn-load-more { @@ -194,7 +194,7 @@ input[type="text"] { } .search-form mat-icon { - color: #129d99; + color: var(--primary-color); } ::ng-deep .search-form .mat-form-field-wrapper { 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 6f51f4a54..e33f46266 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 @@ -1,4 +1,4 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import {Component, OnInit, Output, EventEmitter, Input, ViewChild} from '@angular/core'; import { DatasetListingModel } from '@app/core/model/dataset/dataset-listing'; import { DatasetService } from '@app/core/services/dataset/dataset.service'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; @@ -12,7 +12,7 @@ import { FormControl, FormBuilder } from '@angular/forms'; import { DatasetCopyDialogueComponent } from '@app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component'; import { MatDialog } from '@angular/material/dialog'; import { debounceTime, takeUntil } from 'rxjs/operators'; -import { Router } from '@angular/router'; +import {ActivatedRoute, Router} from '@angular/router'; import { DatasetWizardService } from '@app/core/services/dataset-wizard/dataset-wizard.service'; import * as FileSaver from 'file-saver'; import { ConfirmationDialogComponent } from '@common/modules/confirmation-dialog/confirmation-dialog.component'; @@ -38,9 +38,13 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen @Output() totalCountDatasets: EventEmitter = new EventEmitter(); + @ViewChild("datasets") resultsContainer; + datasetActivities: DatasetListingModel[]; totalCount: number; startIndex: number = 0; + offsetLess: number = 0; + hasMoreResults:boolean = true; pageSize: number = 5; public formGroup = new FormBuilder().group({ like: new FormControl(), @@ -50,7 +54,11 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen order = RecentActivityOrder; + page: number = 1; + @Input() isActive: boolean = false; + constructor( + private route: ActivatedRoute, private authentication: AuthService, private datasetService: DatasetService, private language: TranslateService, @@ -70,20 +78,57 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen ngOnInit() { this.matomoService.trackPageView('Recent Dataset Activity'); + this.route.queryParams.subscribe(params => { + if(this.isActive) { + let page = (params['page'] === undefined) ? 1 : +params['page']; + this.page = (page <= 0) ? 1 : page; + + this.startIndex = (this.page-1)*this.pageSize; + if(this.page > 1) { + this.offsetLess = (this.page-2)*this.pageSize; + } + + let order = params['order']; + if (this.isAuthenticated()) { + if(order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL && order != this.order.STATUS)) { + order = this.order.MODIFIED; + } + } else { + if(order === undefined || (order != this.order.DATASETPUBLISHED && order != this.order.LABEL)) { + order = this.order.DATASETPUBLISHED; + } + } + this.formGroup.get('order').setValue(order); + + let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; + this.formGroup.get("like").setValue(keyword); + + this.updateUrl(); + } + }); if (this.isAuthenticated()) { // const fields: Array = ["-modified"]; - this.formGroup.get('order').setValue(this.order.MODIFIED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); + } const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const datasetDataTableRequest: DataTableRequest = new DataTableRequest(0, this.pageSize, { fields: fields }); + const datasetDataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); datasetDataTableRequest.criteria = new DatasetCriteria(); - datasetDataTableRequest.criteria.like = ""; + datasetDataTableRequest.criteria.like = this.formGroup.get('like').value; this.datasetService .getPaged(datasetDataTableRequest) .pipe(takeUntil(this._destroyed)) .subscribe(response => { this.datasetActivities = response.data; this.totalCount = response.totalCount; - this.totalCountDatasets.emit(this.datasetActivities.length); + this.totalCountDatasets.emit(this.datasetActivities.length) + if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { + let queryParams = { type: "datasets", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], { queryParams: queryParams }) + } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) @@ -93,12 +138,21 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen .subscribe(x => this.refresh()); } else { this.publicMode = true; - this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.DATASETPUBLISHED); + } const dataTableRequest = this.setPublicDataTableRequest(); this.datasetService.getPaged(dataTableRequest).pipe(takeUntil(this._destroyed)).subscribe(response => { this.datasetActivities = response.data; this.totalCount = response.totalCount; this.totalCountDatasets.emit(this.datasetActivities.length); + if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { + let queryParams = { type: "datasets", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], { queryParams: queryParams }) + } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) @@ -109,7 +163,21 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen } } - setPublicDataTableRequest(fields?: Array): DataTableRequest { + ngOnChanges() { + if(this.isActive) { + this.updateUrl(); + } + } + + updateUrl() { + let parameters = "?type=datasets"+ + (this.page != 1 ? "&page="+this.page : "") + + (((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.DATASETPUBLISHED && this.publicMode)) ? "&order="+this.formGroup.get("order").value : "") + + (this.formGroup.get("like").value ? ("&keyword="+this.formGroup.get("like").value) : ""); + this.location.go(this.router.url.split('?')[0]+parameters); + } + + setPublicDataTableRequest(fields?: Array, more: boolean = true): DataTableRequest { const datasetCriteria = new DatasetCriteria(); datasetCriteria.allVersions = false; datasetCriteria.isPublic = true; @@ -117,13 +185,16 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen if (!fields) { fields = new Array('-dmp:publishedAt|join|'); } - const dataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + const dataTableRequest: DataTableRequest = more ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : new DataTableRequest(this.offsetLess, this.pageSize, { fields: fields }); dataTableRequest.criteria = datasetCriteria; return dataTableRequest; } refresh(): void { this.startIndex = 0; + this.page = 1; + this.updateUrl(); + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; const datasetDataTableRequest = this.isAuthenticated() ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields); @@ -138,24 +209,59 @@ export class RecentEditedDatasetActivityComponent extends BaseComponent implemen this.datasetActivities = response.data; this.totalCount = response.totalCount; this.totalCountDatasets.emit(this.datasetActivities.length); + if(response.data.length< this.pageSize) { + this.hasMoreResults = false; + } else { + this.hasMoreResults = true; + } }); } - public loadMore() { + public loadNextOrPrevious(more: boolean = true) { this.startIndex = this.startIndex + this.pageSize; const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const request = this.isAuthenticated() ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields); + let request; + this.startIndex = (this.page)*this.pageSize; + if(this.page > 1) { + this.offsetLess = (this.page-2)*this.pageSize; + } + if(this.isAuthenticated()) { + if(more) { + request = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + } else { + request = new DataTableRequest(this.offsetLess, this.pageSize, { fields: fields }); + } + } else { + request = this.setPublicDataTableRequest(fields, more); + } if (this.isAuthenticated()) { request.criteria = new DatasetCriteria(); request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; } this.datasetService.getPaged(request).pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result) { return []; } - // this.datasetActivities = this.datasetActivities.concat(result.data); - this.datasetActivities = this.datasetActivities.length > 0 ? this.mergeTwoSortedLists(this.datasetActivities, result.data, this.formGroup.get('order').value) : result.data; - this.totalCountDatasets.emit(this.datasetActivities.length); + if (!result || !result.data || result.data.length == 0) { + this.hasMoreResults = false; + // return []; + } else { + this.page = this.page + (more ? 1 : -1); + this.updateUrl(); + // this.datasetActivities = this.datasetActivities.concat(result.data); + // this.datasetActivities = this.datasetActivities.length > 0 ? this.mergeTwoSortedLists(this.datasetActivities, result.data, this.formGroup.get('order').value) : result.data; + this.datasetActivities = result.data; + + if(result.data.length < this.pageSize) { + this.hasMoreResults = false; + } else { + this.hasMoreResults = true; + } + + this.totalCountDatasets.emit(this.datasetActivities.length); + if (more) { + this.resultsContainer.nativeElement.scrollIntoView(); + } + } }); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css index 44bd0a482..6829e925e 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.css @@ -46,7 +46,7 @@ input[type="text"] { } .dmp-label { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; opacity: 1; min-width: 67px; @@ -58,7 +58,7 @@ input[type="text"] { .dataset-label { width: auto; height: 37px; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; text-align: left; line-height: 2.8; @@ -123,7 +123,7 @@ input[type="text"] { } .dataset-card-actions a:hover, .dmp-card-actions a:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .dmp-dataset-descriptions-title { @@ -144,7 +144,7 @@ input[type="text"] { } .show-more:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .btn-load-more { @@ -176,7 +176,7 @@ input[type="text"] { } .search-form mat-icon { - color: #129d99; + color: var(--primary-color); } ::ng-deep .search-form .mat-form-field-wrapper { @@ -204,9 +204,9 @@ a { .is-public { padding-left: 5px; padding-right: 5px; - border: 1px solid #00b29f3b; - color: #00b29f; - background-color: #00b29f0f; + border: 1px solid var(--primary-color-3)3b; + color: var(--primary-color-3); + background-color: var(--primary-color-3)0f; border-radius: 10em; text-align: center; } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html index 46680c012..3eed1fcaf 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.html @@ -1,4 +1,4 @@ -
+
{{'DMP-LISTING.SORT-BY' | translate}}: @@ -20,6 +20,9 @@
+
+ +
-
- +
+ {{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} +
+
+
diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-dmp-activity/recent-edited-dmp-activity.component.ts index 4ad783614..1e53f6b9a 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 @@ -1,6 +1,6 @@ -import { Component, OnInit, Output, EventEmitter } from '@angular/core'; +import {Component, OnInit, Output, EventEmitter, Input, ViewChild} from '@angular/core'; import { MatDialog } from '@angular/material/dialog'; -import { Router } from '@angular/router'; +import {ActivatedRoute, Router} from '@angular/router'; import { RecentActivityType } from '@app/core/common/enum/recent-activity-type'; import { Principal } from '@app/core/model/auth/principal'; import { DataTableRequest } from '@app/core/model/data-table/data-table-request'; @@ -44,6 +44,8 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O @Output() totalCountDmps: EventEmitter = new EventEmitter(); + @ViewChild("dmps") resultsContainer; + dmpActivities: DmpListingModel[]; datasetActivities: DatasetListingModel[]; dmpModel: DmpEditorModel; @@ -52,6 +54,8 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O totalCount: number; startIndex: number = 0; + offsetLess: number = 0; + hasMoreResults:boolean = true; pageSize: number = 5; dmpFormGroup: FormGroup; public formGroup = new FormBuilder().group({ @@ -62,7 +66,11 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O order = RecentActivityOrder; + page: number = 1; + @Input() isActive: boolean = false; + constructor( + private route: ActivatedRoute, private router: Router, public enumUtils: EnumUtils, private authentication: AuthService, @@ -81,13 +89,43 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O ngOnInit() { this.matomoService.trackPageView('Recent DMP Activity'); + this.route.queryParams.subscribe(params => { + if(this.isActive) { + let page = (params['page'] === undefined) ? 1 : +params['page']; + this.page = (page <= 0) ? 1 : page; + + this.startIndex = (this.page-1)*this.pageSize; + if(this.page > 1) { + this.offsetLess = (this.page-2)*this.pageSize; + } + + let order = params['order']; + if (this.isAuthenticated()) { + if(order === undefined || (order != this.order.MODIFIED && order != this.order.LABEL && order != this.order.STATUS)) { + order = this.order.MODIFIED; + } + } else { + if(order === undefined || (order != this.order.PUBLISHED && order != this.order.LABEL)) { + order = this.order.PUBLISHED; + } + } + this.formGroup.get('order').setValue(order); + + let keyword = (params['keyword'] === undefined || params['keyword'].length <= 0) ? "" : params['keyword']; + this.formGroup.get("like").setValue(keyword); + + this.updateUrl(); + } + }); if (this.isAuthenticated()) { // const fields: Array = ["-modified"]; - this.formGroup.get('order').setValue(this.order.MODIFIED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.MODIFIED); + } const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const dmpDataTableRequest: DataTableRequest = new DataTableRequest(0, 5, { fields: fields }); + const dmpDataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, 5, { fields: fields }); dmpDataTableRequest.criteria = new DmpCriteria(); - dmpDataTableRequest.criteria.like = ""; + dmpDataTableRequest.criteria.like = this.formGroup.get('like').value; this.dmpService .getPaged(dmpDataTableRequest, "listing") .pipe(takeUntil(this._destroyed)) @@ -95,6 +133,13 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O this.dmpActivities = response.data; this.totalCount = response.totalCount; this.totalCountDmps.emit(this.dmpActivities.length); + if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { + let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], { queryParams: queryParams }) + } // this.totalCount < this.pageSize ? this.totalCountDmps.emit(response.totalCount) : this.totalCountDmps.emit(this.pageSize); // this.totalCountDmps.emit(this.totalCount); // this.dmpActivities.forEach(dmpActivity => { @@ -128,13 +173,22 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O // }); } else { this.publicMode = true; - this.formGroup.get('order').setValue(this.order.PUBLISHED); + if(!this.formGroup.get('order').value) { + this.formGroup.get('order').setValue(this.order.PUBLISHED); + } const dataTableRequest = this.setPublicDataTableRequest(); this.dmpService.getPaged(dataTableRequest, "listing").pipe(takeUntil(this._destroyed)).subscribe(response => { if (!response) { return []; } this.dmpActivities = response.data; this.totalCount = response.totalCount; this.totalCountDmps.emit(this.dmpActivities.length); + if(this.totalCount > 0 && this.totalCount <= (this.page-1)*this.pageSize && this.page > 1) { + let queryParams = { type: "dmps", page: 1, order: this.formGroup.get("order").value }; + if(this.formGroup.get("like").value) { + queryParams['keyword'] = this.formGroup.get("like").value; + } + this.router.navigate(["/home"], { queryParams: queryParams }) + } }); this.formGroup.get('like').valueChanges .pipe(takeUntil(this._destroyed), debounceTime(500)) @@ -145,11 +199,25 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O } } + ngOnChanges() { + if(this.isActive) { + this.updateUrl(); + } + } + + updateUrl() { + let parameters = "?type=dmps"+ + (this.page != 1 ? "&page="+this.page : "") + + (((this.formGroup.get("order").value != this.order.MODIFIED && !this.publicMode) || (this.formGroup.get("order").value != this.order.PUBLISHED && this.publicMode)) ? "&order="+this.formGroup.get("order").value : "") + + (this.formGroup.get("like").value ? ("&keyword="+this.formGroup.get("like").value) : ""); + this.location.go(this.router.url.split('?')[0]+parameters); + } + public isAuthenticated(): boolean { return !!this.authentication.current(); } - private setPublicDataTableRequest(fields?: Array): DataTableRequest { + private setPublicDataTableRequest(fields?: Array, more: boolean = true): DataTableRequest { const dmpCriteria = new DmpCriteria(); dmpCriteria.allVersions = false; dmpCriteria.isPublic = true; @@ -158,7 +226,7 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O if (!fields) { fields = new Array('-publishedAt'); } - const dataTableRequest: DataTableRequest = new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }); + const dataTableRequest: DataTableRequest = more ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : new DataTableRequest(this.offsetLess, this.pageSize, { fields: fields }); dataTableRequest.criteria = dmpCriteria; return dataTableRequest; } @@ -452,6 +520,9 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O } refresh(): void { + this.page = 1; + this.updateUrl(); + const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; this.startIndex = 0; const dmpDataTableRequest = this.isAuthenticated() ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields); @@ -465,24 +536,59 @@ export class RecentEditedDmpActivityComponent extends BaseComponent implements O this.dmpActivities = response.data; this.totalCount = response.totalCount; this.totalCountDmps.emit(this.dmpActivities.length); + if(response.data.length< this.pageSize) { + this.hasMoreResults = false; + } else { + this.hasMoreResults = true; + } }); } - public loadMore() { + public loadNextOrPrevious(more: boolean = true) { this.startIndex = this.startIndex + this.pageSize; const fields: Array = [((this.formGroup.get('order').value === 'status') || (this.formGroup.get('order').value === 'label') ? '+' : "-") + this.formGroup.get('order').value]; - const request = this.isAuthenticated() ? new DataTableRequest(this.startIndex, this.pageSize, { fields: fields }) : this.setPublicDataTableRequest(fields); + let request; + this.startIndex = (this.page)*this.pageSize; + if(this.page > 1) { + this.offsetLess = (this.page-2)*this.pageSize; + } + if(this.isAuthenticated()) { + if(more) { + request = new DataTableRequest(this.startIndex, this.pageSize, {fields: fields}) + } else { + request = new DataTableRequest(this.offsetLess, this.pageSize, {fields: fields}) + } + } else { + request = this.setPublicDataTableRequest(fields, more); + } if (this.isAuthenticated()) { request.criteria = new DmpCriteria(); request.criteria.like = this.formGroup.get("like").value ? this.formGroup.get("like").value : ""; } this.dmpService.getPaged(request, "listing").pipe(takeUntil(this._destroyed)).subscribe(result => { - if (!result) { return []; } - // this.dmpActivities = this.dmpActivities.concat(result.data); - this.dmpActivities = this.dmpActivities.length > 0 ? this.mergeTwoSortedLists(this.dmpActivities, result.data, this.formGroup.get('order').value) : result.data; - this.totalCountDmps.emit(this.dmpActivities.length); + if (!result || !result.data || result.data.length == 0) { + this.hasMoreResults = false; + // return []; + } else { + this.page = this.page + (more ? 1 : -1); + this.updateUrl(); + // this.dmpActivities = this.dmpActivities.concat(result.data); + // this.dmpActivities = this.dmpActivities.length > 0 ? this.mergeTwoSortedLists(this.dmpActivities, result.data, this.formGroup.get('order').value) : result.data; + this.dmpActivities = result.data; + + if(result.data.length < this.pageSize) { + this.hasMoreResults = false; + } else { + this.hasMoreResults = true; + } + + this.totalCountDmps.emit(this.dmpActivities.length); + if (more) { + this.resultsContainer.nativeElement.scrollIntoView(); + } + } }); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-visited-activity/recent-visited-activity.component.css b/dmp-frontend/src/app/ui/dashboard/recent-visited-activity/recent-visited-activity.component.css index e79187de7..cb5d9aee0 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-visited-activity/recent-visited-activity.component.css +++ b/dmp-frontend/src/app/ui/dashboard/recent-visited-activity/recent-visited-activity.component.css @@ -5,9 +5,9 @@ th { .is-public { padding-left: 5px; padding-right: 5px; - border: 1px solid #00b29f3b; - color: #00b29f; - background-color: #00b29f0f; + border: 1px solid var(--primary-color-3)3b; + color: var(--primary-color-3); + background-color: var(--primary-color-3)0f; border-radius: 10em; text-align: center; } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss index bed07edff..69f3e2062 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-copy-dialogue/dataset-copy-dialogue.component.scss @@ -22,17 +22,17 @@ min-width: 101px; .confirm-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } .confirm-btn:hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.scss b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.scss index 3a40b45e8..b006bc845 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.scss +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/dataset-editor/dataset-editor.component.scss @@ -53,7 +53,7 @@ } .input-btn :hover { - color: #00b29f !important; + color: var(--primary-color-3) !important; } .dmp-link { 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 48fdc4538..246e7ad8b 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 @@ -104,7 +104,7 @@ } .more-icon :hover { - color: #00b29f; + color: var(--primary-color-3); } .new-dataset { @@ -120,8 +120,8 @@ .dataset-editor-header { height: 113px; - background: var(--unnamed-color-129d99) 0% 0% no-repeat padding-box; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #00000029; padding: 0.6rem; margin: 30px 0px 0px 0px; @@ -192,7 +192,7 @@ justify-content: center; align-items: center; font-weight: 700; - color: #129d99; + color: var(--primary-color); } .dataset-discard-btn { @@ -227,7 +227,7 @@ text-align: left; font-size: 1rem; font-weight: 700; - color: #129d99; + color: var(--primary-color); line-height: 25px; } @@ -238,7 +238,7 @@ .dmp-label { min-width: 67px; height: 37px; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; color: white; border-radius: 4px; opacity: 1; @@ -264,7 +264,7 @@ opacity: 0.75; } .open-in-new-icon:hover { - color: #129d99; + color: var(--primary-color); } .dataset-stepper { @@ -347,7 +347,7 @@ width: 100%; height: 27px; line-height: 27px; - background-color: #f7dd72; + background-color: var(--secondary-color); color: #5d5d5d; border-radius: 4px; font-weight: 400; @@ -423,7 +423,7 @@ } .add-dataset-btn { - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; font-weight: 500; word-wrap: break-word; @@ -432,7 +432,7 @@ } .next { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; color: white; box-shadow: 0px 3px 6px #1e202029; font-weight: 400; @@ -440,7 +440,7 @@ } .dataset-next { - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; color: #212121; box-shadow: 0px 3px 6px #1e202029; font-weight: 700; @@ -500,7 +500,7 @@ mat-icon.size-18 { // } // ::ng-deep .mat-ink-bar { -// background-color: #00b29f !important; +// background-color: var(--primary-color-3) !important; // // background-color: #0070c0 !important; // } 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 618db108c..3f7210658 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 @@ -92,7 +92,10 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme datasetProfileDefinitionModel: DatasetDescriptionFormEditorModel; availableProfiles: DatasetProfileModel[] = []; + finalize: boolean = false; itemId: string; + dmpId: string; + newDmpId: string; publicId: string; profileUpdateId: string; downloadDocumentId: string; @@ -165,15 +168,26 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme const params = this.route.snapshot.params; const queryParams = this.route.snapshot.queryParams; + const data: any = this.route.snapshot.data; this.itemId = params['id']; - const dmpId = params['dmpId']; - const newDmpId = queryParams['newDmpId']; + this.dmpId = params['dmpId']; + this.newDmpId = queryParams['newDmpId']; this.publicId = params['publicId']; this.profileUpdateId = params['updateId']; - + this.finalize = data.finalize; this.itemId ? this.downloadDocumentId = this.itemId : this.downloadDocumentId = this.publicId - if (this.itemId != null && newDmpId == null) { + this.init(); + // this.route.params + // .pipe(takeUntil(this._destroyed)) + // .subscribe((params: Params) => { + // const itemId = params['id']; + // if (itemId != null) { setTimeout(() => this.stepper.selectedIndex = 2); } + // }); + } + + init() { + if (this.itemId != null && this.newDmpId == null) { this.isNew = false; this.datasetWizardService.getSingle(this.itemId) .pipe(takeUntil(this._destroyed)) @@ -222,8 +236,13 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme }, maxWidth: '30em' }); } + if(this.finalize && !this.lockStatus && !this.viewOnly) { + setTimeout(() => { + this.saveFinalize(); + }, 0); + } // this.availableProfiles = this.datasetWizardModel.dmp.profiles; - }) + }); }, error => { switch (error.status) { @@ -239,9 +258,9 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.router.navigate(['/datasets/']); return observableOf(null); }); - } else if (dmpId != null) { + } else if (this.dmpId != null) { this.isNew = true; - this.dmpService.getSingleNoDatasets(dmpId).pipe(map(data => data as DmpModel)) + this.dmpService.getSingleNoDatasets(this.dmpId).pipe(map(data => data as DmpModel)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { this.datasetWizardModel = new DatasetWizardEditorModel(); @@ -294,7 +313,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme }]); }); }); - } else if (newDmpId != null) { + } else if (this.newDmpId != null) { this.isNew = false; this.isCopy = true; this.datasetWizardService.getSingle(this.itemId) @@ -306,7 +325,7 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.datasetWizardModel.status = 0; this.formGroup = this.datasetWizardModel.buildForm(); this.formGroup.get('id').setValue(null); - this.dmpService.getSingleNoDatasets(newDmpId).pipe(map(data => data as DmpModel)) + this.dmpService.getSingleNoDatasets(this.newDmpId).pipe(map(data => data as DmpModel)) .pipe(takeUntil(this._destroyed)) .subscribe(data => { setTimeout(() => { @@ -442,13 +461,6 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme url: '/datasets/new/' }]); } - - // this.route.params - // .pipe(takeUntil(this._destroyed)) - // .subscribe((params: Params) => { - // const itemId = params['id']; - // if (itemId != null) { setTimeout(() => this.stepper.selectedIndex = 2); } - // }); } // private _listenersSubscription:Subscription = new Subscription(); @@ -953,9 +965,10 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme document.getElementById('dataset-editor-form').scrollTop = this.scrollTop; document.getElementById('stepper-options').scrollTop = this.tocScrollTop; }, 500); - this.saving = false; - this.isNew = false; + if(this.isNew) { + this.reloadDateset(this.datasetWizardModel.id); + } // this.router.navigate(['/reload']).then(() => { this.router.navigate(['/datasets', 'edit', data.id]); }); } } else { @@ -1326,7 +1339,10 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme }); dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { if (result) { - this.backToDmp(this.formGroup.get('dmp').value.id) + // this.backToDmp(this.formGroup.get('dmp').value.id) + setTimeout(x => { + this.init(); + }); } }); @@ -1338,6 +1354,10 @@ export class DatasetWizardComponent extends CheckDeactivateBaseComponent impleme this.router.navigate(['/datasets', 'new', dmpId]); } + reloadDateset(datasetId: string) { + this.router.navigate(['/datasets', 'edit', datasetId]); + } + backToDmp(id: string) { this.router.navigate(['/plans', 'edit', id]); } diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.html b/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.html index 4882e2944..4cf8f26cc 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.html +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/external-references/dataset-external-references-editor.component.html @@ -8,7 +8,7 @@
- +
diff --git a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.scss b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.scss index 55a2a967c..7a892e68b 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.scss +++ b/dmp-frontend/src/app/ui/dataset/dataset-wizard/prefill-dataset/prefill-dataset.component.scss @@ -3,7 +3,7 @@ display: flex; width: 100%; height: 60px; - background-color: #f7dd72; + background-color: var(--secondary-color); color: #212121; font-size: 1.25rem; } @@ -33,8 +33,8 @@ } .empty-btn, .prefill-btn { - background: #f7dd72 0 0 no-repeat padding-box; - border: 1px solid #f7dd72; + background: var(--secondary-color) 0 0 no-repeat padding-box; + border: 1px solid var(--secondary-color); border-radius: 30px; opacity: 1; min-width: 101px; diff --git a/dmp-frontend/src/app/ui/dataset/dataset.routing.ts b/dmp-frontend/src/app/ui/dataset/dataset.routing.ts index 90f46c598..c3381dc06 100644 --- a/dmp-frontend/src/app/ui/dataset/dataset.routing.ts +++ b/dmp-frontend/src/app/ui/dataset/dataset.routing.ts @@ -28,6 +28,18 @@ const routes: Routes = [ }, canDeactivate:[CanDeactivateGuard] }, + { + path: 'edit/:id/finalize', + component: DatasetWizardComponent, + canActivate: [AuthGuard], + data: { + breadcrumb: true, + public: false, + title: 'GENERAL.TITLES.DATASET-EDIT', + finalize: true + }, + canDeactivate:[CanDeactivateGuard] + }, { path: 'publicEdit/:publicId', component: DatasetWizardComponent, diff --git a/dmp-frontend/src/app/ui/dataset/listing/criteria/dataset-criteria.component.scss b/dmp-frontend/src/app/ui/dataset/listing/criteria/dataset-criteria.component.scss index 62c992251..a8e92de7c 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/criteria/dataset-criteria.component.scss +++ b/dmp-frontend/src/app/ui/dataset/listing/criteria/dataset-criteria.component.scss @@ -34,7 +34,7 @@ .filters-title { width: 93px; // color: #089dbb; - color: #23bcba; + color: var(--primary-color-2); background-color: white; padding: 0px 20px; margin-top: -10px; diff --git a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html index f03d171f4..5c99449fe 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html +++ b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.html @@ -11,7 +11,7 @@ - +
diff --git a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.scss b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.scss index e50263a3e..5042fe772 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.scss +++ b/dmp-frontend/src/app/ui/dataset/listing/dataset-listing.component.scss @@ -102,7 +102,7 @@ max-width: 256px; height: 40px; cursor: pointer; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; border: none; @@ -119,7 +119,7 @@ max-width: 256px; height: 40px; cursor: pointer; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 30px; opacity: 1; border: none; @@ -148,7 +148,7 @@ .filter-btn button { color: white; - background-color: #23bcba; + background-color: var(--primary-color-2); width: 37px; height: 45px; } @@ -173,7 +173,7 @@ } .search-form mat-icon { - color: #129d99; + color: var(--primary-color); } .empty-list { @@ -186,7 +186,7 @@ } .pointer:hover { - color: #00b29f; + color: var(--primary-color-3); } ::ng-deep .search-form .mat-form-field-wrapper { @@ -250,12 +250,12 @@ ::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle { border-color: #777777; - // border-color: #00b29f; + // border-color: var(--primary-color-3); } ::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle { - // color: #00b29f; - // background-color: #00b29f; + // color: var(--primary-color-3); + // background-color: var(--primary-color-3); color: #777777; background-color: #777777; } diff --git a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.scss b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.scss index 659ab566b..20b421820 100644 --- a/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.scss +++ b/dmp-frontend/src/app/ui/dataset/listing/listing-item/dataset-listing-item.component.scss @@ -18,7 +18,7 @@ } .container-header :hover { - color: #00b29f; + color: var(--primary-color-3); } h4 { @@ -42,11 +42,11 @@ h4 > span { } .links :hover { - color: #00b29f; + color: var(--primary-color-3); } .about-item .length { - color: #00b29f; + color: var(--primary-color-3); } .about-item .title { @@ -66,7 +66,7 @@ p { } .storage :hover { - color: #00b29f; + color: var(--primary-color-3); } .draft-bookmark { @@ -115,7 +115,7 @@ input[type="text"] { } .dmp-label { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; opacity: 1; min-width: 67px; @@ -127,7 +127,7 @@ input[type="text"] { .dataset-label { width: auto; height: 37px; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; text-align: left; line-height: 2.8; @@ -209,7 +209,7 @@ input[type="text"] { .dataset-card-actions a:hover, .dmp-card-actions a:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .dmp-dataset-descriptions-title { @@ -230,7 +230,7 @@ input[type="text"] { } .show-more:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .btn-load-more { diff --git a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss index 33bf2bc8b..4d5c9c4c6 100644 --- a/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss +++ b/dmp-frontend/src/app/ui/dataset/overview/dataset-overview.component.scss @@ -17,7 +17,7 @@ width: 2.5em; height: 2.5em; color: #212121; - background-color: #f7dd72; + background-color: var(--secondary-color); } .mat-mini-fab-icon, @@ -27,7 +27,7 @@ .actions-btn:hover, .finalize-btn:hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } @@ -63,7 +63,7 @@ .dmp-btn { width: 35em; min-height: 2.3em; - background-color: #129d99; + background-color: var(--primary-color); border-radius: 4px; flex-direction: row; justify-content: space-between; @@ -80,7 +80,7 @@ width: 31.6em; padding: 0 1em; background-color: #ffffff00; - color: #129d99; + color: var(--primary-color); font-weight: 700; } @@ -91,7 +91,7 @@ } .finalize-btn { - // border: 1px solid #F7DD72; + // border: 1px solid var(--secondary-color); background: #f5db71; } @@ -129,7 +129,7 @@ .dataset-logo { width: 6em; height: 2.6em; - background: #f7dd72; + background: var(--secondary-color); border-radius: 4px; font-size: 0.875em; // color: #212121; @@ -162,7 +162,7 @@ .researcher { font-size: 0.875em; - color: #008887; + color: var(--primary-color); padding-right: 0.5em; align-self: center; } 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 750f98a47..acbcca4f1 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 @@ -53,7 +53,6 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { breadCrumbs: Observable = observableOf(); isUserOwner: boolean; expand = false; - hasDOIToken = false; researchers: ResearcherModel[]; users: UserInfoListingModel[]; lockStatus: Boolean; @@ -498,7 +497,7 @@ export class DatasetOverviewComponent extends BaseComponent implements OnInit { takeUntil(this._destroyed) ) .subscribe( _ =>{ - this.router.navigate(['datasets','edit',dataset.id]); + this.router.navigate(['datasets','edit',dataset.id, 'finalize']); }) diff --git a/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.scss b/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.scss index 2ef15d145..d2a67e117 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.scss +++ b/dmp-frontend/src/app/ui/dmp/clone/clone-dialog/clone-dialog.component.scss @@ -45,14 +45,14 @@ min-width: 84px; height: 43px; background: #ffffff; - color: #129d99; - border: 1px solid #129d99; + color: var(--primary-color); + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; } .confirm-btn:hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } } diff --git a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.scss b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.scss index 9f4c70e5f..5a9122ecf 100644 --- a/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.scss +++ b/dmp-frontend/src/app/ui/dmp/clone/dmp-clone.component.scss @@ -7,7 +7,7 @@ a { } a:hover { - color: #00b29f; + color: var(--primary-color-3); } .main-content { @@ -23,8 +23,8 @@ a:hover { .editor-header { height: 64px; - background: var(--unnamed-color-129d99) 0% 0% no-repeat padding-box; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #00000029; padding: 0.6rem; margin: 30px 0px 0px 0px; @@ -41,8 +41,8 @@ a:hover { .dataset-editor-header { height: 113px; - background: var(--unnamed-color-129d99) 0% 0% no-repeat padding-box; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--unnamed-color-var(--primary-color)) 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #00000029; padding: 0.6rem; margin: 30px 0px 0px 0px; @@ -135,7 +135,7 @@ a:hover { justify-content: center; align-items: center; font-weight: 700; - color: #129d99; + color: var(--primary-color); cursor: pointer; } @@ -241,7 +241,7 @@ a:hover { .dataset-tag { width: 73px; height: 27px; - background-color: #f7dd72; + background-color: var(--secondary-color); color: #5d5d5d; border-radius: 4px; font-weight: 400; @@ -286,7 +286,7 @@ a:hover { } .next { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; color: white; box-shadow: 0px 3px 6px #1e202029; font-weight: 400; @@ -294,7 +294,7 @@ a:hover { } .dataset-next { - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; color: #212121; box-shadow: 0px 3px 6px #1e202029; font-weight: 700; @@ -322,7 +322,7 @@ a:hover { .dmp-label { min-width: 67px; height: 37px; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; color: white; border-radius: 4px; opacity: 1; @@ -372,7 +372,7 @@ a:hover { // } ::ng-deep .mat-ink-bar { - background-color: #00b29f !important; + background-color: var(--primary-color-3) !important; // background-color: #0070c0 !important; } @@ -405,7 +405,7 @@ a:hover { // } // .more-icon :hover { -// color: #00b29f; +// color: var(--primary-color-3); // } // ::ng-deep .mat-tab-labels { @@ -417,5 +417,5 @@ a:hover { // } // ::ng-deep .mat-ink-bar { -// background-color: #00b29f !important; +// background-color: var(--primary-color-3) !important; // } diff --git a/dmp-frontend/src/app/ui/dmp/dataset-preview/dataset-preview-dialog.component.scss b/dmp-frontend/src/app/ui/dmp/dataset-preview/dataset-preview-dialog.component.scss index cf8386431..f64cc489e 100644 --- a/dmp-frontend/src/app/ui/dmp/dataset-preview/dataset-preview-dialog.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dataset-preview/dataset-preview-dialog.component.scss @@ -3,7 +3,7 @@ display: flex; width: 100%; height: 89px; - background-color: #129D99; + background-color: var(--primary-color); color: #FFFFFF; font-size: 1.25rem; } @@ -33,8 +33,8 @@ } .start-btn { - background: #129d99 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + background: var(--primary-color) 0% 0% no-repeat padding-box; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; diff --git a/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.html b/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.html index ff171f0fa..264029888 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.html +++ b/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.html @@ -19,6 +19,6 @@ - + diff --git a/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.scss b/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.scss index 01fd3d2a2..edbe4157a 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.scss +++ b/dmp-frontend/src/app/ui/dmp/dmp-to-dataset/dmp-to-dataset-dialog.component.scss @@ -38,8 +38,8 @@ } .start-btn { - background: #129d99 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + background: var(--primary-color) 0% 0% no-repeat padding-box; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; @@ -49,7 +49,7 @@ } .color-green { - color: #129d99; + color: var(--primary-color); font-weight: 500; } diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-editor-details/dataset-editor-details.component.scss b/dmp-frontend/src/app/ui/dmp/editor/dataset-editor-details/dataset-editor-details.component.scss index ff8c96676..9d2f3fdf7 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-editor-details/dataset-editor-details.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/dataset-editor-details/dataset-editor-details.component.scss @@ -57,7 +57,7 @@ } .input-btn :hover { - color: #00b29f !important; + color: var(--primary-color-3) !important; } .dmp-link { diff --git a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss index 4dc2ab551..4d5220f39 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/dataset-info/dataset-info.component.scss @@ -56,7 +56,7 @@ } .input-btn :hover { - color: #00b29f !important; + color: var(--primary-color-3) !important; } .not-found { diff --git a/dmp-frontend/src/app/ui/dmp/editor/datasets-tab/datasets-tab.component.scss b/dmp-frontend/src/app/ui/dmp/editor/datasets-tab/datasets-tab.component.scss index 1b3deaba4..7f90f8e5e 100644 --- a/dmp-frontend/src/app/ui/dmp/editor/datasets-tab/datasets-tab.component.scss +++ b/dmp-frontend/src/app/ui/dmp/editor/datasets-tab/datasets-tab.component.scss @@ -45,7 +45,7 @@ .show-more { background-color: #ffffff00; - color: #00b29f; + color: var(--primary-color-3); font-weight: 700; justify-self: center; } 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 ae70a647e..37a0be5d1 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 @@ -43,7 +43,7 @@ [vertical]="true" class="ml-2 mr-2">
-
diff --git a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.scss b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.scss index 2d71d0e3d..1ff157f67 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.scss +++ b/dmp-frontend/src/app/ui/dmp/listing/dmp-listing.component.scss @@ -69,7 +69,7 @@ } .more-icon :hover { - color: #00b29f; + color: var(--primary-color-3); } .header-image { @@ -163,7 +163,7 @@ max-width: 256px; height: 40px; cursor: pointer; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; border: none; @@ -180,7 +180,7 @@ max-width: 256px; height: 40px; cursor: pointer; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 30px; opacity: 1; border: none; @@ -211,7 +211,7 @@ .filter-btn button { color: white; - background-color: #23bcba; + background-color: var(--primary-color-2); width: 37px; height: 45px; } @@ -223,7 +223,7 @@ } .search-form mat-icon { - color: #129d99; + color: var(--primary-color); } .empty-list { @@ -242,7 +242,7 @@ .pointer:hover, .zenodo-link:hover { - color: #00b29f; + color: var(--primary-color-3); } ::ng-deep .search-form .mat-form-field-wrapper { diff --git a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.scss b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.scss index e77d00b31..9f90fdda3 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.scss +++ b/dmp-frontend/src/app/ui/dmp/listing/listing-item/dmp-listing-item.component.scss @@ -17,7 +17,7 @@ } .container-header :hover { - color: #00b29f; + color: var(--primary-color-3); } h4 { @@ -45,7 +45,7 @@ h4 > span { } .datasets-counter :hover { - color: #00b29f !important; + color: var(--primary-color-3) !important; } .about-item .title { @@ -149,7 +149,7 @@ input[type="text"] { } .dmp-label { - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; opacity: 1; min-width: 67px; @@ -161,7 +161,7 @@ input[type="text"] { .dataset-label { width: auto; height: 37px; - background: #f7dd72 0% 0% no-repeat padding-box; + background: var(--secondary-color) 0% 0% no-repeat padding-box; border-radius: 4px 0px; text-align: left; line-height: 2.8; @@ -240,7 +240,7 @@ input[type="text"] { .dataset-card-actions a:hover, .dmp-card-actions a:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .dmp-dataset-descriptions-title { @@ -261,7 +261,7 @@ input[type="text"] { } .show-more:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .btn-load-more { diff --git a/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.scss b/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.scss index b959e43c7..fad4d3f42 100644 --- a/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.scss +++ b/dmp-frontend/src/app/ui/dmp/listing/upload-dialogue/dmp-upload-dialogue.component.scss @@ -37,12 +37,12 @@ min-width: 101px; .next-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } @@ -56,7 +56,7 @@ min-width: 101px; } .next-btn:not([disabled]):hover { - background-color: #129d99; + background-color: var(--primary-color); color: #ffffff; } @@ -70,7 +70,7 @@ min-width: 101px; // } // .next-btn:hover { -// background: #129d99; +// background: var(--primary-color); // color: #ffffff; // } @@ -82,15 +82,15 @@ min-width: 101px; min-width: 156px; height: 44px; color: #ffffff; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; } .attach-file:hover { background-color: #ffffff; - border: 1px solid #129d99; - color: #129d99; + border: 1px solid var(--primary-color); + color: var(--primary-color); } .drop-file { diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss index 19f35902f..9833fa58d 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.scss @@ -16,7 +16,7 @@ .mat-mini-fab { width: 2.5em; height: 2.5em; - background-color: #129d99; + background-color: var(--primary-color); color: white; } @@ -45,7 +45,7 @@ .dataset-btn { width: 36.1em; padding: 0 1.1em; - background-color: #f7dd72; + background-color: var(--secondary-color); border-radius: 4px; justify-content: space-between; color: #212121; @@ -65,7 +65,7 @@ width: 31.6em; padding: 0 1em; background-color: #ffffff00; - color: #129d99; + color: var(--primary-color); font-weight: 700; } @@ -75,8 +75,8 @@ } .finalize-btn { - border: 1px solid #129d99; - color: #129d99; + border: 1px solid var(--primary-color); + color: var(--primary-color); } .grant-title { @@ -125,7 +125,7 @@ padding: 10px; min-width: 4.8em; height: 2.6em; - background: #129d99; + background: var(--primary-color); border-radius: 4px; font-size: 0.875em; color: #ffffff; @@ -155,7 +155,7 @@ .researcher { font-size: 0.875em; - color: #008887; + color: var(--primary-color); padding-right: 0.5em; align-self: center; } @@ -237,7 +237,7 @@ } .finalize-txt { - color: #129d99; + color: var(--primary-color); } .frame-txt, @@ -305,7 +305,7 @@ } .add-dataset-btn:hover { - color: #129d99 !important; + color: var(--primary-color) !important; } .show-more-btn { @@ -356,7 +356,7 @@ // } // .more-icon :hover { -// color: #00b29f; +// color: var(--primary-color-3); // } // .export-btn { @@ -453,7 +453,7 @@ // } // .container-header :hover { -// color: #00b29f; +// color: var(--primary-color-3); // } // .dataset-card { @@ -480,13 +480,13 @@ // .show-more { // background-color: #ffffff00; -// color: #00b29f; +// color: var(--primary-color-3); // font-weight: 700; // justify-self: center; // } // .visit-website { -// background-color: #00b29f; +// background-color: var(--primary-color-3); // color: #ffffff; // } @@ -550,7 +550,7 @@ // } // .datasets-counter :hover { -// color: #00b29f !important; +// color: var(--primary-color-3) !important; // } // .total-info { @@ -594,5 +594,5 @@ // } // .interact-icon :hover { -// color: #00b29f !important; +// color: var(--primary-color-3) !important; // } diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts index 6e83b0dcf..d7978b1cb 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.ts @@ -64,7 +64,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { breadCrumbs: Observable = observableOf(); isUserOwner: boolean; expand = false; - hasDOIToken = false; lockStatus: Boolean; textMessage: any; versions: VersionListingModel[]; @@ -510,7 +509,6 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { if (result.length > 0) { this.dmp.dois = result; this.selectedModel = this.dmp.dois[this.dmp.dois.length - 1]; - this.hasDOIToken = true; } } @@ -653,15 +651,15 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { } createDoiLink(doiModel: DoiModel): string { - const recordUrl = this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl; - if(typeof recordUrl !== "undefined"){ + const repository = this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId); + if(typeof repository !== "undefined"){ if(doiModel.repositoryId == "Zenodo"){ const doiarr = doiModel.doi.split('.'); const id = doiarr[doiarr.length - 1]; - return this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl + id; + return repository.repositoryRecordUrl + id; } else{ - return this.depositRepos.find(r => r.repositoryId == doiModel.repositoryId).repositoryRecordUrl + doiModel.doi; + return repository.repositoryRecordUrl + doiModel.doi; } } else{ @@ -838,90 +836,4 @@ export class DmpOverviewComponent extends BaseComponent implements OnInit { // return url; // } - // getDoi(dmp: DmpOverviewModel) { - // this.userService.hasDOIToken().subscribe(response => { - // this.hasDOIToken = true; - // this.showConfirmationDOIDialog(dmp); - // }, error => { - // this.hasDOIToken = false; - // this.showErrorConfirmationDOIDialog(error.error.message, dmp); - // }); - // } - - // showConfirmationDOIDialog(dmp: DmpOverviewModel) { - // const dialogRef = this.dialog.open(ConfirmationDialogComponent, { - // maxWidth: '600px', - // restoreFocus: false, - // data: { - // message: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ZENODO-DOI', { 'username': this.hasDOIToken ? this.authentication.current().zenodoEmail : 'default' }), - // confirmButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CONFIRM'), - // cancelButton: this.language.instant('GENERAL.CONFIRMATION-DIALOG.ACTIONS.CANCEL'), - // } - // }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - // if (result) { - // this.dmpService.getDoi(dmp.id) - // .pipe(takeUntil(this._destroyed)) - // .subscribe( - // complete => { - // this.onDOICallbackSuccess(); - // this.dmp.doi = complete; - // }, - // error => this.onDeleteCallbackError(error) - // ); - // } - // }); - // } - - // showErrorConfirmationDOIDialog(message: string, dmp: DmpOverviewModel) { - // const dialogRef = this.dialog.open(MultipleChoiceDialogComponent, { - // maxWidth: '600px', - // restoreFocus: false, - // data: { - // message: message ? this.language.instant(message) : this.language.instant('GENERAL.ERRORS.HTTP-REQUEST-ERROR'), - // titles: [this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.ZENODO-LOGIN'), this.language.instant('DMP-OVERVIEW.MULTIPLE-DIALOG.USE-DEFAULT')] - // } - // }); - // dialogRef.afterClosed().pipe(takeUntil(this._destroyed)).subscribe(result => { - // switch (result) { - // case 0: - // // this.authentication.logout(); - // // this.router.navigate(['/login/external/zenodo']); - // this.showOauth2Dialog(this.getAccessUrl(), dmp); - // break; - // case 1: - // this.showConfirmationDOIDialog(dmp); - // break; - // } - // }); - // } - - // showOauth2Dialog(url: string, 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.userService.registerDOIToken(result.oauthCode, this.configurationService.app + 'oauth2') - // .pipe(takeUntil(this._destroyed)) - // .subscribe(() => { - // this.hasDOIToken = true; - // this.showConfirmationDOIDialog(dmp); - // }); - // this.oauthLock = true; - // } - // } else { - // this.oauthLock = false; - // } - // }); - // } - - // 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); - // } - } diff --git a/dmp-frontend/src/app/ui/dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component.scss b/dmp-frontend/src/app/ui/dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component.scss index fae608bac..d7a6c0848 100644 --- a/dmp-frontend/src/app/ui/dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component.scss +++ b/dmp-frontend/src/app/ui/dmp/start-new-dataset-dialogue/start-new-dataset-dialog.component.scss @@ -63,17 +63,17 @@ min-width: 101px; .next-btn { background: #ffffff 0% 0% no-repeat padding-box; - border: 1px solid #129d99; + border: 1px solid var(--primary-color); border-radius: 30px; opacity: 1; min-width: 101px; height: 43px; - color: #129d99; + color: var(--primary-color); font-weight: 500; } .next-btn:hover { - background-color: #129d99; + background-color: var(--primary-color); color: white; } @@ -96,7 +96,7 @@ min-width: 101px; text-align: left; text-decoration: underline; letter-spacing: 0px; - color: #008887; + color: var(--primary-color); cursor: pointer; } diff --git a/dmp-frontend/src/app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component.html b/dmp-frontend/src/app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component.html index 1221e1f4f..366410fe6 100644 --- a/dmp-frontend/src/app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component.html +++ b/dmp-frontend/src/app/ui/dmp/start-new-dmp-dialogue/start-new-dmp-dialog.component.html @@ -1,6 +1,6 @@
- +
close
diff --git a/dmp-frontend/src/app/ui/dmp/wizard/editor/dmp-wizard-editor.component.scss b/dmp-frontend/src/app/ui/dmp/wizard/editor/dmp-wizard-editor.component.scss index d7df7678d..3d03c286e 100644 --- a/dmp-frontend/src/app/ui/dmp/wizard/editor/dmp-wizard-editor.component.scss +++ b/dmp-frontend/src/app/ui/dmp/wizard/editor/dmp-wizard-editor.component.scss @@ -14,7 +14,7 @@ } .input-btn :hover { - color: #00b29f !important; + color: var(--primary-color-3) !important; } .table-card .mat-grid-tile { diff --git a/dmp-frontend/src/app/ui/explore-dataset/filters/explore-dataset-filters.component.scss b/dmp-frontend/src/app/ui/explore-dataset/filters/explore-dataset-filters.component.scss index d59ca2f65..e4fb0d02b 100644 --- a/dmp-frontend/src/app/ui/explore-dataset/filters/explore-dataset-filters.component.scss +++ b/dmp-frontend/src/app/ui/explore-dataset/filters/explore-dataset-filters.component.scss @@ -32,7 +32,7 @@ .filters-title { width: 90px; // color: #089dbb; - color: #23bcba; + color: var(--primary-color-2); background-color: white; padding: 0px 20px; margin-top: -10px; @@ -49,7 +49,7 @@ // } // ::ng-deep .mat-focused .mat-form-field-label { -// color: #00b29f !important; +// color: var(--primary-color-3) !important; // } // ::ng-deep.mat-form-field-underline { @@ -57,7 +57,7 @@ // } // ::ng-deep.mat-form-field-ripple { -// background-color: #00b29f !important; +// background-color: var(--primary-color-3) !important; // } // ::ng-deep .mat-checkbox { @@ -74,7 +74,7 @@ .mat-accent .mat-pseudo-checkbox-indeterminate, .mat-pseudo-checkbox-checked, .mat-pseudo-checkbox-indeterminate { - background-color: #00b29f; + background-color: var(--primary-color-3); } ::ng-deep .mat-ripple-element { @@ -92,14 +92,14 @@ ::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle { border-color: #777777; - // border-color: #00b29f; + // border-color: var(--primary-color-3); } ::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle { color: #777777; background-color: #777777; - // color: #00b29f; - // background-color: #00b29f; + // color: var(--primary-color-3); + // background-color: var(--primary-color-3); } .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element { diff --git a/dmp-frontend/src/app/ui/explore-dataset/listing-item/explore-dataset-listing-item.component.scss b/dmp-frontend/src/app/ui/explore-dataset/listing-item/explore-dataset-listing-item.component.scss index 26c7bf5b0..99897de43 100644 --- a/dmp-frontend/src/app/ui/explore-dataset/listing-item/explore-dataset-listing-item.component.scss +++ b/dmp-frontend/src/app/ui/explore-dataset/listing-item/explore-dataset-listing-item.component.scss @@ -34,7 +34,7 @@ h4 { } .about-item .length { - color: #00b29f; + color: var(--primary-color-3); // color: #089dbb; } diff --git a/dmp-frontend/src/app/ui/explore-dmp/dmp-explore-filters/explore-dmp-filters.component.scss b/dmp-frontend/src/app/ui/explore-dmp/dmp-explore-filters/explore-dmp-filters.component.scss index c1cd0df9a..f42ffd3fb 100644 --- a/dmp-frontend/src/app/ui/explore-dmp/dmp-explore-filters/explore-dmp-filters.component.scss +++ b/dmp-frontend/src/app/ui/explore-dmp/dmp-explore-filters/explore-dmp-filters.component.scss @@ -32,7 +32,7 @@ .filters-title { width: 93px; // color: #089dbb; - color: #23bcba; + color: var(--primary-color-2); background-color: white; padding: 0px 20px; margin-top: -10px; @@ -49,7 +49,7 @@ // } // ::ng-deep .mat-focused .mat-form-field-label { -// color: #00b29f !important; +// color: var(--primary-color-3) !important; // } // ::ng-deep.mat-form-field-underline { @@ -57,7 +57,7 @@ // } // ::ng-deep.mat-form-field-ripple { -// background-color: #00b29f !important; +// background-color: var(--primary-color-3) !important; // } // ::ng-deep .mat-checkbox { @@ -74,7 +74,7 @@ .mat-accent .mat-pseudo-checkbox-indeterminate, .mat-pseudo-checkbox-checked, .mat-pseudo-checkbox-indeterminate { - background-color: #00b29f; + background-color: var(--primary-color-3); } ::ng-deep .mat-ripple-element { @@ -92,14 +92,14 @@ ::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle { border-color: #777777; - // border-color: #00b29f; + // border-color: var(--primary-color-3); } ::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle { color: #777777; background-color: #777777; - // color: #00b29f; - // background-color: #00b29f; + // color: var(--primary-color-3); + // background-color: var(--primary-color-3); } .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element { diff --git a/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.scss b/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.scss index 53f7173c0..8e71079de 100644 --- a/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.scss +++ b/dmp-frontend/src/app/ui/explore-dmp/listing-item/explore-dmp-listing-item.component.scss @@ -22,7 +22,7 @@ } .about-item .length { - color: #00b29f; + color: var(--primary-color-3); // color: #089dbb; } diff --git a/dmp-frontend/src/app/ui/faq/dialog/faq-dialog.component.html b/dmp-frontend/src/app/ui/faq/dialog/faq-dialog.component.html index 526d13413..30f2126a1 100644 --- a/dmp-frontend/src/app/ui/faq/dialog/faq-dialog.component.html +++ b/dmp-frontend/src/app/ui/faq/dialog/faq-dialog.component.html @@ -7,7 +7,7 @@ close
-
+
diff --git a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.html b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.html index 28ff25f85..e87b95039 100644 --- a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.html +++ b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.html @@ -1,678 +1,5 @@ -
-
-
-

{{ 'FAQ.TITLE-DASHED' | translate}}

-
-
+
-
-

About ARGOS

-

What is ARGOS?

-

Argos is an open and collaborative platform developed by OpenAIRE to facilitate - Research Data Management (RDM) activities concerning the implementation of Data - Management Plans. It uses OpenAIRE guides created by the RDM Task Force to - familiarize users with basic RDM concepts and guide them throughout the process of - writing DMPs. It also utilises the OpenAIRE pool of services and inferred sources to - make DMPs more dynamic in use and easier to be completed and published. Argos is - based on the OpenDMP open source software and is available through the OpenAIRE - Service catalogue and the EOSC.

- -
-

Is Argos designed for one specific funder, e.g. the EC/Horizon Europe?

-

- Argos is a flexible tool, designed to accommodate all research performing - and research funding organisations’ policies and Research Data Management (RDM) needs. - It already supports templates for different authorities. - These templates are created by Admin users in Argos. - In addition, we currently work to provide non-administrative users with the capability - to modify templates according to their own needs. -

-
-

Why use Argos?

-

Argos is easy to use and navigate around. It familiarises users with the DMP process - and provides guidance on basic RDM concepts so that users find useful resources to - learn from without having to leave the Argos environment. Users can invite their - colleagues and collaboratively work on completing a DMP. Moreover, Argos is an - integral part of the OpeAIRE ecosystem and the Research - Graph. Argos integrates - other services of the ecosystem to enable contextualisation of information, which is - especially useful when data are re-used, for example to understand how/ if they can - be repurposed.

-
-

Who is Argos for?

-

Argos is designed as a tool for inclusive use by researchers, students, funders, - research communities and institutions. It can be used in the context of research - projects’ conduct to comply with funders’ RDM requirements, as a tool in support of - literacy programmes in academia or can be independently deployed to meet given - stakeholder demands. Also, it is available in native languages, thanks to the help - of OpenAIRE NOADs, which strengthens common understanding of all researchers - involved in the DMP writing process. - By using Argos, researchers and students are able to create their DMPs in - collaboration with other colleagues, learn basic RDM concepts throughout the process - and publish DMPs as outputs in an open and FAIR manner, among other things by - assigning DOIs and licenses and by maintaining DMPs as living documents through - versioning. - At the same time, Argos can be configured and deployed by funders, institutions and - research communities. They can plug in their own services and/ or make use of - OpenAIRE underlying services that Argos is built with ad-hoc.

-
-

Using Argos

-

- Argos consists of two main functionalities: DMPs and Datasets. - Argos can be used for: -

- A. Viewing/ consulting publicly released DMPs and Datasets or Projects - corresponding to - DMPs -

- Argos offers options for publishing DMPs in two modes, private or public. To view - public DMPs and Datasets, there is no need for login to the platform. -

- B. Writing and publishing a DMP -

- Argos helps researchers comply with mandates that may be attached to their grant - proposal/ project funding. They can therefore choose from the most suitable to their - needs template from the Datasets collection and proceed with answering the - corresponding questions. Once finalized, researchers can assign a DOI to their DMP, - publish and eventually cite it. -

- C. Practicing on writing DMPs and Dataset Descriptions -

- Argos may be used for educational purposes. The process of Data Management Planning - reflects the data management lifecycle, hence the tool can be used in response to - global RDM training demands. Examples may refer to embedding DMPs and DMP tools in - specific curricula or be embedded in library instructions’ sessions to familiarize - researchers and students the processes of RDM and DMP. -

-
-

Can I exploit ARGOS DMPs?

-

- Of course. If you want to compare DMPs or analyse DMP data, then we advise you to export the records in .xml. - This schema is the most complete as it includes all information held in a DMP: information provided by the Admin - when structuring the template and input provided by researchers when completing their DMPs. -

-
-

Manage Account

-

Log in and out of Argos

-

- You can log in Argos by selecting one of the providers from the Login page. Argos - does not require Sign Up. -

-
-

Create an administrator account

-

- If you are interested in becoming an administrator in Argos and benefit from extra - features relevant to creating tailored templates, please email argos@openaire.eu . -

- -
-

- Switch from administrator account -

-

- There is no need to switch from your administrator account to use Argos. The only - difference between regular users and administrators profiles in Argos is an extra - set of tools at the bottom of the main tool bar that is positioned on the left - handside. -

-
-

- Change your email -

-

- Argos does not have Sign Up. To change email, please see “Switch between accounts”. - Alternatevily, you can add more email addresses to your user account by selecting - the “Add alternative email” from your profile. -

-
-

- Switch between accounts -

-

- You can switch between email accounts by loging in with different providers from the - Login page. The change depends on whether you have used different email addresses to - sign up with those providers. On the occassion that only one email address is used - for all providers offered by Argos, then no change is expected. You can always add - new email accounts in your profile from the “Add alternative email” in your profile - page. -

-
-

- Delete your account -

-

- If you want to delete your Argos profile, please email argos@openaire.eu . -

-
-

- Accounts access and safety -

-

- How can I access my account and edit my profile? -

-

- You can access your profile page and make desired edits from clicking on the avatar - at the very top of the toolbar located on the right handside. -

-
-

- Can’t login to ARGOS -

-

- Please try using a different provider from the Login page and contact us at: - argos@openaire.eu . -

-
-

- Accessing Argos -

-

- If you are reading this right now, you probably know the answer already! One way to - access Argos is through the OpenAIRE Service - catalogue. Another way is through the - EOSC - Catalogue. But, you can always find Argos at - argos.openaire.eu . - To access Argos software, please visit - https://code-repo.d4science.org/MaDgiK-CITE/argos/src/branch/master - . -

-
-

Argos User Roles

-

- Who is the author of a DMP? -

-

- Author of the DMP is everyone contributing to writing the DMP. Both Argos owners and - Argos members are DMP authors. Researchers, however, are not DMP authors. -

-
-

- What is the difference between owners and - members? -

-

- Argos DMP owner is the person initiating the DMP. People who are invited to join the - DMP process are members who contribute to writing the DMP. DMP owners have extra - editing rights and they are the ones to finalize the DMP process. Members can view - and edit DMPs and Datasets, but can not perform further actions for its validation - or finalization. -

-
-

- What is the role of a researcher in Argos? -

-

- Researchers in Argos are project contributors and usually those who own or have - managed data described in respective DMPs. -

-
-

- Can a researcher be a DMP author? -

-

- Of course! This depends on whether the researcher has also been involved in the DMP - writing process. -

-
-

- What does an Admin user do? -

-

- Not everyone can become an Admin user in Argos. This happens upon request at - argos@openaire.eu. Admin users are able to create - their own tailored templates from - a specialised editor, configure their own APIs and integrate services with Argos in - collaboration with and support of the Argos development team. Fees may apply - according to the type of requests. -

-
-

Creating DMPs

-

- I can’t find my project in the list. What should - I do? -

-

- DMPs that are created as part of the project proposal are not included in Argos. - Only accepted project proposals are listed in the platform. If you can’t find your - project in the list (drop-down menu), please use the “Insert manually” - functionality. -

-
-

- I can’t find my grant in the list. What should I - do? -

-

- If you can’t find your grant in the list (drop-down menu), please use the “Insert - manually” functionality. -

-
-

- How do I edit and design my own DMP - template? -

-

- You have to be an Admin user to design your own template in Argos. To learn more - about Admin users, check “What does an Admin user do?”. -

-
-

- Can I create my own templates in Argos? -

-

- Yes, you can, provided that you are an Admin user. To learn more about Admin users, - check “What does an Admin user do?”. -

-
-

- What is the difference between “Save”, “Save & - Close”, “Save & Add New”? -

-
-

They all perform the same action, but the difference lies in where you are directed - after you have saved your DMP or Dataset.

-
    -
  • - When choosing Save, information that you have added in the editor is kept - and you - can continue adding more from the same page you were working on. -
  • -
  • - When choosing Save & Close, information that you have added is kept, but the - editor’s window closes and you are redirected to your dashboard. -
  • -
  • - [only for datasets] When choosing Save & Add New, information that you have - added is - kept, and you are redirected to another editor to start a new dataset. -
  • -
-
-
-

- Can I modify things once I have finalized - them? -

-

- Yes, you can, as long as you haven’t assigned a DOI to your DMP. You just select - “Undo Finalization”. -

-
-

- How do I invite collaborators? -

-

- You may use the “Invite” button to share DMPs with your colleagues and start working - on them together. -

-
-

- Can scientists collaborate on the same DMP even though they may belong to different institutions (e.g. a hospital, a University, etc, collaborating on a project) and the dataset also "belongs" to different institutions? -

-

- Of course. Argos supports collaborations across diverse teams. There are two most frequent ways that can address this question: -

- A. Everyone works on the same DMP, but on different dataset descriptions -

- In this case, each organisation makes its own dataset description(s) in a single DMP. - That means that the manager (i.e. person responsible for the DMP activity) creates a DMP in ARGOS - and shares it with everyone. If the DMP is shared with co-ownership rights, - then the people will be able to edit it and add their dataset descriptions at any time during the project. - If there is the need to control editing rights of people writing the DMPs, then the manager can create the dataset description(s) - and share these each time with the team members that are responsible for adding input for the specified datasets. -

- B. Everyone works on their own DMP and content is later merged into one single DMP -

- In this case, each organisation might work on their own DMP for the same project. - At one point, you need to decide which DMP is going to be the core for the work you perform, share co-ownership - between managers of all DMPs so they can copy all dataset descriptions of their DMPs in this single DMP document. -

-
-

- How do I create an identical DMP or Dataset as a - copy? -

-

- DMPs and Datasets can be cloned and used in different research contexts. - Existing DMPs presenting similarities with new ones, can be cloned, changed name and - then edited according to the new project data requirements. - Existing Datasets can be cloned and used in new DMPs that are reusing data described - in their context. -

-
-

- What is the DMP version? How is it set? -

-

- Versioning in Argos is both an internal and an external process. That means that - versioning happens both in the Argos environment when editing the DMP, and outside - of Argos when a DMP output is published in Zenodo. At every stage of the DMP - lifecycle, users have the option of keeping versions of the DMPs they are editing. - In Argos, users can create new versions of their DMPs by selecting the “Start New - Version” option to keep track of the evolution of their DMP throughout the writing - process. When published, versioning is associated with a DOI. Published DMPs are - automatically versioned every time a newer version of the same output is uploaded in - Zenodo. -

-
-

- DMPs and Datasets -

-

- What is the DMP? -

-

- A DMP in Argos consists of vital information about the research project on behalf of - which the DMP is created and of more in depth information about the management, - handling and curation of datasets collected, produced or reused during the research - lifetime. A DMP in Argos accommodates documentation of more than one datasets. That - way datasets are provided with the flexibility to be described separately, following - different templates per type of dataset or research community concerned each time, - also possible to be copied and used in multiple DMPs. Datasets are then bundled up - in a DMP and can be shared more broadly. Special attention is given to the handling - of data that are being re-used via OpenAIRE APIs. -

-
-

- How do I find which Dataset template to use? -

-

- This depends on the reason why you are creating a DMP in the first place. If it is - for compliance matters with funders, institutions or research communities RDM - policies, then you may select the dataset template of that particular stakeholder. - If you are creating a DMP for training purposes, you may select and work on any - template from the Argos collection. -

-
-

- How do I create my own Dataset template? -

-

- Currently, it is not possible for all Argos users to create dataset templates of - their own, so they have to work on predefined templates. Additional rights for - editing Dataset templates according to tailored needs have Admin users. This is - expected to change in the near future. To learn more about Admin users, check “What - does an Admin user do?”. -

-
-

- Can I create smaller versions of a template for project proposals? -

-

- Yes, it is possible in Argos to create short versions of templates that can be used - for grant proposals, such as for Horizon Europe. - If you are interested in working with us to create this short version of any ARGOS template, - please contact us: argos@openaire.eu. -

-
-

- Can I customise an existing template (e.g. for a specific institution)? -

-

- Yes, you can. In the current version, this is possible for Admin users who have their own deployment on-premises or cloud. - Please note that this subject to change in the near future as we are working on a feature that will allow all users - to customise (remove/add/extend) specific questions on the template they are working on. -

-
-

- What is a Dataset? -

-

- A Dataset in Argos is an editor with set up questions that support the creation of - descriptions of how data are / have been handled, managed and curated throughout the - research data lifecycle. The editor holds a collection of Dataset templates each one - with different sets of predefined questions as per funders, institutions, research - communities RDM policy requirements. Researchers and students can choose the - template that corresponds to their RDM needs in order to get funding or get their - degree, respectively. A DMP in Argos may consist of one or more datasets. -

-
-

- Why do I need more than one Dataset? -

-

- You don’t necessarily need to have many Datasets in a DMP. However, you might be - producing a plethora of data during your research that are diverse in type and/ or - scope of collection/ re-use, thus presenting diverse management needs. Argos gives - you the flexibility to describe all data produced and/ or re-used in your research - separately. That way it is easy to perform the mapping of information provided in a - DMP to the respective data types or data collections they correspond to. Equally, - reuse of particular datasets in different DMPs is easier. For the latter, please - check “How do I create an identical DMP or Dataset as a copy?”. -

-
-

- It is not very clear to me when one should choose to add a dataset or to describe several "data products" in the same description. -

-

- This is something that has to be tackled conceptually, from the author of the DMP. - If those "products" have their own lifetime and rules (IPR, Access rights, etc), they should be described as different datasets. - Alternative formats should not be treated as different datasets, unless they have other differences due to the format, too. - But, for instance, if you have datasets in CSV and JSON formats and under the same terms, they could be seen as one dataset description in the DMP. -

-
-

- Can I add to my DMP information about datasets published on Zenodo? -

-

- Argos offers a search to Zenodo for prefilling the DMP you are working with dataset metadata. - This search has been developed according to the rules set by Zenodo - and therefore has the same behaviour as when you are using the search bar on the Zenodo interface. - However, we understand the need to be able to find records with their PID, - hence we introduced some changes and now support searching DOIs from the Argos interface. -

-
-

- Is it possible to describe a dataset that is not yet in a repository? -

-

- Of course! You can choose to manually describe your dataset, e.g. for a dataset you are planning to produce, - instead of pre-filling the template with available metadata from a dataset that has already been shared and preserved in a repository. -

-
-

- What are public DMPs and Datasets? -

-

- Public DMPs and Public Datasets are collections of openly available Argos outputs. - That means that DMP owners and members are making their DMP and/or Dataset outputs - available to all Argos and non-Argos users who might want to consult or re-use them - under the framework provided by the assigned DMP license. Please also check “Is all - the information I create visible by default?”. -

-
-

- Is all information I create visible by - default? -

-

- No, it is not. You can choose how your DMP is displayed in Argos from the - “Visibility” option. Choosing Public will immediately locate your DMP in the “Public - DMPs” collection and make it available to all Argos and non-Argos users. - Choosing Private will keep the DMP visible only to you and to the people invited to - edit the DMP in collaboration with you. Private DMPs are not publicly displayed to - other users. -

-
-

- What is the difference between the DMP and the dataset export? -

-

- DMP export contains all vital information for a DMP, including funding and dataset details, - while dataset export is a subset of the DMP export containing information only about a dataset described in the DMP. - Both DMP and Dataset exports are available in .pdf, .docx, .xml. - In addition, DMP export is available in the RDA .json format - to increase interoperability of ARGOS exchanged DMPs. -

-
-

- Is there a storage allowance limitation for the - DMPs and Dataset files? -

-

- No, there is no storage limit or fee for either files stored in Argos. -

-
-

- Publishing DMPs -

-

- Is it possible to publish DMPs in different repositories (so not Zenodo)? -

-

- Yes, it is possible. - But, to have different repositories attached to the system, you will need your own on-premises or cloud deployment. - We are already working on that for DSpace and Dataverse repositories. -

-
-

- Do you know that Zenodo has empty DMPs from ARGOS? -

-

- Yes, we are aware of that. - Argos has no control over the DMPs that you generate and publish and thus can not be held accountable for empty DMPs. - Please remember that, as on all other occasions where you publish content, you should do so responsinbly. - If you have any questions regarding publishing DMPs, don’t hesitate to contact us at argos@openaire.eu. -

-
-

- Once I upload a final version of a DMP to Zenodo, do I need to update this first final version from Zenodo or from Argos? -

-

- Both options are possible according to how you have deposited the DMP in the first place. - If you have deposited your DMP with a token (i.e. from the ARGOS account on Zenodo), - then you won’t have editing rights on the Zenodo record, but you will still be able to make changes - on ARGOS by starting and depositing a new version of the published DMP. - However, if you have deposited your DMP using your own account on Zenodo (i.e. login to Zenodo with your own credentials), - then you are able to also make minor changes, e.g. on the title of the DMP, directly from the Zenodo interface. -

-
-

Troubleshooting

-

- Can’t finalize a DMP -

-

- You might be experiencing this problem because there are incomplete mandatory fields - in your DMP. Please check for those fields, fill in with appropriate information and - try again. Should the problem persists, please contact argos@openaire.eu . -

-
-

- Can’t co-edit a DMP -

-

- DMPs can be shared with many colleagues in support of collaborative writing, but - DMPs should be worked by one person at a time. Argos will inform you if another - colleague has the DMP you are trying to edit open, so that your team avoids - information loss. -

-
-

- Deposit is not working -

-

- You need to have a Zenodo login to perform a deposit. Please sign up in Zenodo or - use the token option to publish your DMPs and get a DOI. -

-
-

Legal and privacy

-

- Is Argos open source? -

-

- Yes, it is. The OpenDMP software that Argos has deployed upon is open source code - available under Apache 2.0 license. You may find more information about the software - here. -

-
-

- Can I contribute to Argos development? -

-

- Of course! Please feel free to suggest new features and to actively contribute to - Argos development via pull requests in Gitea. -

-
-

- Is Argos GDPR compliant? -

-

- Argos takes all necessary steps in handling and protecting personal and sensitive - information. Please check the Argos Terms of Service and Privacy Policy. -

-
-

- Which is the Argos data policy? -

-

- Please find all information about Argos Terms of Service and Privacy, here. - Additionally, you may find Argos Cookies policy, here. -

-
-

- What is the work ownership of information - created in Argos? -

-

- Unless there are any contractual or institutional agreements stating ownership of - outputs produced in the context of a project/ collaboration, owners of Argos outputs - are DMP contributors, i.e. DMP owners and DMP members, who have been involved with - writing the DMP. -

-
-

- Which are the terms and policies of Argos? -

-

- Please find all information about Argos Terms of Service and Privacy, here. - Additionally, you may find Argos Cookies policy, here. -

- - -
+
-
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.scss b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.scss index 91beac1bf..f6c049328 100644 --- a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.scss +++ b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.scss @@ -7,6 +7,10 @@ img { width: 100%; } -.faq-component { - //margin-top: 80px; +.iframe { + width: 100%; + height: 65vh; + margin: 0px; + border: none; + max-width: 100%; } diff --git a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts index 179cbc410..80cce9640 100644 --- a/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts +++ b/dmp-frontend/src/app/ui/faq/faq-content/faq-content.component.ts @@ -1,17 +1,38 @@ import { Component, OnInit, Input } from '@angular/core'; +import { SafeResourceUrl, DomSanitizer } from '@angular/platform-browser'; +import { FaqService } from '@app/core/services/faq/faq.service'; +import { LanguageService } from '@app/core/services/language/language.service'; +import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { BaseComponent } from '@common/base/base.component'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-faq-content', templateUrl: './faq-content.component.html', styleUrls: ['./faq-content.component.scss'] }) -export class FaqContentComponent implements OnInit { +export class FaqContentComponent extends BaseComponent implements OnInit { @Input() isDialog: boolean; - constructor() { } + faqHTMLUrl: SafeResourceUrl; + sanitizedGuideUrl: any; + + constructor( + private faqService: FaqService, + private sanitizer: DomSanitizer, + private languageService: LanguageService, + private matomoService: MatomoService + ) { super(); } ngOnInit() { + this.matomoService.trackPageView('FAQ'); + this.faqService.getFaq(this.languageService.getCurrentLanguage()) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'text/html' }); + this.faqHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); + }); } } diff --git a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.html b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.html index 953bb8298..0d965191d 100644 --- a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.html +++ b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.html @@ -1,24 +1,5 @@ -
-
-
-

{{ 'GLOSSARY.TITLE' | translate}}

-
-
+
-
-

DMP

-

A DMP - short for Data Management Plan - is a document describing the processes that the data have undergone and the tools used for their handling and storage during a research lifecycle. Most importantly, DMPs secure provenance and enable re-use of data by appointing data managers and by including information on how data can be re-used by others in the future. Therefore, a DMP is a living document which is modified according to the data developments of a project before it’s completed and handed over at the end of the project. - Public funders increasingly contain DMPs in their grant proposals or policy funding requirements. A good paradigm is the European Commission demands for the production and delivery of DMPs for projects funded under the Horizon 2020 Funding Programme. On that note, and to encourage good data management practices uptake, many European institutions include DMPs in post-graduate researchers policies and offer relevant support to staff and students. -

- -

DMP template

-

DMP template contains general but vital information about the name and the duration of the project that the DMP corresponds to, the contributing organisations and individuals as well as the datasets that are under the Dataset Description section. It also offers the possibility of describing datasets other than primary data generated, under “External References” section. A DMP template can have many Dataset Descriptions. -

- -

Dataset Description

-

Dataset Description documents the management processes of datasets following funder’s or institution’s requirements. A dataset description is essentially a questionnaire template with underlying added value services for interoperability and machine readability of information which is developed based on the given requirements. Management requirements differ from funder to funder and from institution to institution, hence the growing collection of Dataset Descriptions to select from. - Moreover, a Dataset Description links to the documentation of one dataset, hence a DMP template may contain more than one dataset descriptions on the occasion when multiple datasets were used during the project. When documentation of some of the project’s datasets falls under additional requirements (e.g. projects receiving multiple grants from different sources), there is the possibility of describing datasets with more than one Dataset Description template. -

-
+
-
+
\ No newline at end of file diff --git a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.scss b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.scss index 2d066c10e..30a2f8b8b 100644 --- a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.scss +++ b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.scss @@ -8,6 +8,9 @@ img { width: 100%; } -.glossary-component { - //margin-top: 80px; +.iframe { + width: 100%; + height: calc(100vh - 80px); + margin: 0px; + border: none; } diff --git a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts index 83696d3e5..e4deba043 100644 --- a/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts +++ b/dmp-frontend/src/app/ui/glossary/glossary-content/glossary-content.component.ts @@ -1,23 +1,46 @@ -import { HttpClient } from '@angular/common/http'; import { Component, OnInit, Input } from '@angular/core'; +import { DomSanitizer, SafeResourceUrl } from '@angular/platform-browser'; +import { Router } from '@angular/router'; +import { GlossaryService } from '@app/core/services/glossary/glossary.service'; +import { LanguageService } from '@app/core/services/language/language.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; +import { BaseComponent } from '@common/base/base.component'; +import { LangChangeEvent, TranslateService } from '@ngx-translate/core'; +import { takeUntil } from 'rxjs/operators'; @Component({ selector: 'app-glossary-content', templateUrl: './glossary-content.component.html', styleUrls: ['./glossary-content.component.scss'] }) -export class GlossaryContentComponent implements OnInit { +export class GlossaryContentComponent extends BaseComponent implements OnInit { @Input() isDialog: boolean; + glossaryHTMLUrl: SafeResourceUrl; + sanitizedGuideUrl: any; + constructor( - private httpClient: HttpClient, - private matomoService: MatomoService - ) { } + private glossaryService: GlossaryService, + private sanitizer: DomSanitizer, + private languageService: LanguageService, + private matomoService: MatomoService, + private translate: TranslateService, + private router: Router + ) { super(); } ngOnInit() { this.matomoService.trackPageView('Glossary'); + this.translate.onLangChange.subscribe((event: LangChangeEvent) => { + this.router.navigate(['/reload'], { skipLocationChange: true }).then(() => this.router.navigate(['/glossary'])); + + }); + this.glossaryService.getGlossary(this.languageService.getCurrentLanguage()) + .pipe(takeUntil(this._destroyed)) + .subscribe(response => { + const blob = new Blob([response.body], { type: 'text/html' }); + this.glossaryHTMLUrl = this.sanitizer.bypassSecurityTrustResourceUrl((window.URL ? URL : webkitURL).createObjectURL(blob)); + }); } } diff --git a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss b/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss index d4e4c18ab..0eebb1bea 100644 --- a/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss +++ b/dmp-frontend/src/app/ui/grant/listing/criteria/grant-criteria.component.scss @@ -46,7 +46,7 @@ .filters-title { width: 90px; // color: #089dbb; - color: #23bcba; + color: var(--primary-color-2); background-color: white; padding: 0px 20px; margin-top: -10px; @@ -63,7 +63,7 @@ // } // ::ng-deep .mat-focused .mat-form-field-label { -// color: #00b29f !important; +// color: var(--primary-color-3) !important; // } // ::ng-deep.mat-form-field-underline { @@ -71,7 +71,7 @@ // } // ::ng-deep.mat-form-field-ripple { -// background-color: #00b29f !important; +// background-color: var(--primary-color-3) !important; // } ::ng-deep .mat-checkbox { @@ -88,7 +88,7 @@ .mat-accent .mat-pseudo-checkbox-indeterminate, .mat-pseudo-checkbox-checked, .mat-pseudo-checkbox-indeterminate { - background-color: #00b29f; + background-color: var(--primary-color-3); } ::ng-deep .mat-ripple-element { @@ -106,14 +106,14 @@ ::ng-deep .mat-radio-button.mat-accent.mat-radio-checked .mat-radio-outer-circle { border-color: #777777; - // border-color: #00b29f; + // border-color: var(--primary-color-3); } ::ng-deep .mat-radio-button.mat-accent .mat-radio-inner-circle { color: #777777; background-color: #777777; - // color: #00b29f; - // background-color: #00b29f; + // color: var(--primary-color-3); + // background-color: var(--primary-color-3); } .mat-radio-button.mat-accent .mat-radio-ripple .mat-ripple-element { diff --git a/dmp-frontend/src/app/ui/language/language-content/language.component.ts b/dmp-frontend/src/app/ui/language/language-content/language.component.ts index 9eff5109f..e27bf0258 100644 --- a/dmp-frontend/src/app/ui/language/language-content/language.component.ts +++ b/dmp-frontend/src/app/ui/language/language-content/language.component.ts @@ -5,8 +5,7 @@ import { LanguageService } from '@app/core/services/language/language.service'; import { UserService } from '@app/core/services/user/user.service'; import { takeUntil } from 'rxjs/operators'; import { BaseComponent } from '@common/base/base.component'; - -const availableLanguages: any[] = require('../../../../assets/resources/language.json'); +import { ConfigurationService } from '@app/core/services/configuration/configuration.service'; @Component({ selector: 'app-language', @@ -16,14 +15,18 @@ const availableLanguages: any[] = require('../../../../assets/resources/language export class LanguageComponent extends BaseComponent implements OnInit { @Output() languageChange: EventEmitter = new EventEmitter(); - languages = availableLanguages; + languages = []; constructor( private router: Router, private authentication: AuthService, private languageService: LanguageService, - private userService: UserService - ) { super(); } + private userService: UserService, + private configurationService:ConfigurationService + ) { + super(); + this.languages = this.configurationService.availableLanguages; + } ngOnInit() { this.languageChange.emit(this.getCurrentLanguage().value) diff --git a/dmp-frontend/src/app/ui/misc/breadcrumb/breadcrumb.component.scss b/dmp-frontend/src/app/ui/misc/breadcrumb/breadcrumb.component.scss index 543dc4cc3..b045dae51 100644 --- a/dmp-frontend/src/app/ui/misc/breadcrumb/breadcrumb.component.scss +++ b/dmp-frontend/src/app/ui/misc/breadcrumb/breadcrumb.component.scss @@ -44,7 +44,7 @@ } .active { - color: #00b29f; + color: var(--primary-color-3); } .icon { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-title/form-composite-title.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-title/form-composite-title.component.scss index b6469481f..356217a1e 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-title/form-composite-title.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-composite-title/form-composite-title.component.scss @@ -24,7 +24,7 @@ h6 { .more { text-decoration: underline; - color: #F7DD72; + color: var(--secondary-color); cursor: pointer; font-size: 1rem; font-weight: 400; diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.scss index 1f281e606..627591d48 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-field/form-field.component.scss @@ -38,15 +38,15 @@ min-width: 156px; height: 44px; color: #ffffff; - background: #129d99 0% 0% no-repeat padding-box; + background: var(--primary-color) 0% 0% no-repeat padding-box; box-shadow: 0px 3px 6px #1e202029; border-radius: 30px; } .attach-file-btn:hover { background-color: #ffffff; - border: 1px solid #129d99; - color: #129d99; + border: 1px solid var(--primary-color); + color: var(--primary-color); } .attach-file-btn.mat-button-disabled, .attach-file-btn.mat-button-disabled:hover { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.scss index 8c65d8bdd..7d7f80f08 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section-inner/form-section-inner.component.scss @@ -9,7 +9,7 @@ .addOneFieldButton { margin-top: -15px; margin-left: -11px; - color: #129d99; + color: var(--primary-color); } .panel-title, .panel-desc { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.scss index 606e1a5bb..cb676cf4c 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/components/form-section/form-section.component.scss @@ -9,7 +9,7 @@ .addOneFieldButton { margin-top: -15px; margin-left: -11px; - color: #129d99; + color: var(--primary-color); } .panel-title, .panel-desc { diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.component.scss index 57b066d5c..955e5fed6 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description-form.component.scss @@ -27,5 +27,5 @@ .mat-step-header .mat-step-icon-selected, .mat-step-header .mat-step-icon-state-done, .mat-step-header .mat-step-icon-state-edit { - background-color: #129d99 !important; + background-color: var(--primary-color) !important; } diff --git a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.scss b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.scss index b081e1ae7..3b8872d71 100644 --- a/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.scss +++ b/dmp-frontend/src/app/ui/misc/dataset-description-form/dataset-description.component.scss @@ -43,5 +43,5 @@ // ::ng-deep .mat-step-header .mat-step-icon-selected, // .mat-step-header .mat-step-icon-state-done, // .mat-step-header .mat-step-icon-state-edit { -// background-color: #129d99 !important; +// background-color: var(--primary-color) !important; // } 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 4fdfb42e4..91a5a18c9 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 @@ -44,6 +44,26 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit } ngOnInit() { + this.init(); + } + + ngOnChanges(changes: SimpleChanges) { + this.init(); + // When the form is changed set stepper index to 0. + // if (this.stepper && changes['form'] && !changes['form'].isFirstChange()) { + // this.stepper.selectedIndex = 0; + // } else if (this.stepper && changes['linkToScroll'] && changes['linkToScroll'].currentValue) { + // if (changes['linkToScroll'].currentValue.page >= 0) { + // this.stepper.selectedIndex = changes['linkToScroll'].currentValue.page; + // } + // } + } + + ngAfterViewInit() { + + } + + init() { this.tocentries = this.getTocEntries(); const rules_to_append = this._enrichWithMultiplicityRules(this.tocentries); @@ -64,33 +84,15 @@ export class DatasetDescriptionComponent extends BaseComponent implements OnInit this.hiddenEntriesIds = this._findHiddenEntries(this.tocentries); this.visibilityRulesService.visibilityChange - .pipe( - takeUntil(this._destroyed), - debounceTime(100) - ) - .subscribe(_=>{ - this.hiddenEntriesIds = this._findHiddenEntries(this.tocentries); - }) + .pipe( + takeUntil(this._destroyed), + debounceTime(100) + ) + .subscribe(_=>{ + this.hiddenEntriesIds = this._findHiddenEntries(this.tocentries); + }) } - ngOnChanges(changes: SimpleChanges) { - - // When the form is changed set stepper index to 0. - // if (this.stepper && changes['form'] && !changes['form'].isFirstChange()) { - // this.stepper.selectedIndex = 0; - // } else if (this.stepper && changes['linkToScroll'] && changes['linkToScroll'].currentValue) { - // if (changes['linkToScroll'].currentValue.page >= 0) { - // this.stepper.selectedIndex = changes['linkToScroll'].currentValue.page; - // } - // } - } - - ngAfterViewInit() { - - } - - - onAskedToScroll(panel: MatExpansionPanel, id?:string){ panel.open(); this.fieldsetFocusChange.emit(id); diff --git a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.scss b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.scss index 1f78b313e..a7b439673 100644 --- a/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.scss +++ b/dmp-frontend/src/app/ui/misc/navigation/user-dialog/user-dialog.component.scss @@ -50,7 +50,7 @@ $mat-card-header-size: 40px !default; } .check-icon { - color: #129D99; + color: var(--primary-color); transform: scale(0.7); } diff --git a/dmp-frontend/src/app/ui/navbar/navbar.component.html b/dmp-frontend/src/app/ui/navbar/navbar.component.html index d5f969740..0c9b6c9b9 100644 --- a/dmp-frontend/src/app/ui/navbar/navbar.component.html +++ b/dmp-frontend/src/app/ui/navbar/navbar.component.html @@ -1,13 +1,13 @@