Merge branch 'dmp-refactoring' of https://code-repo.d4science.org/MaDgiK-CITE/argos into dmp-refactoring

This commit is contained in:
Sofia Papacharalampous 2024-05-16 14:47:20 +03:00
commit 346ef4476a
12 changed files with 77 additions and 37 deletions

View File

@ -13,6 +13,7 @@ import org.opencdmp.commons.enums.IsActive;
import org.opencdmp.convention.ConventionService;
import org.opencdmp.data.DmpEntity;
import org.opencdmp.model.*;
import org.opencdmp.model.dmp.Dmp;
import org.opencdmp.query.*;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
@ -88,7 +89,10 @@ public class PublicDmpBuilder extends BaseBuilder<PublicDmp, DmpEntity> {
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()));
if (entityDoisMap != null && !entityDoisMap.isEmpty() && entityDoisMap.containsKey(d.getId())) m.setEntityDois(entityDoisMap.get(d.getId()));
if (otherDmpVersionsMap != null && !otherDmpVersionsMap.isEmpty() && otherDmpVersionsMap.containsKey(d.getGroupId())) m.setOtherDmpVersions(otherDmpVersionsMap.get(d.getGroupId()));
if (otherDmpVersionsMap != null && !otherDmpVersionsMap.isEmpty() && otherDmpVersionsMap.containsKey(d.getGroupId())){
m.setOtherDmpVersions(otherDmpVersionsMap.get(d.getGroupId()));
m.getOtherDmpVersions().sort(Comparator.comparing(PublicDmp::getVersion));
}
models.add(m);
}
@ -178,7 +182,7 @@ public class PublicDmpBuilder extends BaseBuilder<PublicDmp, DmpEntity> {
DmpQuery query = this.queryFactory.query(DmpQuery.class).disableTracking().authorize(this.authorize).groupIds(data.stream().map(DmpEntity::getGroupId).distinct().collect(Collectors.toList())).isActive(IsActive.Active);
itemMap = this.builderFactory.builder(PublicDmpBuilder.class).authorize(this.authorize).asMasterKey(query, clone, PublicDmp::getGroupId);
if (!fields.hasField(this.asIndexer(PublicDmp._otherDmpVersions, PublicDmp._id))) {
if (!fields.hasField(PublicDmp._id)) {
itemMap.values().stream().flatMap(List::stream).filter(Objects::nonNull).forEach(x -> {
x.setId(null);
});

View File

@ -32,6 +32,7 @@ import org.opencdmp.model.dmpblueprint.DmpBlueprint;
import org.opencdmp.model.dmpreference.DmpReference;
import org.opencdmp.model.user.User;
import org.opencdmp.query.*;
import org.opencdmp.service.externalfetcher.config.entities.SourceBaseConfiguration;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
@ -137,7 +138,10 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
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()));
if (dmpDescriptionTemplatesMap != null && !dmpDescriptionTemplatesMap.isEmpty() && dmpDescriptionTemplatesMap.containsKey(d.getId())) m.setDmpDescriptionTemplates(dmpDescriptionTemplatesMap.get(d.getId()));
if (otherDmpVersionsMap != null && !otherDmpVersionsMap.isEmpty() && otherDmpVersionsMap.containsKey(d.getGroupId())) m.setOtherDmpVersions(otherDmpVersionsMap.get(d.getGroupId()));
if (otherDmpVersionsMap != null && !otherDmpVersionsMap.isEmpty() && otherDmpVersionsMap.containsKey(d.getGroupId())) {
m.setOtherDmpVersions(otherDmpVersionsMap.get(d.getGroupId()));
m.getOtherDmpVersions().sort(Comparator.comparing(Dmp::getVersion));
}
if (!propertiesFields.isEmpty() && d.getProperties() != null){
DmpPropertiesEntity propertyDefinition = this.jsonHandlingService.fromJsonSafe(DmpPropertiesEntity.class, d.getProperties());
m.setProperties(this.builderFactory.builder(DmpPropertiesBuilder.class).authorize(this.authorize).build(propertiesFields, propertyDefinition));
@ -310,7 +314,7 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
DmpQuery query = this.queryFactory.query(DmpQuery.class).disableTracking().authorize(this.authorize).groupIds(data.stream().map(DmpEntity::getGroupId).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(DmpBuilder.class).authorize(this.authorize).asMasterKey(query, clone, Dmp::getGroupId);
if (!fields.hasField(this.asIndexer(Dmp._otherDmpVersions, Dmp._id))) {
if (!fields.hasField(Dmp._id)) {
itemMap.values().stream().flatMap(List::stream).filter(Objects::nonNull).forEach(x -> {
x.setId(null);
});

View File

@ -128,17 +128,18 @@ public class FieldPersist {
protected List<Specification> specifications(FieldPersist item) {
FieldType fieldType = this.fieldEntity != null && this.fieldEntity.getData() != null ? this.fieldEntity.getData().getFieldType() : FieldType.FREE_TEXT;
boolean required = this.fieldEntity != null && this.fieldEntity.getValidations() != null ? this.fieldEntity.getValidations().contains(FieldValidationType.Required) : false;
boolean isUrlRequired = this.fieldEntity != null && this.fieldEntity.getValidations() != null ? this.fieldEntity.getValidations().contains(FieldValidationType.Url) : false;
// boolean isUrlRequired = this.fieldEntity != null && this.fieldEntity.getValidations() != null ? this.fieldEntity.getValidations().contains(FieldValidationType.Url) : false;
boolean isVisible = this.fieldEntity != null ? this.visibilityService.isVisible(this.fieldEntity.getId(), this.ordinal) : true;
return Arrays.asList(
this.spec()
.iff(()-> FieldType.isTextType(fieldType) && DescriptionStatus.Finalized.equals(this.status) && isVisible && required)
.must(() -> !this.isEmpty(item.getTextValue()))
.failOn(FieldPersist._textValue).failWith(this.messageSource.getMessage("Validation_Required", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())),
this.spec()
.iff(()-> fieldType.equals(FieldType.FREE_TEXT) && DescriptionStatus.Finalized.equals(this.status) && isVisible && isUrlRequired)
.must(() -> this.isValidURL(item.getTextValue()))
.failOn(FieldPersist._textValue).failWith(this.messageSource.getMessage("Validation_UrlRequired", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())),
//TODO
// this.spec()
// .iff(()-> fieldType.equals(FieldType.FREE_TEXT) && DescriptionStatus.Finalized.equals(this.status) && isVisible && isUrlRequired && (required || !this.isEmpty(item.getTextValue())))
// .must(() -> this.isValidURL(item.getTextValue()))
// .failOn(FieldPersist._textValue).failWith(this.messageSource.getMessage("Validation_UrlRequired", new Object[]{FieldPersist._textValue}, LocaleContextHolder.getLocale())),
this.spec()
.iff(()-> FieldType.isDateType(fieldType) && DescriptionStatus.Finalized.equals(this.status) && isVisible && required)
.must(() -> !this.isNull(item.getDateValue()))

View File

@ -343,7 +343,7 @@ public class DmpServiceImpl implements DmpService {
.groupIds(data.getGroupId());
dmpQuery.setOrder(new Ordering().addDescending(Dmp._version));
previousDmp = dmpQuery.first();
previousDmp = dmpQuery.collect().get(0);
if (previousDmp != null){
if (previousDmp.getStatus().equals(DmpStatus.Finalized)) previousDmp.setVersionStatus(DmpVersionStatus.Current);
else previousDmp.setVersionStatus(DmpVersionStatus.NotFinalized);
@ -566,7 +566,8 @@ public class DmpServiceImpl implements DmpService {
if (newStatus.equals(DmpStatus.Finalized)) {
List<DmpEntity> latestVersionDmps = this.queryFactory.query(DmpQuery.class)
.versionStatuses(DmpVersionStatus.Current).isActive(IsActive.Active).groupIds(data.getGroupId()).collect();
.versionStatuses(DmpVersionStatus.Current).excludedIds(data.getId())
.isActive(IsActive.Active).groupIds(data.getGroupId()).collect();
if (latestVersionDmps.size() > 1)
throw new MyValidationException("Multiple previous template found");
DmpEntity oldDmpEntity = latestVersionDmps.stream().findFirst().orElse(null);
@ -1086,11 +1087,28 @@ public class DmpServiceImpl implements DmpService {
dmp.setStatus(DmpStatus.Draft);
dmp.setUpdatedAt(Instant.now());
dmp.setVersionStatus(DmpVersionStatus.NotFinalized);
this.entityManager.merge(dmp);
this.entityManager.flush();
this.updateVersionStatusAndSave(dmp, DmpStatus.Finalized, dmp.getStatus());
this.entityManager.flush();
DmpQuery dmpQuery = this.queryFactory.query(DmpQuery.class).disableTracking()
.versionStatuses(DmpVersionStatus.Previous)
.excludedIds(dmp.getId())
.isActive(IsActive.Active)
.groupIds(dmp.getGroupId());
dmpQuery.setOrder(new Ordering().addDescending(Dmp._version));
DmpEntity previousDmp = dmpQuery.collect().get(0);
if (previousDmp != null){
if (previousDmp.getStatus().equals(DmpStatus.Finalized)) previousDmp.setVersionStatus(DmpVersionStatus.Current);
else previousDmp.setVersionStatus(DmpVersionStatus.NotFinalized);
this.entityManager.merge(previousDmp);
}
this.entityManager.flush();
this.annotationEntityTouchedIntegrationEventHandler.handleDmp(dmp.getId());
this.sendNotification(dmp);
}

View File

@ -7,7 +7,9 @@ description: Discover how to create a new plan
-img- start a new plan -img-
To create a new Plan in OpenCDMP you can either [import](/docs/documentation/application/plans/imports) an existing plan from other source or writting a Plan from start. It provides an editor that you must fill **Title**, **Description** and select the [**Blueprint**](/docs/documentation/administration/blueprints/) of this plan that describes the structure. Also there is a Default Plan Blueprint for use. After save, the plan is automatically in draft status.
To create a new Plan in OpenCDMP you can either [import](/docs/documentation/application/plans/imports) an existing plan from a file or fill in a Plan from the start.
To do this, there is a form available where you must fill a **Title**, a **Description** and select the **[Blueprint](/docs/documentation/administration/blueprints/)** of this plan that describes its structure. Also, there is a Default Plan Blueprint for use. When ready, after you press `save`, the plan is automatically saved having the `draft` status. More information about the lifecycle of a plan, can be found [here](/docs/documentation/application/plans/plan-lifecycle).
-img- plan editor first step -img-

View File

@ -5,10 +5,10 @@ description: Discover how to edit a plan
# Edit a Plan
You can view a plan by either from `Home Page` or from `My Plans`. By selecting the plan you can view the overview and all actions for this.
You can view a plan either from `Home Page` or from `My Plans`. By selecting the plan you can view the overview and all the actions available for it.
-img- plan overview -img-
In edit state you can make and revert changes but also add descriptions to specific section that contains description templates field.
While in the edit view, you can make and revert changes but also add descriptions to specific sections that contain description template fields.
-img- plan editor in edit state -img-

View File

@ -7,7 +7,7 @@ description: Discover export options for a plan
-img- export plan-img-
Application supports download the structure of the plan in the following formats:
You can export the structure of a plan in the following formats:
- **PDF**
- **DOCX**
- **RDA JSON**
@ -15,7 +15,7 @@ Application supports download the structure of the plan in the following formats
:::tip
- You can use the export feature in anytime in plans' lifecycle
- Export is also available in Public Plans
- You can use the export feature anytime in a plans' lifecycle
- Export is also available for the Public Plans
:::

View File

@ -5,6 +5,6 @@ description: Discover import options for a plan
# Imports
You can import an existing plan to continue work in appliation. Import supports upload of `.json` files that are produced according to [RDA specifications](https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard) for machine-actionable plans.
You can import an existing plan so that you don't have to work on a new one from scratch. Import supports the upload of `.json` files that are produced according to [RDA specifications](https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard) for machine-actionable plans.
-img- import plan pop up dialog -img-

View File

@ -7,18 +7,19 @@ description: Discover how you invite people to a plan
-img- invite users -img-
Before finalization, the plan can be further edited by inviting users collaborate on completing this. There are two methods to invite users:
- **External**: If user is registered in application then a notification (email or in App) sends to him. If not, a registration email sends.
- **Internal**: It's a quick way, that we can invite users that is already associated to other plans we work with as well.
Before finalization, the plan can be further edited by inviting users in order to collaborate on it and complete it. There are two methods to invite users:
- **External**: If the user is registered in the application, then a notification (email or in App) gets sent to him. If not, a registration email is being sent instead.
- **Internal**: It's a quick way, that we can invite users already associated to other plans we work with as well.
For each member, a role on the plan must be defined. There are three different roles:
For each member, must be defined the role for the plan. There are three different roles:
- **Owner**: manage and edit all plan features.
- **Description Contributor**: only edit descriptions of this plan.
- **Reviewer**: view the plan but no rights to edit.
- **Owner**: Manage and edit all plan features.
- **Description Contributor**: Edit only the descriptions of this plan.
- **Reviewer**: View the plan without being able to edit it.
:::note
the roles' features can be apply to entire plan or specific section
The collaboration roles we discussed above, can be applied to an entire plan or only to a specific section of it.
:::

View File

@ -5,4 +5,14 @@ description: Discover the lifecycle of a plan
# Plan lifecycle
After a plan is created automatically get the draft status. In `My Plans` they appears all the plans that user has or collaborate.
After a plan is created, it gets saved automatically in `draft` mode. While in this mode, the user can make any changes he wants and save it as many times as he wants. When ready, the user can then `finalize` it which means no more changes will be possible. If there comes a need for further editing after the plan is already finalized, the user has the option to undo the finalization and bring it back into `draft` mode.
A finalized plan can then be [deposited](/docs/documentation/application/plans/doi-assignment.md).
:::warning
When a plan gets deposited it can not be edited anymore. This action is irreversible. In this case, the only option is to either clone it or make a new [version](/docs/documentation/application/plans/versions) of it.
:::
In the `My Plans` page, the user can view all the plans he has created or the ones he has been invited as a [collaborator](/docs/documentation/application/plans/invite-collaborators).

View File

@ -5,15 +5,15 @@ description: Discover plan versioning options
# Versions
A plan can have many versions. There is always one version that is marked as `current`, it is the most recent version and it is the one that gets displayed on the listing views. All the other ones are marked as `previous` and can be viewed when the `All Plan Versions` option is pressed.
:::info
If the plan is finalized you can create a new version for it. New Version don't delete the previous version of this plan, just creates a new with draft status.
If the plan is finalized you can create a new version for it, which will have all the properties of the last one and it will be in `draft` mode ready for changes. Making a new version doesn't delete the previous ones.
:::
`New Version` button exists in `My Plans` or `Plan Overview` actions. In new version form can change the title, description, plan blueprint and optional select which descriptions include in the new version. After the process is completed, plan and descriptions are available to edit.
The `New Version` option cab be found in the `My Plans` or `Plan Overview` pages. In the new version form, the user can change titles, descriptions, plan blueprints and optionally select which descriptions to include in the new version. After the process is completed, the new plan and descriptions are available for editing.
-img- new version overview -img-
-img- new version listing -img-
:::tip
`All Plan Versions` - shows the history of the different versions of the existing plan
:::
-img- new version listing -img-

View File

@ -1,6 +1,6 @@
# Supplementary Services
There are four supplementary services directly integrated into this platform. They are used to extend it's functionality and improve the user experience. In this section of the docs, we will dive into each one of them, and see how they contribute to the overall usage of the platform.
There are four supplementary services directly integrated into this platform. They are used to extend its functionality and improve the user experience. In this section of the docs, we will dive into each one of them, and see how they contribute to the overall usage of the platform.
Follow the links below, to find out more information about them respectively.