From 403e618d04999d711ef5d70466dd35089a62a801 Mon Sep 17 00:00:00 2001 From: sgiannopoulos Date: Mon, 11 Mar 2024 15:01:56 +0200 Subject: [PATCH 01/12] deposit changes --- .../java/eu/eudat/audit/AuditableAction.java | 1 + .../eu/eudat/commons/enums/StorageType.java | 3 +- .../deposit/DepositProperties.java | 18 ++ .../transformer/TransformerProperties.java | 10 +- .../dmp/DmpCommonModelBuilder.java | 7 - .../eudat/model/file/ExportRequestModel.java | 9 + .../main/java/eu/eudat/query/UserQuery.java | 1 + .../service/deposit/DepositServiceImpl.java | 112 ++++++++--- .../java/eu/eudat/service/dmp/DmpService.java | 2 +- .../eu/eudat/service/dmp/DmpServiceImpl.java | 4 +- .../transformer/FileTransformerService.java | 175 +---------------- .../FileTransformerServiceImpl.java | 178 ++++++++++++++++++ .../eu/eudat/controllers/DmpController.java | 14 +- .../FileTransformerController.java | 2 +- .../web/src/main/resources/config/deposit.yml | 2 + .../main/resources/config/storage-devel.yml | 8 +- .../src/main/resources/config/transformer.yml | 3 + 17 files changed, 334 insertions(+), 215 deletions(-) create mode 100644 dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerServiceImpl.java diff --git a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java index c8ad61c07..b7e35ea99 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java +++ b/dmp-backend/core/src/main/java/eu/eudat/audit/AuditableAction.java @@ -40,6 +40,7 @@ public class AuditableAction { public static final EventId Dmp_Invite_Users = new EventId(5008, "Dmp_Invite_Users"); public static final EventId Dmp_Invite_Accept = new EventId(5009, "Dmp_Invite_Accept"); public static final EventId Dmp_PublicQuery = new EventId(5010, "Dmp_PublicQuery"); + public static final EventId Dmp_Export = new EventId(5011, "Dmp_Export"); public static final EventId Description_Query = new EventId(6000, "Description_Query"); public static final EventId Description_Lookup = new EventId(6001, "Description_Lookup"); diff --git a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/StorageType.java b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/StorageType.java index 3b72aff20..6525b5abe 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/commons/enums/StorageType.java +++ b/dmp-backend/core/src/main/java/eu/eudat/commons/enums/StorageType.java @@ -9,7 +9,8 @@ public enum StorageType implements DatabaseEnum { Temp((short) 0), Main((short) 1), - Transformer((short)2); + Transformer((short)2), + Deposit((short)3); private final Short value; diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java index 4ebcded6c..ea695791f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/deposit/DepositProperties.java @@ -26,6 +26,8 @@ public class DepositProperties { private String clientId; private String clientSecret; private String scope; + private String pdfTransformerId; + private String rdaTransformerId; public String getRepositoryId() { return repositoryId; @@ -74,5 +76,21 @@ public class DepositProperties { public void setScope(String scope) { this.scope = scope; } + + public String getPdfTransformerId() { + return pdfTransformerId; + } + + public void setPdfTransformerId(String pdfTransformerId) { + this.pdfTransformerId = pdfTransformerId; + } + + public String getRdaTransformerId() { + return rdaTransformerId; + } + + public void setRdaTransformerId(String rdaTransformerId) { + this.rdaTransformerId = rdaTransformerId; + } } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/configurations/transformer/TransformerProperties.java b/dmp-backend/core/src/main/java/eu/eudat/configurations/transformer/TransformerProperties.java index 7457f28a3..d2d0e9e33 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/configurations/transformer/TransformerProperties.java +++ b/dmp-backend/core/src/main/java/eu/eudat/configurations/transformer/TransformerProperties.java @@ -22,6 +22,7 @@ public class TransformerProperties { public static class TransformerSource { private final String url; + private final String transformerId; private final List codes; private final String issuerUrl; private final String clientId; @@ -29,9 +30,10 @@ public class TransformerProperties { private final String scope; @ConstructorBinding - public TransformerSource(String url, List codes, String issuerUrl, String clientId, String clientSecret, String scope) { + public TransformerSource(String url, String transformerId, List codes, String issuerUrl, String clientId, String clientSecret, String scope) { this.url = url; - this.codes = codes; + this.transformerId = transformerId; + this.codes = codes; this.issuerUrl = issuerUrl; this.clientId = clientId; this.clientSecret = clientSecret; @@ -61,5 +63,9 @@ public class TransformerProperties { public List getCodes() { return codes; } + + public String getTransformerId() { + return transformerId; + } } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/dmp/DmpCommonModelBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/dmp/DmpCommonModelBuilder.java index e1e4a0f3c..dc64e93ca 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/dmp/DmpCommonModelBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/commonmodels/dmp/DmpCommonModelBuilder.java @@ -49,7 +49,6 @@ public class DmpCommonModelBuilder extends BaseCommonModelBuilder authorize = EnumSet.of(AuthorizationFlags.None); @@ -79,11 +78,6 @@ public class DmpCommonModelBuilder extends BaseCommonModelBuilder (short)1) m.setPreviousDOI(this.getPreviousDOI(d.getGroupId(), d.getId())); switch (d.getAccessType()){ case Public -> m.setAccessType(DmpAccessType.Public); diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/file/ExportRequestModel.java b/dmp-backend/core/src/main/java/eu/eudat/model/file/ExportRequestModel.java index 6e782b6db..ab6dceca7 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/file/ExportRequestModel.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/file/ExportRequestModel.java @@ -5,6 +5,7 @@ import java.util.UUID; public class ExportRequestModel { private UUID id; + private String repositoryId; private String format; public UUID getId() { @@ -22,4 +23,12 @@ public class ExportRequestModel { public void setFormat(String format) { this.format = format; } + + public String getRepositoryId() { + return repositoryId; + } + + public void setRepositoryId(String repositoryId) { + this.repositoryId = repositoryId; + } } diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java index dee5c6a60..099a3ee5f 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java @@ -150,6 +150,7 @@ public class UserQuery extends QueryBase { if (this.authorize.contains(AuthorizationFlags.Permission) && this.authService.authorize(Permission.BrowseUser)) return null; UUID userId; if (this.authorize.contains(AuthorizationFlags.Owner)) userId = this.userScope.getUserIdSafe(); + if (this.authorize.contains(AuthorizationFlags.Public)) userId = this.userScope.getUserIdSafe(); else userId = null; List predicates = new ArrayList<>(); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java index 47e0382a7..d5e642620 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/deposit/DepositServiceImpl.java @@ -3,19 +3,34 @@ package eu.eudat.service.deposit; import eu.eudat.authorization.AuthorizationFlags; import eu.eudat.authorization.Permission; import eu.eudat.commonmodels.models.FileEnvelopeModel; +import eu.eudat.commonmodels.models.description.DescriptionModel; +import eu.eudat.commonmodels.models.description.FieldModel; +import eu.eudat.commonmodels.models.description.PropertyDefinitionFieldSetItemModel; +import eu.eudat.commonmodels.models.description.PropertyDefinitionFieldSetModel; import eu.eudat.commonmodels.models.dmp.DmpModel; +import eu.eudat.commons.enums.StorageType; +import eu.eudat.commons.scope.user.UserScope; import eu.eudat.configurations.deposit.DepositProperties; +import eu.eudat.convention.ConventionService; +import eu.eudat.data.DescriptionTemplateEntity; import eu.eudat.data.DmpEntity; import eu.eudat.depositinterface.repository.DepositClient; import eu.eudat.depositinterface.repository.DepositConfiguration; +import eu.eudat.model.DescriptionTemplate; import eu.eudat.model.EntityDoi; +import eu.eudat.model.StorageFile; import eu.eudat.model.builder.commonmodels.DepositConfigurationBuilder; import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; +import eu.eudat.model.persist.StorageFilePersist; import eu.eudat.model.persist.deposit.DepositAuthenticateRequest; import eu.eudat.model.persist.deposit.DepositRequest; import eu.eudat.model.persist.EntityDoiPersist; +import eu.eudat.query.DescriptionTemplateQuery; import eu.eudat.query.DmpQuery; import eu.eudat.service.entitydoi.EntityDoiService; +import eu.eudat.service.storage.StorageFileProperties; +import eu.eudat.service.storage.StorageFileService; +import eu.eudat.service.transformer.FileTransformerService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService; import gr.cite.commons.web.authz.service.AuthorizationService; import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; @@ -23,7 +38,10 @@ import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel; import gr.cite.tools.data.builder.BuilderFactory; import gr.cite.tools.data.query.QueryFactory; import gr.cite.tools.exception.MyNotFoundException; +import gr.cite.tools.fieldset.BaseFieldSet; import gr.cite.tools.fieldset.FieldSet; +import gr.cite.tools.validation.ValidatorFactory; +import org.apache.commons.io.FilenameUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -32,11 +50,12 @@ import org.springframework.context.i18n.LocaleContextHolder; import org.springframework.stereotype.Service; import org.springframework.web.reactive.function.client.WebClient; +import java.io.IOException; import java.net.URI; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; +import java.net.URLConnection; +import java.time.Duration; +import java.util.*; +import java.util.stream.Collectors; @Service public class DepositServiceImpl implements DepositService { @@ -52,7 +71,12 @@ public class DepositServiceImpl implements DepositService { private final MessageSource messageSource; private final BuilderFactory builderFactory; private final DepositConfigurationCacheService depositConfigurationCacheService; - + private final FileTransformerService fileTransformerService; + private final StorageFileService storageFileService; + private final UserScope userScope; + private final ValidatorFactory validatorFactory; + private final StorageFileProperties storageFileProperties; + private final ConventionService conventionService; @Autowired public DepositServiceImpl(DepositProperties depositProperties, TokenExchangeCacheService tokenExchangeCacheService, @@ -61,7 +85,7 @@ public class DepositServiceImpl implements DepositService { EntityDoiService doiService, QueryFactory queryFactory, MessageSource messageSource, - BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService) { + BuilderFactory builderFactory, DepositConfigurationCacheService depositConfigurationCacheService, FileTransformerService fileTransformerService, StorageFileService storageFileService, UserScope userScope, ValidatorFactory validatorFactory, StorageFileProperties storageFileProperties, ConventionService conventionService) { this.depositProperties = depositProperties; this.tokenExchangeCacheService = tokenExchangeCacheService; this.authorizationService = authorizationService; @@ -71,6 +95,12 @@ public class DepositServiceImpl implements DepositService { this.messageSource = messageSource; this.builderFactory = builderFactory; this.depositConfigurationCacheService = depositConfigurationCacheService; + this.fileTransformerService = fileTransformerService; + this.storageFileService = storageFileService; + this.userScope = userScope; + this.validatorFactory = validatorFactory; + this.storageFileProperties = storageFileProperties; + this.conventionService = conventionService; this.clients = new HashMap<>(); } @@ -130,29 +160,48 @@ public class DepositServiceImpl implements DepositService { //GK: Forth make the required files to be uploaded with the deposit //TODO: Properly create required files - FileEnvelopeModel docEnvelope = new FileEnvelopeModel(); + DepositProperties.DepositSource source = depositProperties.getSources().stream().filter(depositSource -> depositSource.getRepositoryId().equals(dmpDepositModel.getRepositoryId())).findFirst().orElse(null); + if (source == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{dmpDepositModel.getRepositoryId(), DepositProperties.DepositSource.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + eu.eudat.model.file.FileEnvelope pdfFile = this.fileTransformerService.exportDmp(dmpEntity.getId(), source.getPdfTransformerId(),"pdf"); + eu.eudat.model.file.FileEnvelope rda = this.fileTransformerService.exportDmp(dmpEntity.getId(), source.getRdaTransformerId(),"json"); + FileEnvelopeModel pdfEnvelope = new FileEnvelopeModel(); FileEnvelopeModel jsonEnvelope = new FileEnvelopeModel(); - FileEnvelopeModel zip = new FileEnvelopeModel(); - //TODO: Create Files -// File zip = new File(environment.getProperty("temp.temp") + UUID.randomUUID() + ".zip"); -// try { -// docEnvelope.setFilename("test.docx"); -// docEnvelope.setFile(this.storageFileService.getH2020TemplateFile()); -// File pdfFile = PDFUtils.convertToPDF(docEnvelope, environment); -// pdfEnvelope.setFilename("test.pdf"); -// pdfEnvelope.setFile(pdfFile); -// File jsonFile = new File(this.environment.getProperty("temp.temp") + UUID.randomUUID() + ".json"); -// jsonEnvelope.setFilename("test.json"); -// jsonEnvelope.setFile(jsonFile); -// -// } catch (IOException e) { -// logger.error(e.getMessage(), e); -// } - + + pdfEnvelope.setFilename(pdfFile.getFilename()); + jsonEnvelope.setFilename(rda.getFilename()); + if (!depositClient.getConfiguration().isUseSharedStorage()){ + pdfEnvelope.setFile(pdfFile.getFile()); + jsonEnvelope.setFile(rda.getFile()); + } else { + pdfEnvelope.setFileRef(this.addFileToSharedStorage(pdfFile)); + jsonEnvelope.setFileRef(this.addFileToSharedStorage(rda)); + } + //GK: Fifth Transform them to the DepositModel DmpModel depositModel = this.builderFactory.builder(DmpCommonModelBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic) - .setRepositoryId(dmpDepositModel.getRepositoryId()).setPdfFile(pdfEnvelope).setRdaJsonFile(jsonEnvelope).setSupportingFilesZip(zip).build(dmpEntity); + .setRepositoryId(dmpDepositModel.getRepositoryId()).setPdfFile(pdfEnvelope).setRdaJsonFile(jsonEnvelope).build(dmpEntity); + + //TODO +// if (depositModel != null && !this.conventionService.isListNullOrEmpty(depositModel.getDescriptions())){ +// for (DescriptionModel descriptionModel :depositModel.getDescriptions()){ +// DescriptionTemplateEntity descriptionTemplate = this.queryFactory.query(DescriptionTemplateQuery.class).ids(descriptionModel.getDescriptionTemplate().getId()).firstAs(new BaseFieldSet().ensure(DescriptionTemplate._definition)); +// if (descriptionTemplate == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{descriptionModel.getDescriptionTemplate().getId(), DescriptionTemplate.class.getSimpleName()}, LocaleContextHolder.getLocale())); +// +// if (descriptionModel.getProperties() != null && descriptionModel.getProperties().getFieldSets() != null){ +// for(PropertyDefinitionFieldSetItemModel propertyDefinitionFieldSetItemModel : descriptionModel.getProperties().getFieldSets().values().stream().filter(x-> x.getItems() != null).map(PropertyDefinitionFieldSetModel::getItems).flatMap(Collection::stream).toList()){ +// if (propertyDefinitionFieldSetItemModel.getFields() != null){ +// for(Map.Entry entrySet : propertyDefinitionFieldSetItemModel.getFields().entrySet()){ +// +// } +// } +// } +// } +// +// } +// +// } //GK: Sixth Perform the deposit String doi = depositClient.deposit(depositModel, dmpDepositModel.getAccessToken()); @@ -165,6 +214,19 @@ public class DepositServiceImpl implements DepositService { doiPersist.setEntityId(dmpEntity.getId()); return doiService.persist(doiPersist, dmpDepositModel.getProject()); } + + private String addFileToSharedStorage(eu.eudat.model.file.FileEnvelope file) throws IOException { + StorageFilePersist storageFilePersist = new StorageFilePersist(); + storageFilePersist.setName(FilenameUtils.removeExtension(file.getFilename())); + storageFilePersist.setExtension(FilenameUtils.getExtension(file.getFilename())); + storageFilePersist.setMimeType(URLConnection.guessContentTypeFromName(file.getFilename())); + storageFilePersist.setOwnerId(this.userScope.getUserIdSafe()); + storageFilePersist.setStorageType(StorageType.Temp); + storageFilePersist.setLifetime(Duration.ofSeconds(this.storageFileProperties.getTempStoreLifetimeSeconds())); //TODO + this.validatorFactory.validator(StorageFilePersist.StorageFilePersistValidator.class).validateForce(storageFilePersist); + StorageFile persisted = this.storageFileService.persistBytes(storageFilePersist, file.getFile(), new BaseFieldSet(StorageFile._id, StorageFile._fileRef)); + return persisted.getFileRef(); + } @Override public String getLogo(String repositoryId) { diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java index 1e9f8df1f..76e92b64b 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpService.java @@ -34,7 +34,7 @@ public interface DmpService { List assignUsers(UUID dmp, List model, FieldSet fields) throws InvalidApplicationException, IOException; Dmp removeUser(DmpUserRemovePersist model, FieldSet fields) throws InvalidApplicationException, IOException; - ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException; + ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException; void inviteUsers(UUID id, List users) throws InvalidApplicationException, JAXBException, IOException; diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java index 63a9f01bc..687dbb00c 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/dmp/DmpServiceImpl.java @@ -518,10 +518,10 @@ public class DmpServiceImpl implements DmpService { } @Override - public ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException { + public ResponseEntity export(UUID id, String transformerId, String exportType) throws InvalidApplicationException, IOException { HttpHeaders headers = new HttpHeaders(); - FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(id, exportType); + FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(id, transformerId, exportType); headers.add("Content-Disposition", "attachment;filename=" + fileEnvelope.getFilename()); byte[] data = fileEnvelope.getFile(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerService.java b/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerService.java index 265d53c9c..674259823 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerService.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerService.java @@ -1,177 +1,14 @@ package eu.eudat.service.transformer; -import eu.eudat.authorization.AuthorizationFlags; -import eu.eudat.authorization.Permission; -import eu.eudat.cache.transformer.FileTransformerConfigurationCache; -import eu.eudat.commonmodels.models.FileEnvelopeModel; -import eu.eudat.commonmodels.models.description.DescriptionModel; -import eu.eudat.commonmodels.models.dmp.DmpModel; -import eu.eudat.commons.enums.StorageType; -import eu.eudat.configurations.transformer.TransformerProperties; -import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration; import eu.eudat.file.transformer.models.misc.FileFormat; -import eu.eudat.model.Description; -import eu.eudat.model.Dmp; -import eu.eudat.model.builder.commonmodels.description.DescriptionCommonModelBuilder; -import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; -import eu.eudat.model.file.TransformerCacheModel; -import eu.eudat.query.DescriptionQuery; -import eu.eudat.query.DmpQuery; -import eu.eudat.repository.TransformerRepository; -import eu.eudat.service.storage.StorageFileService; -import gr.cite.commons.web.authz.service.AuthorizationService; -import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService; -import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; -import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel; -import gr.cite.tools.data.builder.BuilderFactory; -import gr.cite.tools.data.query.QueryFactory; -import gr.cite.tools.exception.MyNotFoundException; -import org.slf4j.Logger; -import org.slf4j.LoggerFactory; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.context.MessageSource; -import org.springframework.context.i18n.LocaleContextHolder; -import org.springframework.stereotype.Service; -import org.springframework.web.reactive.function.client.ExchangeFilterFunction; -import org.springframework.web.reactive.function.client.WebClient; -import reactor.core.publisher.Mono; -import javax.management.InvalidApplicationException; -import java.io.IOException; -import java.net.URI; -import java.util.*; +import java.util.List; +import java.util.UUID; -@Service -public class FileTransformerService { - private static final Logger logger = LoggerFactory.getLogger(FileTransformerService.class); +public interface FileTransformerService { + List getAvailableExportFileFormats(); - private final TransformerProperties transformerProperties; - private final Map clients; - private final TokenExchangeCacheService tokenExchangeCacheService; - private final FileTransformerConfigurationCache fileTransformerConfigurationCache; - private final AuthorizationService authorizationService; - private final WebClient.Builder webClientBuilder; - private final QueryFactory queryFactory; - private final BuilderFactory builderFactory; - private final StorageFileService storageFileService; - private final MessageSource messageSource; + eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format); - @Autowired - public FileTransformerService(TransformerProperties transformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCache fileTransformerConfigurationCache, WebClient.Builder builder, AuthorizationService authorizationService, - QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource) { - this.transformerProperties = transformerProperties; - this.tokenExchangeCacheService = tokenExchangeCacheService; - this.fileTransformerConfigurationCache = fileTransformerConfigurationCache; - this.authorizationService = authorizationService; - this.webClientBuilder = builder; - this.queryFactory = queryFactory; - this.builderFactory = builderFactory; - this.storageFileService = storageFileService; - this.messageSource = messageSource; - this.clients = new HashMap<>(); - } - - private TransformerRepository getRepository(String repoId) { - if (this.clients.containsKey(repoId)) return this.clients.get(repoId); - - //GK: It's register time - TransformerProperties.TransformerSource source = transformerProperties.getSources().stream().filter(depositSource -> depositSource.getCodes().contains(repoId)).findFirst().orElse(null); - if (source != null) { - String host = URI.create(source.getUrl()).getHost(); - TokenExchangeModel tokenExchangeModel = new TokenExchangeModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); - TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); - TransformerRepository repository = new TransformerRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> { - exchangeFilterFunctions.add(tokenExchangeFilterFunction); - exchangeFilterFunctions.add(logRequest()); - }).build()); - source.getCodes().forEach(code -> this.clients.put(code, repository)); - return repository; - } - return null; - } - - - public List getAvailableExportFileFormats() { - List formats = new ArrayList<>(); - List configurations = this.getAvailableConfigurations(); - if(configurations != null){ - for (FileTransformerConfiguration configuration : configurations){ - if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants()); - } - } - return formats; - } - - private List getAvailableConfigurations() { - TransformerCacheModel configs = fileTransformerConfigurationCache.lookup("base"); - if (configs == null) { - List configurations = new ArrayList<>(); - //GK: So much for lazy loading - List repositories = transformerProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getCodes().getFirst())).toList(); - - repositories = new ArrayList<>(repositories); - repositories.forEach((client) -> { - try { - FileTransformerConfiguration repositoryConfig = client.getConfiguration(); - if (repositoryConfig != null) { - configurations.add(repositoryConfig); - } - } catch (Exception e) { - logger.warn(e.getLocalizedMessage(), e); - } - }); - - configs = new TransformerCacheModel(configurations); - this.fileTransformerConfigurationCache.put("base", configs); - } - - return configs.getConfigurations(); - } - - public eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String format) throws InvalidApplicationException, IOException { - this.authorizationService.authorize(Permission.EditDmp); - //GK: First get the right client - TransformerRepository repository = getRepository(format); - if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{format, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale())); - //GK: Second get the Target Data Management Plan - DmpQuery query = this.queryFactory.query(DmpQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(dmpId); - DmpModel dmpFileTransformerModel = this.builderFactory.builder(DmpCommonModelBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(query.first()); - if (dmpFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{dmpId, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); - - FileEnvelopeModel fileEnvelope = repository.exportDmp(dmpFileTransformerModel, format); - eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope(); - - byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile(); - result.setFile(data); - result.setFilename(fileEnvelope.getFilename()); - return result; - } - - public eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String format) { - this.authorizationService.authorize(Permission.EditDmp); - //GK: First get the right client - TransformerRepository repository = getRepository(format); - if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{format, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale())); - - //GK: Second get the Target Data Management Plan - DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(descriptionId); - DescriptionModel descriptionFileTransformerModel = this.builderFactory.builder(DescriptionCommonModelBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(query.first()); - if (descriptionFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{descriptionId, Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); - - FileEnvelopeModel fileEnvelope = repository.exportDescription(descriptionFileTransformerModel, format); - eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope(); - byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile(); //TODO: shared storage should be per repository - result.setFile(data); - result.setFilename(fileEnvelope.getFilename()); - return result; - } - - // This method returns filter function which will log request data - private static ExchangeFilterFunction logRequest() { - return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { - logger.info("Request: {} {}", clientRequest.method(), clientRequest.url()); - clientRequest.headers().forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); - return Mono.just(clientRequest); - }); - } + eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String format); } diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerServiceImpl.java new file mode 100644 index 000000000..c3a469e2c --- /dev/null +++ b/dmp-backend/core/src/main/java/eu/eudat/service/transformer/FileTransformerServiceImpl.java @@ -0,0 +1,178 @@ +package eu.eudat.service.transformer; + +import eu.eudat.authorization.AuthorizationFlags; +import eu.eudat.authorization.Permission; +import eu.eudat.cache.transformer.FileTransformerConfigurationCache; +import eu.eudat.commonmodels.models.FileEnvelopeModel; +import eu.eudat.commonmodels.models.description.DescriptionModel; +import eu.eudat.commonmodels.models.dmp.DmpModel; +import eu.eudat.commons.enums.StorageType; +import eu.eudat.configurations.transformer.TransformerProperties; +import eu.eudat.file.transformer.interfaces.FileTransformerConfiguration; +import eu.eudat.file.transformer.models.misc.FileFormat; +import eu.eudat.model.Description; +import eu.eudat.model.Dmp; +import eu.eudat.model.builder.commonmodels.description.DescriptionCommonModelBuilder; +import eu.eudat.model.builder.commonmodels.dmp.DmpCommonModelBuilder; +import eu.eudat.model.file.TransformerCacheModel; +import eu.eudat.query.DescriptionQuery; +import eu.eudat.query.DmpQuery; +import eu.eudat.repository.TransformerRepository; +import eu.eudat.service.storage.StorageFileService; +import gr.cite.commons.web.authz.service.AuthorizationService; +import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeCacheService; +import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeFilterFunction; +import gr.cite.commons.web.oidc.filter.webflux.TokenExchangeModel; +import gr.cite.tools.data.builder.BuilderFactory; +import gr.cite.tools.data.query.QueryFactory; +import gr.cite.tools.exception.MyNotFoundException; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.context.MessageSource; +import org.springframework.context.i18n.LocaleContextHolder; +import org.springframework.stereotype.Service; +import org.springframework.web.reactive.function.client.ExchangeFilterFunction; +import org.springframework.web.reactive.function.client.WebClient; +import reactor.core.publisher.Mono; + +import java.net.URI; +import java.util.*; + +@Service +public class FileTransformerServiceImpl implements FileTransformerService { + private static final Logger logger = LoggerFactory.getLogger(FileTransformerServiceImpl.class); + + private final TransformerProperties transformerProperties; + private final Map clients; + private final TokenExchangeCacheService tokenExchangeCacheService; + private final FileTransformerConfigurationCache fileTransformerConfigurationCache; + private final AuthorizationService authorizationService; + private final WebClient.Builder webClientBuilder; + private final QueryFactory queryFactory; + private final BuilderFactory builderFactory; + private final StorageFileService storageFileService; + private final MessageSource messageSource; + + @Autowired + public FileTransformerServiceImpl(TransformerProperties transformerProperties, TokenExchangeCacheService tokenExchangeCacheService, FileTransformerConfigurationCache fileTransformerConfigurationCache, WebClient.Builder builder, AuthorizationService authorizationService, + QueryFactory queryFactory, BuilderFactory builderFactory, StorageFileService storageFileService, MessageSource messageSource) { + this.transformerProperties = transformerProperties; + this.tokenExchangeCacheService = tokenExchangeCacheService; + this.fileTransformerConfigurationCache = fileTransformerConfigurationCache; + this.authorizationService = authorizationService; + this.webClientBuilder = builder; + this.queryFactory = queryFactory; + this.builderFactory = builderFactory; + this.storageFileService = storageFileService; + this.messageSource = messageSource; + this.clients = new HashMap<>(); + } + + private TransformerRepository getRepository(String repoId) { + if (this.clients.containsKey(repoId)) return this.clients.get(repoId); + + //GK: It's register time + TransformerProperties.TransformerSource source = transformerProperties.getSources().stream().filter(depositSource -> depositSource.getCodes().contains(repoId)).findFirst().orElse(null); + if (source != null) { + String host = URI.create(source.getUrl()).getHost(); + TokenExchangeModel tokenExchangeModel = new TokenExchangeModel(host + "_" + source.getClientId(), source.getIssuerUrl(), source.getClientId(), source.getClientSecret(), source.getScope()); + TokenExchangeFilterFunction tokenExchangeFilterFunction = new TokenExchangeFilterFunction(this.tokenExchangeCacheService, tokenExchangeModel); + TransformerRepository repository = new TransformerRepository(webClientBuilder.baseUrl(source.getUrl() + "/api/file-transformer").filters(exchangeFilterFunctions -> { + exchangeFilterFunctions.add(tokenExchangeFilterFunction); + exchangeFilterFunctions.add(logRequest()); + }).build()); + source.getCodes().forEach(code -> this.clients.put(code, repository)); + return repository; + } + return null; + } + + + @Override + public List getAvailableExportFileFormats() { + List formats = new ArrayList<>(); + List configurations = this.getAvailableConfigurations(); + if(configurations != null){ + for (FileTransformerConfiguration configuration : configurations){ + if (configuration != null && configuration.getExportVariants() != null) formats.addAll(configuration.getExportVariants()); + } + } + return formats; + } + + private List getAvailableConfigurations() { + TransformerCacheModel configs = fileTransformerConfigurationCache.lookup("base"); + if (configs == null) { + List configurations = new ArrayList<>(); + //GK: So much for lazy loading + List repositories = transformerProperties.getSources().stream().map(depositSource -> getRepository(depositSource.getCodes().getFirst())).toList(); + + repositories = new ArrayList<>(repositories); + repositories.forEach((client) -> { + try { + FileTransformerConfiguration repositoryConfig = client.getConfiguration(); + if (repositoryConfig != null) { + configurations.add(repositoryConfig); + } + } catch (Exception e) { + logger.warn(e.getLocalizedMessage(), e); + } + }); + + configs = new TransformerCacheModel(configurations); + this.fileTransformerConfigurationCache.put("base", configs); + } + + return configs.getConfigurations(); + } + + @Override + public eu.eudat.model.file.FileEnvelope exportDmp(UUID dmpId, String repositoryId, String format) { + this.authorizationService.authorize(Permission.EditDmp); + //GK: First get the right client + TransformerRepository repository = getRepository(repositoryId); + if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{repositoryId, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale())); + //GK: Second get the Target Data Management Plan + DmpQuery query = this.queryFactory.query(DmpQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(dmpId); + DmpModel dmpFileTransformerModel = this.builderFactory.builder(DmpCommonModelBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(query.first()); + if (dmpFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{dmpId, Dmp.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + FileEnvelopeModel fileEnvelope = repository.exportDmp(dmpFileTransformerModel, format); + eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope(); + + byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile(); + result.setFile(data); + result.setFilename(fileEnvelope.getFilename()); + return result; + } + + @Override + public eu.eudat.model.file.FileEnvelope exportDescription(UUID descriptionId, String format) { + this.authorizationService.authorize(Permission.EditDmp); + //GK: First get the right client + TransformerRepository repository = getRepository(format); + if (repository == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{format, TransformerRepository.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + //GK: Second get the Target Data Management Plan + DescriptionQuery query = this.queryFactory.query(DescriptionQuery.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).ids(descriptionId); + DescriptionModel descriptionFileTransformerModel = this.builderFactory.builder(DescriptionCommonModelBuilder.class).authorize(AuthorizationFlags.OwnerOrDmpAssociatedOrPermissionOrPublic).build(query.first()); + if (descriptionFileTransformerModel == null) throw new MyNotFoundException(messageSource.getMessage("General_ItemNotFound", new Object[]{descriptionId, Description.class.getSimpleName()}, LocaleContextHolder.getLocale())); + + FileEnvelopeModel fileEnvelope = repository.exportDescription(descriptionFileTransformerModel, format); + eu.eudat.model.file.FileEnvelope result = new eu.eudat.model.file.FileEnvelope(); + byte[] data = repository.getConfiguration().isUseSharedStorage() ? storageFileService.readByFileRefAsBytesSafe(fileEnvelope.getFileRef(), StorageType.Transformer) : fileEnvelope.getFile(); //TODO: shared storage should be per repository + result.setFile(data); + result.setFilename(fileEnvelope.getFilename()); + return result; + } + + // This method returns filter function which will log request data + private static ExchangeFilterFunction logRequest() { + return ExchangeFilterFunction.ofRequestProcessor(clientRequest -> { + logger.info("Request: {} {}", clientRequest.method(), clientRequest.url()); + clientRequest.headers().forEach((name, values) -> values.forEach(value -> logger.info("{}={}", name, value))); + return Mono.just(clientRequest); + }); + } +} diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java index c3e2ad149..5781a0f68 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/DmpController.java @@ -215,11 +215,17 @@ public class DmpController { return new QueryResult<>(persisted); } - @GetMapping("{id}/export/{type}") - public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { - logger.debug(new MapLogEntry("exporting dmp")); + @GetMapping("{id}/export/{transformerId}/{type}") + public ResponseEntity export(@PathVariable("id") UUID id, @PathVariable("transformerId") String transformerId, @PathVariable("type") String exportType) throws InvalidApplicationException, IOException { + logger.debug(new MapLogEntry("exporting dmp").And("id", id).And("transformerId", transformerId).And("exportType", exportType)); - return this.dmpService.export(id, exportType); + ResponseEntity bytes = this.dmpService.export(id, transformerId, exportType); + this.auditService.track(AuditableAction.Dmp_Export, Map.ofEntries( + new AbstractMap.SimpleEntry("id", id), + new AbstractMap.SimpleEntry("transformerId", transformerId), + new AbstractMap.SimpleEntry("exportType", exportType) + )); + return bytes; } @PostMapping("{id}/invite-users") diff --git a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java index a520eb020..a06b1642b 100644 --- a/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java +++ b/dmp-backend/web/src/main/java/eu/eudat/controllers/FileTransformerController.java @@ -52,7 +52,7 @@ public class FileTransformerController { logger.debug(new MapLogEntry("exporting dmp")); HttpHeaders headers = new HttpHeaders(); - FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(requestModel.getId(), requestModel.getFormat()); + FileEnvelope fileEnvelope = this.fileTransformerService.exportDmp(requestModel.getId(), requestModel.getRepositoryId(), requestModel.getFormat()); headers.add("Content-Disposition", "attachment;filename=" + fileEnvelope.getFilename()); byte[] data = fileEnvelope.getFile(); headers.setContentType(MediaType.APPLICATION_OCTET_STREAM); diff --git a/dmp-backend/web/src/main/resources/config/deposit.yml b/dmp-backend/web/src/main/resources/config/deposit.yml index ea22fd026..84b70f957 100644 --- a/dmp-backend/web/src/main/resources/config/deposit.yml +++ b/dmp-backend/web/src/main/resources/config/deposit.yml @@ -2,6 +2,8 @@ deposit: sources: - url: http://localhost:8082 repositoryId: zenodo + pdfTransformerId: docx-file-transformer + rdaTransformerId: rda-file-transformer issuer-url: ${ZENODO_ISSUER_URI:IDP_APIKEY_ISSUER_URI}/protocol/openid-connect/token client-id: ${ZENODO_DEPOSIT_CLIENT_ID:} client-secret: ${ZENODO_DEPOSIT_CLIENT_SECRET:} diff --git a/dmp-backend/web/src/main/resources/config/storage-devel.yml b/dmp-backend/web/src/main/resources/config/storage-devel.yml index 5bd3e9916..3731cc12c 100644 --- a/dmp-backend/web/src/main/resources/config/storage-devel.yml +++ b/dmp-backend/web/src/main/resources/config/storage-devel.yml @@ -3,11 +3,13 @@ storage: defaultLanguage: en storages: - type: Temp - basePath: ./storage/temp + basePath: ${FILE_STORAGE}/temp - type: Main - basePath: ./storage/main + basePath: ${FILE_STORAGE}/main - type: Transformer - basePath: ${TRANSFORMER_BASE_PATH} + basePath: ${FILE_STORAGE}/transformer + - type: Deposit + basePath: ${FILE_STORAGE}/deposit static-files: externalUrls: dmp-backend/web/src/main/resources/externalUrls/ExternalUrls.xml semantics: dmp-backend/web/src/main/resources/Semantics.json diff --git a/dmp-backend/web/src/main/resources/config/transformer.yml b/dmp-backend/web/src/main/resources/config/transformer.yml index b8df6d50d..7cb90d96a 100644 --- a/dmp-backend/web/src/main/resources/config/transformer.yml +++ b/dmp-backend/web/src/main/resources/config/transformer.yml @@ -1,18 +1,21 @@ transformer: sources: - url: http://localhost:8084 + transformerId: docx-file-transformer codes: [ docx, pdf ] issuer-url: ${IDP_ISSUER_URI_TOKEN:} client-id: ${IDP_APIKEY_CLIENT_ID:} client-secret: ${IDP_APIKEY_CLIENT_SECRET:} scope: ${IDP_APIKEY_SCOPE:} - url: http://localhost:8086 + transformerId: rda-file-transformer codes: [ json ] issuer-url: ${IDP_ISSUER_URI_TOKEN:} client-id: ${IDP_APIKEY_CLIENT_ID:} client-secret: ${IDP_APIKEY_CLIENT_SECRET:} scope: ${IDP_APIKEY_SCOPE:} - url: http://localhost:8087 + transformerId: import-export-file-transformer codes: [ xml ] issuer-url: ${IDP_ISSUER_URI_TOKEN:} client-id: ${IDP_APIKEY_CLIENT_ID:} From 06e6ee406b6ea878be3f7ba1c5f6261b7759f3aa Mon Sep 17 00:00:00 2001 From: amentis Date: Mon, 11 Mar 2024 15:20:09 +0200 Subject: [PATCH 02/12] fixes --- .../java/eu/eudat/authorization/Permission.java | 2 +- .../src/main/java/eu/eudat/model/PublicDmp.java | 10 +++++----- .../eudat/model/builder/PublicDmpBuilder.java | 2 +- .../src/main/java/eu/eudat/query/UserQuery.java | 5 ++++- .../DescriptionTemplateServiceImpl.java | 6 +++--- .../web/src/main/resources/config/security.yml | 2 +- dmp-frontend/src/app/core/model/dmp/dmp.ts | 2 +- .../services/description/description.service.ts | 17 +++++++++++++---- .../src/app/core/services/dmp/dmp.service.ts | 16 +++++++++++++--- .../services/reference/reference.service.ts | 2 +- ...mplate-editor-composite-field.component.html | 8 ++------ ...ription-template-editor-field.component.html | 10 +++------- .../description-template-editor.component.ts | 2 +- .../editor/description-template-editor.model.ts | 3 ++- .../description-template-editor.resolver.ts | 1 + .../editor/dmp-blueprint-editor.component.ts | 2 +- .../editor/description-editor.resolver.ts | 2 ++ .../form-field/form-field.component.html | 2 +- .../listing/description-listing.component.ts | 1 + .../overview/description-overview.component.ts | 1 + .../dmp-editor.component.ts | 7 ++++--- .../app/ui/dmp/listing/dmp-listing.component.ts | 1 + .../ui/dmp/overview/dmp-overview.component.ts | 1 + dmp-frontend/src/assets/i18n/en.json | 4 ++++ 24 files changed, 68 insertions(+), 41 deletions(-) diff --git a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java index 322326452..02bd52676 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java +++ b/dmp-backend/core/src/main/java/eu/eudat/authorization/Permission.java @@ -15,7 +15,7 @@ public final class Permission { //Public public static String PublicBrowseDescription = "PublicBrowseDescription"; - public static String PublicBrowseDescriptionTemplate = "BrowseDescriptionTemplate"; + public static String PublicBrowseDescriptionTemplate = "PublicBrowseDescriptionTemplate"; public static String PublicBrowseDmp = "PublicBrowseDmp"; public static String PublicBrowseDmpReference = "PublicBrowseDmpReference"; public static String PublicBrowseDmpUser = "PublicBrowseDmpUser"; diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java index a23903658..a0ceb5135 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/PublicDmp.java @@ -37,7 +37,7 @@ public class PublicDmp { public static final String _publishedAt = "publishedAt"; - private List users; + private List dmpUsers; public static final String _dmpUsers = "dmpUsers"; @@ -104,12 +104,12 @@ public class PublicDmp { this.publishedAt = publishedAt; } - public List getUsers() { - return users; + public List getDmpUsers() { + return dmpUsers; } - public void setUsers(List users) { - this.users = users; + public void setDmpUsers(List dmpUsers) { + this.dmpUsers = dmpUsers; } public List getDmpReferences() { diff --git a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java index b07921a91..7017394c2 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java +++ b/dmp-backend/core/src/main/java/eu/eudat/model/builder/PublicDmpBuilder.java @@ -76,7 +76,7 @@ public class PublicDmpBuilder extends BaseBuilder { if (fields.hasField(this.asIndexer(PublicDmp._updatedAt))) m.setUpdatedAt(d.getUpdatedAt()); if (dmpReferenceMap != null && !dmpReferenceMap.isEmpty() && dmpReferenceMap.containsKey(d.getId())) m.setDmpReferences(dmpReferenceMap.get(d.getId())); - if (dmpUsersMap != null && !dmpUsersMap.isEmpty() && dmpUsersMap.containsKey(d.getId())) m.setUsers(dmpUsersMap.get(d.getId())); + if (dmpUsersMap != null && !dmpUsersMap.isEmpty() && dmpUsersMap.containsKey(d.getId())) m.setDmpUsers(dmpUsersMap.get(d.getId())); if (descriptionsMap != null && !descriptionsMap.isEmpty() && descriptionsMap.containsKey(d.getId())) m.setDescriptions(descriptionsMap.get(d.getId())); models.add(m); diff --git a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java index 4bd7d7c95..dc9d107b6 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java +++ b/dmp-backend/core/src/main/java/eu/eudat/query/UserQuery.java @@ -154,7 +154,10 @@ public class UserQuery extends QueryBase { else userId = null; List predicates = new ArrayList<>(); - if (userId != null) { + boolean usePublic = this.authorize.contains(AuthorizationFlags.Public); + if (usePublic){ + predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._isActive)).value(IsActive.Active)); + }else if (userId != null) { predicates.add(queryContext.CriteriaBuilder.in(queryContext.Root.get(UserEntity._id)).value(userId)); } if (!predicates.isEmpty()) { diff --git a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java index f2c4b6cef..e4b6a4675 100644 --- a/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java +++ b/dmp-backend/core/src/main/java/eu/eudat/service/descriptiontemplate/DescriptionTemplateServiceImpl.java @@ -202,7 +202,7 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic this.entityManager.persist(data); this.persistUsers(data.getId(), model.getUsers()); - if (!isUpdate) + if (this.conventionService.isListNullOrEmpty(model.getUsers())) this.addOwner(data); this.entityManager.flush(); @@ -260,9 +260,9 @@ public class DescriptionTemplateServiceImpl implements DescriptionTemplateServic this.sendDescriptionTemplateInvitationEvent(data, NotificationContactType.EMAIL); this.sendDescriptionTemplateInvitationEvent(data, NotificationContactType.IN_APP); } - updatedCreatedIds.add(data.getId()); + updatedCreatedIds.add(data.getUserId()); } - List toDelete = items.stream().filter(x -> updatedCreatedIds.stream().noneMatch(y -> y.equals(x.getId()))).collect(Collectors.toList()); + List toDelete = items.stream().filter(x -> updatedCreatedIds.stream().noneMatch(y -> y.equals(x.getUserId()))).collect(Collectors.toList()); this.deleterFactory.deleter(UserDescriptionTemplateDeleter.class).delete(toDelete); } diff --git a/dmp-backend/web/src/main/resources/config/security.yml b/dmp-backend/web/src/main/resources/config/security.yml index 2494d97ef..2c7e3f241 100644 --- a/dmp-backend/web/src/main/resources/config/security.yml +++ b/dmp-backend/web/src/main/resources/config/security.yml @@ -2,7 +2,7 @@ web: security: enabled: true authorized-endpoints: [ api ] - allowed-endpoints: [ api/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public ] + allowed-endpoints: [ api/public, api/dmp/public, api/description/public, /api/supportive-material/public, api/language/public, api/contact-support/public, api/dashboard/public ] idp: api-key: enabled: false diff --git a/dmp-frontend/src/app/core/model/dmp/dmp.ts b/dmp-frontend/src/app/core/model/dmp/dmp.ts index b5cc56b86..4fdeb4c00 100644 --- a/dmp-frontend/src/app/core/model/dmp/dmp.ts +++ b/dmp-frontend/src/app/core/model/dmp/dmp.ts @@ -158,7 +158,7 @@ export interface PublicDmp extends BaseEntity { finalizedAt?: Date; publishedAt?: Date; dmpReferences: PublicDmpReference[]; - users: PublicDmpUser[]; + dmpUsers: PublicDmpUser[]; descriptions: PublicDescription[]; } diff --git a/dmp-frontend/src/app/core/services/description/description.service.ts b/dmp-frontend/src/app/core/services/description/description.service.ts index 633394bc9..e0b02e453 100644 --- a/dmp-frontend/src/app/core/services/description/description.service.ts +++ b/dmp-frontend/src/app/core/services/description/description.service.ts @@ -34,7 +34,11 @@ export class DescriptionService { publicQuery(q: DescriptionLookup): Observable> { const url = `${this.apiBase}/public/query`; - return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http.post>(url, q, {params: params}).pipe(catchError((error: any) => throwError(error))); } getSingle(id: Guid, reqFields: string[] = []): Observable { @@ -50,10 +54,15 @@ export class DescriptionService { getPublicSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/public/${id}`; - const options = { params: { f: reqFields } }; - + const options: HttpParamsOptions = { fromObject: { f: reqFields } }; + + let params: BaseHttpParams = new BaseHttpParams(options); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http - .get(url, options).pipe( + .get(url, { params: params }).pipe( catchError((error: any) => throwError(error))); } 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 9b40743d7..410a38920 100644 --- a/dmp-frontend/src/app/core/services/dmp/dmp.service.ts +++ b/dmp-frontend/src/app/core/services/dmp/dmp.service.ts @@ -43,7 +43,11 @@ export class DmpService { publicQuery(q: DmpLookup): Observable> { const url = `${this.apiBase}/public/query`; - return this.http.post>(url, q).pipe(catchError((error: any) => throwError(error))); + const params = new BaseHttpParams(); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; + return this.http.post>(url, q, {params: params}).pipe(catchError((error: any) => throwError(error))); } getSingle(id: Guid, reqFields: string[] = []): Observable { @@ -57,10 +61,16 @@ export class DmpService { getPublicSingle(id: Guid, reqFields: string[] = []): Observable { const url = `${this.apiBase}/public/${id}`; - const options = { params: { f: reqFields } }; + + const options: HttpParamsOptions = { fromObject: { f: reqFields } }; + + let params: BaseHttpParams = new BaseHttpParams(options); + params.interceptorContext = { + excludedInterceptors: [InterceptorType.AuthToken] + }; return this.http - .get(url, options).pipe( + .get(url, { params: params }).pipe( catchError((error: any) => throwError(error))); } diff --git a/dmp-frontend/src/app/core/services/reference/reference.service.ts b/dmp-frontend/src/app/core/services/reference/reference.service.ts index 959f4ff9a..fde3936a5 100644 --- a/dmp-frontend/src/app/core/services/reference/reference.service.ts +++ b/dmp-frontend/src/app/core/services/reference/reference.service.ts @@ -206,7 +206,7 @@ export class ReferenceService { } getReferencesForTypes(dmpReferences: DmpReference[], referenceTypeIds?: Guid[]): DmpReference[] { - return dmpReferences?.filter(x => referenceTypeIds?.includes(x?.reference?.type?.id)); + return dmpReferences?.filter(x => referenceTypeIds?.includes(x?.reference?.type?.id)).filter(x=> x.isActive === IsActive.Active);; } getReferencesForTypesFirstSafe(dmpReferences: DmpReference[], referenceTypeIds?: Guid[]): DmpReference { diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/components/composite-field/description-template-editor-composite-field.component.html b/dmp-frontend/src/app/ui/admin/description-template/editor/components/composite-field/description-template-editor-composite-field.component.html index 9a3a9bde9..3b6665f1e 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/components/composite-field/description-template-editor-composite-field.component.html +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/components/composite-field/description-template-editor-composite-field.component.html @@ -205,18 +205,14 @@ Argos Entities - - + diff --git a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts index f5ec839c6..379ea9de0 100644 --- a/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-template/editor/description-template-editor.component.ts @@ -135,6 +135,22 @@ export class DescriptionTemplateEditorComponent extends BaseEditor void) { @@ -200,7 +216,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor void): void { - if (!this.isClone && !this.isNewVersion){ + if (this.isNewVersion == false){ const formData = this.formService.getValue(this.formGroup.value) as DescriptionTemplatePersist; this.descriptionTemplateService.persist(formData) @@ -208,7 +224,7 @@ export class DescriptionTemplateEditorComponent extends BaseEditor onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), error => this.onCallbackError(error) ); - } else if (this.isNewVersion && !this.isNew && !this.isClone) { + } else if (this.isNewVersion== true && this.isNew == false && this.isClone == false) { const formData = this.formService.getValue(this.formGroup.value) as NewVersionDescriptionTemplatePersist; this.descriptionTemplateService.newVersion(formData) diff --git a/dmp-frontend/src/app/ui/admin/description-types/editor/description-template-type-editor.component.ts b/dmp-frontend/src/app/ui/admin/description-types/editor/description-template-type-editor.component.ts index 4a62698d1..bbba7c49f 100644 --- a/dmp-frontend/src/app/ui/admin/description-types/editor/description-template-type-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/description-types/editor/description-template-type-editor.component.ts @@ -135,6 +135,7 @@ export class DescriptionTemplateTypeEditorComponent extends BaseEditor
-

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

-

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

+

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

+

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

{{'DMP-BLUEPRINT-EDITOR.TITLE.CLONE' | translate}} {{formGroup.get('label').value}} diff --git a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts index 53593682f..d5b94b111 100644 --- a/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/dmp-blueprint/editor/dmp-blueprint-editor.component.ts @@ -153,7 +153,6 @@ export class DmpBlueprintEditorComponent extends BaseEditor void): void { - if (this.isNew && !this.isClone && !this.isNewVersion) { + if ( this.isNewVersion == false) { const formData = this.formService.getValue(this.formGroup.value) as DmpBlueprintPersist; this.dmpBlueprintService.persist(formData) @@ -215,7 +214,7 @@ export class DmpBlueprintEditorComponent extends BaseEditor onSuccess ? onSuccess(complete) : this.onCallbackSuccess(complete), error => this.onCallbackError(error) ); - } else if (this.isNewVersion && !this.isNew && !this.isClone) { + } else if (this.isNewVersion == true && this.isNew == false && this.isClone == false) { const formData = this.formService.getValue(this.formGroup.value) as NewVersionDmpBlueprintPersist; this.dmpBlueprintService.newVersion(formData) diff --git a/dmp-frontend/src/app/ui/admin/language/editor/language-editor.component.ts b/dmp-frontend/src/app/ui/admin/language/editor/language-editor.component.ts index 8806ff43c..d6e12f228 100644 --- a/dmp-frontend/src/app/ui/admin/language/editor/language-editor.component.ts +++ b/dmp-frontend/src/app/ui/admin/language/editor/language-editor.component.ts @@ -155,6 +155,7 @@ export class LanguageEditorComponent extends BaseEditor } formSubmit(): void { + this.formService.removeAllBackEndErrors(this.formGroup); this.formService.touchAllFormFields(this.formGroup); - // if (!this.isFormValid()) { - // return; - // } + if (!this.isFormValid()) { + return; + } this.persistEntity(); } diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.html b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.html index 8da972d99..d2a157d3d 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.html +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.html @@ -4,10 +4,10 @@ {{'DMP-LISTING.SORT-BY' | translate}}: - {{enumUtils.toRecentActivityOrderString(order.MODIFIED)}} - {{enumUtils.toRecentActivityOrderString(order.DATASETPUBLISHED)}} - {{enumUtils.toRecentActivityOrderString(order.LABEL)}} - {{enumUtils.toRecentActivityOrderString(order.STATUS)}} + {{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}} + + {{enumUtils.toRecentActivityOrderString(order.Label)}} + {{enumUtils.toRecentActivityOrderString(order.Status)}} diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts index a6b23531f..dae06b876 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.resolver.ts @@ -155,9 +155,9 @@ export class DescriptionEditorResolver extends BaseEditorResolver { const dmpSectionId = route.paramMap.get('dmpSectionId'); const copyDmpId = route.paramMap.get('copyDmpId'); // const cloneid = route.paramMap.get('cloneid'); - if (id != null) { + if (id != null && copyDmpId == null && dmpSectionId == null) { return this.descriptionService.getSingle(Guid.parse(id), fields) - } else if (dmpId != null && dmpSectionId != null) { + } else if (dmpId != null && dmpSectionId != null && copyDmpId == null) { return this.dmpService.getSingle(Guid.parse(dmpId), DescriptionEditorResolver.dmpLookupFields()).pipe(tap(x => this.breadcrumbService.addIdResolvedValue(x.id?.toString(), x.label)), takeUntil(this._destroyed), map(dmp => { const description: Description = {}; diff --git a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html index 2bc4c1997..1510a44a0 100644 --- a/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html +++ b/dmp-frontend/src/app/ui/description/listing/listing-item/description-listing-item.component.html @@ -24,7 +24,7 @@

- open_in_new{{'DESCRIPTION-LISTING.ACTIONS.EXPORT' | translate}} + open_in_new{{'DESCRIPTION-LISTING.ACTIONS.EXPORT' | translate}} group_add{{'DESCRIPTION-LISTING.ACTIONS.INVITE-SHORT' | translate}} file_copy{{'DESCRIPTION-LISTING.ACTIONS.COPY-DESCRIPTION' | translate}} delete{{ 'DESCRIPTION-LISTING.ACTIONS.DELETE' | translate }} diff --git a/dmp-frontend/src/app/ui/description/overview/description-overview.component.html b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html index af852bb26..cf5aa87b0 100644 --- a/dmp-frontend/src/app/ui/description/overview/description-overview.component.html +++ b/dmp-frontend/src/app/ui/description/overview/description-overview.component.html @@ -91,7 +91,7 @@
-
+
-
+
- +
{{'GENERAL.ACTIONS.NO-MORE-AVAILABLE' | translate}} diff --git a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts index a9f39ee5a..c0d755343 100644 --- a/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts +++ b/dmp-frontend/src/app/ui/dashboard/recent-edited-description-activity/recent-edited-description-activity.component.ts @@ -7,10 +7,11 @@ import { DescriptionTemplate } from '@app/core/model/description-template/descri import { Description } from '@app/core/model/description/description'; import { Dmp, DmpUser } from '@app/core/model/dmp/dmp'; import { DmpReference } from '@app/core/model/dmp/dmp-reference'; +import { ReferenceType } from '@app/core/model/reference-type/reference-type'; import { Reference } from '@app/core/model/reference/reference'; -import { DescriptionLookup } from '@app/core/query/description.lookup'; +import { RecentActivityItemLookup } from '@app/core/query/recent-activity-item-lookup.lookup'; import { AuthService } from '@app/core/services/auth/auth.service'; -import { DescriptionService } from '@app/core/services/description/description.service'; +import { DashboardService } from '@app/core/services/dashboard/dashboard.service'; import { MatomoService } from '@app/core/services/matomo/matomo-service'; import { EnumUtils } from '@app/core/services/utilities/enum-utils.service'; import { BaseComponent } from '@common/base/base.component'; @@ -24,7 +25,7 @@ import { nameof } from 'ts-simple-nameof'; }) export class RecentEditedDescriptionActivityComponent extends BaseComponent implements OnInit { - lookup: DescriptionLookup = new DescriptionLookup(); + lookup: RecentActivityItemLookup = new RecentActivityItemLookup(); pageSize: number = 5; listingItems: Description[]; @@ -48,7 +49,7 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl private router: Router, public enumUtils: EnumUtils, private authentication: AuthService, - private descriptionService: DescriptionService, + private dashboardService: DashboardService, private location: Location, private matomoService: MatomoService ) { @@ -98,7 +99,7 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl } updateUrl() { - let parameters = "?type=dmps" + + let parameters = "?type=descriptions" + (this.page != 1 ? "&page=" + this.page : "") + //TODO refactor //(((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 : "") + @@ -115,7 +116,7 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl this.formGroup.get('order').setValue(this.order.UpdatedAt); } this.lookup.page = { size: this.pageSize, offset: 0 }; - this.lookup.order = { items: ['-' + this.formGroup.get('order').value] }; + this.lookup.orderField = this.formGroup.get('order').value; this.lookup.like = this.formGroup.get('like').value; this.lookup.project = { @@ -136,17 +137,18 @@ export class RecentEditedDescriptionActivityComponent extends BaseComponent impl [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.label)].join('.'), - [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.type)].join('.'), + [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.type), nameof(x => x.id)].join('.'), [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.reference)].join('.'), + [nameof(x => x.dmp), nameof(x => x.dmpReferences), nameof(x => x.reference), nameof(x => x.isActive)].join('.'), ] }; - this.descriptionService - .query(this.lookup) + this.dashboardService + .getMyRecentActivityItems(this.lookup) .pipe(takeUntil(this._destroyed)) .subscribe(response => { - this.listingItems = response.items; - this.totalCount = response.count; + this.listingItems = response.map(x => x.description); + // this.totalCount = response.count; //this.totalCountDmps.emit(this.dmpActivities.length); 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 dc5d56ba9..519620897 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 @@ -4,10 +4,10 @@ {{'DMP-LISTING.SORT-BY' | translate}}: - {{enumUtils.toRecentActivityOrderString(order.MODIFIED)}} - {{enumUtils.toRecentActivityOrderString(order.PUBLISHED)}} - {{enumUtils.toRecentActivityOrderString(order.LABEL)}} - {{enumUtils.toRecentActivityOrderString(order.STATUS)}} + {{enumUtils.toRecentActivityOrderString(order.UpdatedAt)}} + + {{enumUtils.toRecentActivityOrderString(order.Label)}} + {{enumUtils.toRecentActivityOrderString(order.Status)}} @@ -24,7 +24,7 @@
- +