diff --git a/backend/core/src/main/java/org/opencdmp/model/persist/NewVersionDmpPersist.java b/backend/core/src/main/java/org/opencdmp/model/persist/NewVersionDmpPersist.java index ffd301e6d..a311046fe 100644 --- a/backend/core/src/main/java/org/opencdmp/model/persist/NewVersionDmpPersist.java +++ b/backend/core/src/main/java/org/opencdmp/model/persist/NewVersionDmpPersist.java @@ -1,7 +1,7 @@ package org.opencdmp.model.persist; -import org.opencdmp.commons.validation.BaseValidator; import gr.cite.tools.validation.specification.Specification; +import org.opencdmp.commons.validation.BaseValidator; import org.opencdmp.convention.ConventionService; import org.opencdmp.data.DmpEntity; import org.opencdmp.errorcode.ErrorThesaurusProperties; @@ -18,18 +18,18 @@ import java.util.UUID; public class NewVersionDmpPersist { - private UUID id = null; + private UUID id; public static final String _id = "id"; - private String label = null; + private String label; public static final String _label = "label"; - private String description = null; + private String description; public static final String _description = "description"; - private UUID blueprintId = null; + private UUID blueprintId; public static final String _blueprintId = "blueprintId"; @@ -42,7 +42,7 @@ public class NewVersionDmpPersist { public static final String _hash = "hash"; public UUID getId() { - return id; + return this.id; } public void setId(UUID id) { @@ -50,7 +50,7 @@ public class NewVersionDmpPersist { } public String getLabel() { - return label; + return this.label; } public void setLabel(String label) { @@ -58,7 +58,7 @@ public class NewVersionDmpPersist { } public String getDescription() { - return description; + return this.description; } public void setDescription(String description) { @@ -66,7 +66,7 @@ public class NewVersionDmpPersist { } public UUID getBlueprintId() { - return blueprintId; + return this.blueprintId; } public void setBlueprintId(UUID blueprintId) { @@ -74,7 +74,7 @@ public class NewVersionDmpPersist { } public List getDescriptions() { - return descriptions; + return this.descriptions; } public void setDescriptions(List descriptions) { @@ -82,7 +82,7 @@ public class NewVersionDmpPersist { } public String getHash() { - return hash; + return this.hash; } public void setHash(String hash) { @@ -113,23 +113,23 @@ public class NewVersionDmpPersist { this.spec() .iff(() -> this.isValidGuid(item.getId())) .must(() -> this.isValidHash(item.getHash())) - .failOn(NewVersionDmpPersist._hash).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._hash}, LocaleContextHolder.getLocale())), + .failOn(NewVersionDmpPersist._hash).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._hash}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isEmpty(item.getLabel())) - .failOn(NewVersionDmpPersist._label).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._label}, LocaleContextHolder.getLocale())), + .failOn(NewVersionDmpPersist._label).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._label}, LocaleContextHolder.getLocale())), this.spec() .iff(() -> !this.isEmpty(item.getLabel())) .must(() -> this.lessEqualLength(item.getLabel(), DmpEntity._labelLength)) - .failOn(NewVersionDmpPersist._label).failWith(messageSource.getMessage("Validation_MaxLength", new Object[]{NewVersionDmpPersist._label}, LocaleContextHolder.getLocale())), + .failOn(NewVersionDmpPersist._label).failWith(this.messageSource.getMessage("Validation_MaxLength", new Object[]{NewVersionDmpPersist._label}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isEmpty(item.getDescription())) - .failOn(NewVersionDmpPersist._description).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._description}, LocaleContextHolder.getLocale())), + .failOn(NewVersionDmpPersist._description).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._description}, LocaleContextHolder.getLocale())), this.spec() .must(() -> this.isValidGuid(item.getBlueprintId())) - .failOn(NewVersionDmpPersist._blueprintId).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._blueprintId}, LocaleContextHolder.getLocale())), + .failOn(NewVersionDmpPersist._blueprintId).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._blueprintId}, LocaleContextHolder.getLocale())), this.spec() .must(() -> !this.isNull(item.getDescriptions())) - .failOn(NewVersionDmpPersist._descriptions).failWith(messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._descriptions}, LocaleContextHolder.getLocale())) + .failOn(NewVersionDmpPersist._descriptions).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{NewVersionDmpPersist._descriptions}, LocaleContextHolder.getLocale())) ); } } diff --git a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionService.java b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionService.java index f5d5d308c..23e5e027b 100644 --- a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionService.java +++ b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionService.java @@ -1,17 +1,17 @@ package org.opencdmp.service.description; -import org.opencdmp.commons.types.description.importexport.DescriptionImportExport; -import org.opencdmp.data.StorageFileEntity; -import org.opencdmp.model.description.Description; -import org.opencdmp.model.DescriptionValidationResult; -import org.opencdmp.model.StorageFile; -import org.opencdmp.model.persist.*; import gr.cite.tools.exception.MyApplicationException; import gr.cite.tools.exception.MyForbiddenException; import gr.cite.tools.exception.MyNotFoundException; import gr.cite.tools.exception.MyValidationException; import gr.cite.tools.fieldset.FieldSet; import jakarta.xml.bind.JAXBException; +import org.opencdmp.commons.types.description.importexport.DescriptionImportExport; +import org.opencdmp.data.StorageFileEntity; +import org.opencdmp.model.DescriptionValidationResult; +import org.opencdmp.model.StorageFile; +import org.opencdmp.model.description.Description; +import org.opencdmp.model.persist.*; import org.springframework.http.ResponseEntity; import org.springframework.web.multipart.MultipartFile; import org.xml.sax.SAXException; @@ -40,8 +40,6 @@ public interface DescriptionService { List validate(List descriptionIds) throws InvalidApplicationException; - void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException; - ResponseEntity export(UUID id, String exportType) throws InvalidApplicationException, IOException, InvalidAlgorithmParameterException, NoSuchPaddingException, IllegalBlockSizeException, NoSuchAlgorithmException, BadPaddingException, InvalidKeyException; StorageFile uploadFieldFile(DescriptionFieldFilePersist model, MultipartFile file, FieldSet fields) throws IOException; diff --git a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java index cd79e1b22..742bec78b 100644 --- a/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/description/DescriptionServiceImpl.java @@ -817,73 +817,6 @@ public class DescriptionServiceImpl implements DescriptionService { //region clone - @Override - public void clone(UUID dmpId, UUID descriptionId) throws InvalidApplicationException, IOException { - logger.debug("cloning description: {} with description: {}", descriptionId, dmpId); - - this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(descriptionId)), Permission.CloneDescription); - - DescriptionEntity existing = this.queryFactory.query(DescriptionQuery.class).disableTracking().ids(descriptionId).isActive(IsActive.Active).first(); - - DescriptionEntity newDescription = new DescriptionEntity(); - newDescription.setId(UUID.randomUUID()); - newDescription.setLabel(existing.getLabel()); - newDescription.setDescription(existing.getDescription()); - newDescription.setStatus(DescriptionStatus.Draft); - newDescription.setProperties(existing.getProperties()); - newDescription.setDmpId(dmpId); - newDescription.setDmpDescriptionTemplateId(existing.getDmpDescriptionTemplateId()); - newDescription.setDescriptionTemplateId(existing.getDescriptionTemplateId()); - newDescription.setCreatedById(this.userScope.getUserId()); - newDescription.setCreatedAt(Instant.now()); - newDescription.setUpdatedAt(Instant.now()); - newDescription.setIsActive(IsActive.Active); - - this.entityManager.persist(newDescription); - - List descriptionReferences = this.queryFactory.query(DescriptionReferenceQuery.class).disableTracking() - .descriptionIds(existing.getId()) - .isActive(IsActive.Active) - .collect(); - - List descriptionTags = this.queryFactory.query(DescriptionTagQuery.class).disableTracking() - .descriptionIds(existing.getId()) - .isActive(IsActive.Active) - .collect(); - - for (DescriptionReferenceEntity descriptionReference : descriptionReferences) { - DescriptionReferenceEntity newReference = new DescriptionReferenceEntity(); - newReference.setId(UUID.randomUUID()); - newReference.setDescriptionId(newDescription.getId()); - newReference.setReferenceId(descriptionReference.getReferenceId()); - newReference.setData(descriptionReference.getData()); - newReference.setCreatedAt(Instant.now()); - newReference.setUpdatedAt(Instant.now()); - newReference.setIsActive(IsActive.Active); - - this.entityManager.persist(newReference); - } - - for(DescriptionTagEntity descriptionTag : descriptionTags) { - DescriptionTagEntity newTag = new DescriptionTagEntity(); - newTag.setId(UUID.randomUUID()); - newTag.setDescriptionId(newDescription.getId()); - newTag.setTagId(descriptionTag.getTagId()); - newTag.setCreatedAt(Instant.now()); - newTag.setUpdatedAt(Instant.now()); - newTag.setIsActive(IsActive.Active); - - this.entityManager.persist(newTag); - } - - this.entityManager.flush(); - - this.elasticService.persistDescription(newDescription); - - this.annotationEntityTouchedIntegrationEventHandler.handleDescription(newDescription.getId()); - this.annotationEntityTouchedIntegrationEventHandler.handleDescription(existing.getId()); - } - //endregion //region file export diff --git a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java index 1c302e8df..9d8f89acb 100644 --- a/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java +++ b/backend/core/src/main/java/org/opencdmp/service/dmp/DmpServiceImpl.java @@ -444,6 +444,7 @@ public class DmpServiceImpl implements DmpService { this.entityManager.persist(newReference); } + Map dmpDescriptionTemplateRemap = new HashMap<>(); for (DmpDescriptionTemplateEntity dmpDescriptionTemplate : dmpDescriptionTemplates) { DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity(); newTemplate.setId(UUID.randomUUID()); @@ -453,12 +454,15 @@ public class DmpServiceImpl implements DmpService { newTemplate.setCreatedAt(Instant.now()); newTemplate.setUpdatedAt(Instant.now()); newTemplate.setIsActive(IsActive.Active); + dmpDescriptionTemplateRemap.put(dmpDescriptionTemplate.getId(), newTemplate.getId()); this.entityManager.persist(newTemplate); } + this.entityManager.flush(); + for (UUID descriptionId : model.getDescriptions()) { - this.descriptionService.clone(newDmp.getId(), descriptionId); + this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, descriptionId); } this.entityManager.flush(); @@ -476,6 +480,74 @@ public class DmpServiceImpl implements DmpService { return this.builderFactory.builder(DmpBuilder.class).build(BaseFieldSet.build(fields, Dmp._id), newDmp); } + public void cloneDescription(UUID dmpId, Map dmpDescriptionTemplateRemap, UUID descriptionId) throws InvalidApplicationException, IOException { + logger.debug("cloning description: {} with description: {}", descriptionId, dmpId); + + this.authorizationService.authorizeAtLeastOneForce(List.of(this.authorizationContentResolver.descriptionAffiliation(descriptionId)), Permission.CloneDescription); + + DescriptionEntity existing = this.queryFactory.query(DescriptionQuery.class).disableTracking().ids(descriptionId).isActive(IsActive.Active).first(); + + DescriptionEntity newDescription = new DescriptionEntity(); + newDescription.setId(UUID.randomUUID()); + newDescription.setLabel(existing.getLabel()); + newDescription.setDescription(existing.getDescription()); + newDescription.setStatus(DescriptionStatus.Draft); + newDescription.setProperties(existing.getProperties()); + newDescription.setDmpId(dmpId); + newDescription.setDmpDescriptionTemplateId(dmpDescriptionTemplateRemap.get(existing.getDmpDescriptionTemplateId())); + newDescription.setDescriptionTemplateId(existing.getDescriptionTemplateId()); + newDescription.setCreatedById(this.userScope.getUserId()); + newDescription.setCreatedAt(Instant.now()); + newDescription.setUpdatedAt(Instant.now()); + newDescription.setIsActive(IsActive.Active); + + this.entityManager.persist(newDescription); + + List descriptionReferences = this.queryFactory.query(DescriptionReferenceQuery.class).disableTracking() + .descriptionIds(existing.getId()) + .isActive(IsActive.Active) + .collect(); + + List descriptionTags = this.queryFactory.query(DescriptionTagQuery.class).disableTracking() + .descriptionIds(existing.getId()) + .isActive(IsActive.Active) + .collect(); + + for (DescriptionReferenceEntity descriptionReference : descriptionReferences) { + DescriptionReferenceEntity newReference = new DescriptionReferenceEntity(); + newReference.setId(UUID.randomUUID()); + newReference.setDescriptionId(newDescription.getId()); + newReference.setReferenceId(descriptionReference.getReferenceId()); + newReference.setData(descriptionReference.getData()); + newReference.setCreatedAt(Instant.now()); + newReference.setUpdatedAt(Instant.now()); + newReference.setIsActive(IsActive.Active); + + this.entityManager.persist(newReference); + } + + for(DescriptionTagEntity descriptionTag : descriptionTags) { + DescriptionTagEntity newTag = new DescriptionTagEntity(); + newTag.setId(UUID.randomUUID()); + newTag.setDescriptionId(newDescription.getId()); + newTag.setTagId(descriptionTag.getTagId()); + newTag.setCreatedAt(Instant.now()); + newTag.setUpdatedAt(Instant.now()); + newTag.setIsActive(IsActive.Active); + + this.entityManager.persist(newTag); + } + + this.entityManager.flush(); + + this.elasticService.persistDescription(newDescription); + + this.annotationEntityTouchedIntegrationEventHandler.handleDescription(newDescription.getId()); + this.annotationEntityTouchedIntegrationEventHandler.handleDescription(existing.getId()); + } + + + private void updateVersionStatusAndSave(DmpEntity data, DmpStatus previousStatus, DmpStatus newStatus) throws InvalidApplicationException { if (previousStatus.equals(newStatus)) return; @@ -578,6 +650,7 @@ public class DmpServiceImpl implements DmpService { this.entityManager.persist(newReference); } + Map dmpDescriptionTemplateRemap = new HashMap<>(); for (DmpDescriptionTemplateEntity dmpDescriptionTemplate : dmpDescriptionTemplates) { DmpDescriptionTemplateEntity newTemplate = new DmpDescriptionTemplateEntity(); newTemplate.setId(UUID.randomUUID()); @@ -587,6 +660,7 @@ public class DmpServiceImpl implements DmpService { newTemplate.setCreatedAt(Instant.now()); newTemplate.setUpdatedAt(Instant.now()); newTemplate.setIsActive(IsActive.Active); + dmpDescriptionTemplateRemap.put(dmpDescriptionTemplate.getId(), newTemplate.getId()); this.entityManager.persist(newTemplate); } @@ -600,7 +674,7 @@ public class DmpServiceImpl implements DmpService { DmpEntity resultingDmpEntity = this.queryFactory.query(DmpQuery.class).disableTracking().ids(newDmp.getId()).firstAs(fields); if (!this.conventionService.isListNullOrEmpty(model.getDescriptions())){ for (UUID description: model.getDescriptions()) { - this.descriptionService.clone(newDmp.getId(), description); + this.cloneDescription(newDmp.getId(), dmpDescriptionTemplateRemap, description); } } return this.builderFactory.builder(DmpBuilder.class).build(fields, resultingDmpEntity); diff --git a/backend/web/src/main/resources/config/storage-devel.yml b/backend/web/src/main/resources/config/storage-devel.yml index 8e3edbd48..0b0d2f9da 100644 --- a/backend/web/src/main/resources/config/storage-devel.yml +++ b/backend/web/src/main/resources/config/storage-devel.yml @@ -1,15 +1,5 @@ storage: service: - defaultLanguage: en - storages: - - type: Temp - basePath: ${FILE_STORAGE}/temp - - type: Main - basePath: ${FILE_STORAGE}/main - - type: Transformer - basePath: ${FILE_STORAGE}/transformer - - type: Deposit - basePath: ${FILE_STORAGE}/deposit static-files: semantics: backend/web/src/main/resources/Semantics.json material-files: diff --git a/backend/web/src/main/resources/config/storage.yml b/backend/web/src/main/resources/config/storage.yml index eece13a50..444fb7d5c 100644 --- a/backend/web/src/main/resources/config/storage.yml +++ b/backend/web/src/main/resources/config/storage.yml @@ -3,6 +3,16 @@ storage: enable: true intervalSeconds: 600 service: + defaultLanguage: en + storages: + - type: Temp + basePath: ${FILE_STORAGE}/temp + - type: Main + basePath: ${FILE_STORAGE}/main + - type: Transformer + basePath: ${FILE_STORAGE}/transformer + - type: Deposit + basePath: ${FILE_STORAGE}/deposit tempStoreLifetimeSeconds: 7200 material-files: localizedNameLanguageKey: "{lang}" diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html index c1333cd32..3ec5ac043 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.html +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.html @@ -66,10 +66,9 @@ - - + - + diff --git a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts index 41f2a5056..2d073f85b 100644 --- a/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts +++ b/dmp-frontend/src/app/ui/description/editor/description-editor.component.ts @@ -63,6 +63,7 @@ export class DescriptionEditorComponent extends BaseEditor { - const canedit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription); + this.canEdit = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.EditDescription); this.canReview = permissionPerSection && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()] && permissionPerSection[this.item.dmpDescriptionTemplate.sectionId.toString()].some(x => x === AppPermission.ReviewDescription); - this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !canedit); + this.formGroup = this.editorModel.buildForm(null, this.isDeleted || !this.canEdit); if (this.item.descriptionTemplate?.definition) this.visibilityRulesService.setContext(this.item.descriptionTemplate.definition, this.formGroup.get('properties')); if (this.item.descriptionTemplate?.definition) this.pageToFieldSetMap = this.mapPageToFieldSet(this.item.descriptionTemplate);; // this.selectedSystemFields = this.selectedSystemFieldDisabled(); this.descriptionEditorService.setValidationErrorModel(this.editorModel.validationErrorModel); - if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted || !canedit) { + if (this.editorModel.status == DescriptionStatus.Finalized || this.isDeleted || !this.canEdit) { this.viewOnly = true; this.isFinalized = true; this.formGroup.disable(); diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html index 480826958..a65ff6ef6 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.html @@ -104,8 +104,14 @@ diff --git a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts index 21bc35e57..1b00babfc 100644 --- a/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts +++ b/dmp-frontend/src/app/ui/dmp/dmp-editor-blueprint/dmp-editor.component.ts @@ -298,9 +298,11 @@ export class DmpEditorComponent extends BaseEditor implemen //Transform descriptionTemplates formData.descriptionTemplates = []; for (const sectionId in (this.formGroup.get('descriptionTemplates') as UntypedFormGroup).controls) { - formData.descriptionTemplates.push( - ...(this.formGroup.get('descriptionTemplates').get(sectionId).value as Guid[]).map(x => { return { sectionId: Guid.parse(sectionId), descriptionTemplateGroupId: x } }) - ); + if (this.formGroup.get('descriptionTemplates').get(sectionId).value != undefined){ + formData.descriptionTemplates.push( + ...(this.formGroup.get('descriptionTemplates').get(sectionId).value as Guid[]).map(x => { return { sectionId: Guid.parse(sectionId), descriptionTemplateGroupId: x } }) + ); + } } this.dmpService.persist(formData) @@ -572,7 +574,12 @@ export class DmpEditorComponent extends BaseEditor implemen }); } - canAddDescription(section: DmpBlueprintDefinitionSection): boolean { + hasDescriptionTemplates(section: DmpBlueprintDefinitionSection): boolean { + if (this.item.dmpDescriptionTemplates?.filter(x => x.sectionId == section.id).length > 0) return true; + return false; + } + + hasValidMultiplicity(section: DmpBlueprintDefinitionSection): boolean { if (section.hasTemplates) { if (section.descriptionTemplates?.length > 0) { const descriptions = this.descriptionsInSection(section.id) diff --git a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html index 4d8cfc31b..481c0d4a4 100644 --- a/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html +++ b/dmp-frontend/src/app/ui/dmp/overview/dmp-overview.component.html @@ -239,15 +239,15 @@
-
+

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

-
-
@@ -257,7 +257,11 @@ ({{ 'DMP-OVERVIEW.YOU' | translate }})

-

{{ enumUtils.toDmpUserRoleString(dmpUser.role) }}

+

+ {{ enumUtils.toDmpUserRoleString(dmpUser.role) }} - + {{ 'DMP-OVERVIEW.ROLES.ALL-SECTIONS' | translate}} + {{ getSectionNameById(dmpUser.sectionId) }} +